{"record":{"id":"df2b9d0cb4121fa4","repo":"rust-lang/rust","slug":"discr-subgoal","errorCode":null,"errorMessage":"discr subgoal...","messagePattern":"discr subgoal\\.\\.\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs","lineNumber":1008,"sourceCode":"            | ty::FnDef(..)\n            | ty::FnPtr(..)\n            | ty::Closure(..)\n            | ty::CoroutineClosure(..)\n            | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))\n            | ty::Coroutine(..)\n            | ty::CoroutineWitness(..)\n            | ty::Never\n            | ty::Foreign(..)\n            | ty::Adt(_, _)\n            | ty::Str\n            | ty::Slice(_)\n            | ty::Dynamic(_, _)\n            | ty::Tuple(_)\n            | ty::Error(_) => self_ty.discriminant_ty(ecx.cx()),\n\n            ty::UnsafeBinder(_) => {\n                // FIXME(unsafe_binders): instantiate this with placeholders?? i guess??\n                unimplemented!(\"discr subgoal...\")\n            }\n\n            // Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid\n            // alias. In case there's a where-bound further constraining this alias it is preferred over\n            // this impl candidate anyways. It's still a bit scuffed.\n            ty::Alias(ty::IsRigid::Yes, _) | ty::Param(_) | ty::Placeholder(..) => {\n                return ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {\n                    ecx.instantiate_normalizes_to_as_rigid(goal)?;\n                    ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)\n                });\n            }\n\n            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))\n            | ty::Alias(ty::IsRigid::No, _)\n            | ty::Bound(..) => panic!(\n                \"unexpected self ty `{:?}` when normalizing `<T as DiscriminantKind>::Discriminant`\",\n                goal.predicate.self_ty()\n            ),","sourceCodeStart":990,"sourceCodeEnd":1026,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs#L990-L1026","documentation":"Inside the next trait solver's DiscriminantKind handling (computing <T as DiscriminantKind>::Discriminant), when the self type is ty::UnsafeBinder the code cannot derive a discriminant type and panics with unimplemented!(\"discr subgoal...\"). It is a FIXME(unsafe_binders) placeholder: unsafe binder types are an unstable feature whose interaction with discriminant computation has not been finished.","triggerScenarios":"Using unsafe binder types (#![feature(unsafe_binders)]) with code that needs the DiscriminantKind impl / discriminant type — e.g. mem::discriminant, match on a value whose type is wrapped in an unsafe binder, or any intrinsic that queries the discriminant type — while running under the next trait solver.","commonSituations":"Experimental code enabling #![feature(unsafe_binders)] on a recent nightly, especially when the compiler auto-derives DiscriminantKind for enums behind an unsafe binder. Not reachable on stable.","solutions":["Do not wrap enum types that need discriminant queries in an unsafe binder; operate on the unwrapped inner type.","Disable the unsafe_binders feature and use a raw pointer / transmute-based alternative for the unsafe access.","Switch to the classic trait solver if the code path does not strictly require the next solver.","Wait for / upstream a fix for the FIXME(unsafe_binders) discriminant subgoal; report on the unsafe_binders tracking issue."],"exampleFix":"// before\n#![feature(unsafe_binders)]\nlet b: unsafe_binder<'_, Enum> = bind(value);\nlet d = mem::discriminant(&b); // panics: discr subgoal\n\n// after: unwrap before querying discriminant\nlet d = mem::discriminant(&value);","handlingStrategy":"validation","validationCode":"// Avoid querying discriminants on unsafe-binder-wrapped enum types.\n// Validate by not wrapping enums that need DiscriminantKind:\nfn needs_discriminant<T>() { let _ = std::mem::discriminant; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not wrap enum types in unsafe binders when discriminant semantics are required.","Disable #![feature(unsafe_binders)] for code that touches enums via discriminants.","Prefer the classic solver for unsafe-binder experiments."],"tags":["rustc","trait-solver","nightly","unsafe-binders","discriminant"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}