rust-lang/rust · error

FIXME(unsafe_binder)

Error message

FIXME(unsafe_binder)

What it means

An `unimplemented!("FIXME(unsafe_binder)")` ICE in `rustc_middle`'s `ptr_metadata_ty_or_tail`. When computing the metadata type (or struct tail) of a pointer whose pointee is `ty::UnsafeBinder`, the function has no handling and panics. All other primitive/compound tails are handled; `UnsafeBinder` is the unfinished arm.

Source

Thrown at compiler/rustc_middle/src/ty/sty.rs:1830

            // If returned by `struct_tail_raw` this is a unit struct
            // without any fields, or not a struct, and therefore is Sized.
            ty::Adt(..) => Ok(tcx.types.unit),
            // If returned by `struct_tail_raw` this is the empty tuple,
            // a.k.a. unit type, which is Sized
            ty::Tuple(..) => Ok(tcx.types.unit),

            ty::Str | ty::Slice(_) => Ok(tcx.types.usize),

            ty::Dynamic(_, _) => {
                let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, DUMMY_SP);
                Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]).skip_norm_wip())
            }

            // We don't know the metadata of `self`, but it must be equal to the
            // metadata of `tail`.
            ty::Param(_) | ty::Alias(..) => Err(tail),

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

            ty::Infer(ty::TyVar(_))
            | ty::Pat(..)
            | ty::Bound(..)
            | ty::Placeholder(..)
            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => bug!(
                "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})"
            ),
        }
    }

    /// Returns the type of metadata for (potentially wide) pointers to this type.
    /// Causes an ICE if the metadata type cannot be determined.
    pub fn ptr_metadata_ty(
        self,
        tcx: TyCtxt<'tcx>,
        normalize: impl FnMut(Unnormalized<'tcx, Ty<'tcx>>) -> Ty<'tcx>,
    ) -> Ty<'tcx> {

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Do not take pointers (or metadata) of `UnsafeBinder`-typed points; convert out of the binder first.
  2. Disable the `unsafe_binder` feature for the affected crate.
  3. Track the upstream FIXME and upgrade nightly when implemented.

Example fix

// before (metadata of unsafe-binder pointee -> ICE)
#![feature(unsafe_binder)]
let m = std::ptr::metadata(p as *const unsafe<'a> Wrap<'a, [u8]>);

// after — take metadata of the underlying tail type
let m = std::ptr::metadata(p as *const [u8]);
Defensive patterns

Strategy: validation

Validate before calling

# Detect pointer/metadata use on unsafe-binder types
rg -nE 'ptr::metadata|size_of_val|align_of_val' src/ | xargs -r grep -l unsafe_binder 2>/dev/null

Prevention

When it happens

Trigger: Calling `ptr::metadata` on, or computing fat-pointer metadata for, a type that is or contains `ty::UnsafeBinder` (e.g. `&unsafe<'a> Wrap<'a, T>` or `*const unsafe<'a> _`), while the `unsafe binder` feature is enabled.

Common situations: Using `std::ptr::metadata` or building wide pointers to unsafe-binder-typed points; part of exercising the unstable `unsafe_binder` feature.

Related errors


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