rust-lang/rust · error

FIXME(unsafe_binder)

Error message

FIXME(unsafe_binder)

What it means

An `unimplemented!("FIXME(unsafe_binder)")` ICE in `rustc_trait_selection`'s projection code. While computing whether a type has a known discriminant (for the `Discriminant` trait) during a projection obligation, a `ty::UnsafeBinder` pointee reaches project.rs:1077 and panics. The discriminant logic is unfinished for binder types.

Source

Thrown at compiler/rustc_trait_selection/src/traits/project.rs:1077

                        | ty::Str
                        | ty::Array(..)
                        | ty::Pat(..)
                        | ty::Slice(_)
                        | ty::RawPtr(..)
                        | ty::Ref(..)
                        | ty::FnDef(..)
                        | ty::FnPtr(..)
                        | ty::Dynamic(..)
                        | ty::Closure(..)
                        | ty::CoroutineClosure(..)
                        | ty::Coroutine(..)
                        | ty::CoroutineWitness(..)
                        | ty::Never
                        | ty::Tuple(..)
                        // Integers and floats always have `u8` as their discriminant.
                        | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,

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

                        // type parameters, opaques, and unnormalized projections don't have
                        // a known discriminant and may need to be normalized further or rely
                        // on param env for discriminant projections
                        ty::Param(_)
                        | ty::Alias(..)
                        | ty::Bound(..)
                        | ty::Placeholder(..)
                        | ty::Infer(..)
                        | ty::Error(_) => false,
                    },
                    Some(LangItem::PointeeTrait) => {
                        let tail = selcx.tcx().struct_tail_raw(
                            self_ty,
                            &obligation.cause,
                            |ty| {
                                // We throw away any obligations we get from this, since we normalize
                                // and confirm these obligations once again during confirmation

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Do not query `Discriminant` on `UnsafeBinder`-typed values; extract the inner type first.
  2. Disable the `unsafe_binder` feature.
  3. Track the upstream FIXME; upgrade when implemented.

Example fix

// before (Discriminant of unsafe-binder type -> ICE)
#![feature(unsafe_binder)]
let d = std::mem::discriminant(&binder_value);

// after — take discriminant of the inner (unwrapped) type
let d = std::mem::discriminant(&binder_value.inner());
Defensive patterns

Strategy: validation

Validate before calling

# Detect Discriminant use on binder-typed values
rg -nE 'mem::discriminant|Discriminant<' src/  # review for unsafe-binder self types

Prevention

When it happens

Trigger: A trait-obligation involving `std::mem::Discriminant` (or the `Discriminant` lang item) where the self-type contains `ty::UnsafeBinder`, under the `unsafe binder` feature.

Common situations: Using `mem::discriminant` / `Discriminant<T>` on a binder-wrapped type during trait solving on nightly with `#![feature(unsafe_binder)]`.

Related errors


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