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
- Do not take pointers (or metadata) of `UnsafeBinder`-typed points; convert out of the binder first.
- Disable the `unsafe_binder` feature for the affected crate.
- 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
- Do not take `ptr::metadata` of binder-typed points.
- Unwrap the binder before computing metadata.
- Reserve `unsafe_binder` for runtime code.
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
- FIXME(unsafe_binder)
- FIXME(unsafe_binder)
- FIXME(unsafe_binder)
- `async gen` closures not supported yet
- FIXME(comptime)
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/ffc8b289e33c4db5.
Report an issue: GitHub.