Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,7 @@ impl<'tcx> Ty<'tcx> {
ty::Adt(adt, _) if adt.is_enum() => adt.repr().discr_type().to_ty(tcx),
ty::Coroutine(_, args) => args.as_coroutine().discr_ty(tcx),

ty::Param(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {
ty::Param(_) | ty::Placeholder(_) | ty::Alias(..) | ty::Infer(ty::TyVar(_)) => {

@fee1-dead fee1-dead Jul 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Is this needed and correct? The UnsafeBinder arm below just instantiates with erased. Placeholders have discriminants question mark? cc @rust-lang/types

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is for the next solver. IIUC, placeholders don't have a known concrete discriminant type, so we return <!0 as DiscriminantKind>::Discriminant rather than inventing u8. Same pattern as other unknown types in this function.

let assoc_items = tcx.associated_item_def_ids(
tcx.require_lang_item(hir::LangItem::DiscriminantKind, DUMMY_SP),
);
Expand Down Expand Up @@ -1757,9 +1757,7 @@ impl<'tcx> Ty<'tcx> {
| ty::Error(_)
| ty::Infer(IntVar(_) | FloatVar(_)) => tcx.types.u8,

ty::Bound(..)
| ty::Placeholder(_)
| ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
ty::Bound(..) | ty::Infer(FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`discriminant_ty` applied to unexpected type: {:?}", self)
}
}
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1001,13 +1001,9 @@ where
| ty::Slice(_)
| ty::Dynamic(_, _)
| ty::Tuple(_)
| ty::UnsafeBinder(_)
| ty::Error(_) => self_ty.discriminant_ty(ecx.cx()),

ty::UnsafeBinder(_) => {
// FIXME(unsafe_binders): instantiate this with placeholders?? i guess??
todo!("discr subgoal...")
}

// Given an alias, parameter, or placeholder we add an impl candidate normalizing to a rigid
// alias. In case there's a where-bound further constraining this alias it is preferred over
// this impl candidate anyways. It's still a bit scuffed.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,11 +1081,10 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::CoroutineWitness(..)
| ty::Never
| ty::Tuple(..)
| ty::UnsafeBinder(_)
// Integers and floats always have `u8` as their discriminant.
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,

ty::UnsafeBinder(_) => todo!("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
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/unsafe-binders/discriminant-kind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Regression test for https://github.com/rust-lang/rust/issues/158839
//@ check-pass
//@ revisions: current next
//@ [next] compile-flags: -Znext-solver=globally

#![feature(unsafe_binders)]

fn foo<T: std::marker::Copy>(x: unsafe<> T) {
std::mem::discriminant(&x);
}

fn main() {}
Loading