rust-lang/rust · error

FIXME(unsafe_binder)

Error message

FIXME(unsafe_binder)

What it means

An `unimplemented!("FIXME(unsafe_binder)")` ICE in `rustc_hir_typeck`'s cast-checking code (`pointer_kind`). When type-checking a pointer cast whose pointee type is `ty::UnsafeBinder`, the compiler cannot yet decide whether the pointer is thin/fat and panics. The `UnsafeBinder` arm has no handling implemented.

Source

Thrown at compiler/rustc_hir_typeck/src/cast.rs:121

        let t = self.resolve_vars_with_obligations(t);

        Ok(match *t.kind() {
            ty::Slice(_) | ty::Str => Some(PointerKind::Length),
            ty::Dynamic(tty, _) => Some(PointerKind::VTable(tty)),
            ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
                None => Some(PointerKind::Thin),
                Some(f) => {
                    let field_ty = self.field_ty(span, f, args);
                    self.pointer_kind(field_ty, span)?
                }
            },
            ty::Tuple(fields) => match fields.last() {
                None => Some(PointerKind::Thin),
                Some(&f) => self.pointer_kind(f, span)?,
            },

            ty::UnsafeBinder(_) => unimplemented!("FIXME(unsafe_binder)"),

            // Pointers to foreign types are thin, despite being unsized
            ty::Foreign(..) => Some(PointerKind::Thin),
            // We should really try to normalize here.
            ty::Alias(_, pi) => Some(PointerKind::OfAlias(pi)),
            ty::Param(p) => Some(PointerKind::OfParam(p)),
            // Insufficient type information.
            ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None,

            ty::Bool
            | ty::Char
            | ty::Int(..)
            | ty::Uint(..)
            | ty::Float(_)
            | ty::Array(..)
            | ty::CoroutineWitness(..)
            | ty::RawPtr(_, _)
            | ty::Ref(..)

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Avoid casting raw pointers to/from `UnsafeBinder`-typed points; access through the binder's documented API instead.
  2. Disable the `unsafe_binder` feature for the affected module.
  3. Track the upstream FIXME; update nightly once the cast path is implemented.

Example fix

// before (cast to unsafe-binder pointee -> ICE)
#![feature(unsafe_binder)]
let p = &x as *const _ as *const unsafe<'a> Wrap<'a, u8>;

// after — do not cast; obtain the pointer through the binder API
#![feature(unsafe_binder)]
let p: *const u8 = &x;
Defensive patterns

Strategy: validation

Validate before calling

# Audit casts involving unsafe binder pointees
rg -n 'as \*const .*(unsafe|Wrap)' src/  # review matches by hand

Prevention

When it happens

Trigger: Writing an `as` cast (or raw-pointer cast) to or from a type whose pointee involves `ty::UnsafeBinder`, while the `unsafe binder` nightly feature is enabled. The type-checker's `pointer_kind` recurses into the pointee and hits cast.rs:121.

Common situations: Using the `#![feature(unsafe_binder)]` feature and casting raw pointers to/from binder-wrapped types during type checking.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/4d71b8d55885732f. Report an issue: GitHub.