Change:
I tried this code: I expected the code to run without errors Instead, the assertion failed. Compiler version: 1.46.0-nightly (2020-07-01 )
Seems something wrong with the intrinsics evaluation.
I think the issue is that is in place when we try to hash . I am not very familiar with the code here but I think this might be evaluated before monomorphization which causes this issue.
Another example showing this is pre-monomorphization: rustc happily compiles this, but I would expect something like .
I was trying to do something somewhat similar with const type_id when I filed . There seem to be some inconsistencies in what combinations of generics and patterns are allowed, which might be contributing to the problem.
I have no idea what is going on, but it certainly looks odd... Cc
needs to monomorphize the type before evaluating it I'd guess (an assert checking for would make sense there, too I'd think).
I wonder if instead of we should more explicitly check for "type or const params", but I think it's mostly about aesthetics thanks to miri working with lifetime-erased types. You said "assert" but I think the type is already monomorphized and what we need to do is return if it's not monomorphic. Same for , actually - any reflection that doesn't rely on will have this problem.
oh right, this may be an evaluation happening too early, so is totally reasonable to emit here. I'm always wary of emitting .
Doesn't that mean that the code samples above will be forbidden?
No, just evaluating the consts early will fail. Once everything is monomorphized it will work.
I have an attempt here: It prevents OP's snippet from compiling:
hmm... maybe const prop is interfering here. Can you try running the same build with and ?
Ah, so this is a different issue. It's the same issue (even if a different symptom) of running
Patterns need to be monomorphic, you can never have a pattern that depends on generic parameters. We may lift this restriction in the future, but it's a separate issue and needs a language RFC afaik
in stable and gives in nightly. We will need a better diagnostics for the TooGeneric error.
works on stable, so the old diagnostic was wrong. It's specifically associated constants that depend on generic parameters.
so is the approach of returning all we need to do here? If so would you be happy to open your branch as a PR so we could look at adding some ui tests and whatnot?
The thing I worried is that the error isn't very helpful. Maybe fixing that diagnostics should be a separate PR?
Yea, cleaning up the diagnostics can be done after fixing the bug

Discussion:
}; use rustc_middle::ty; use rustc_middle::ty::subst::SubstsRef; <del> use rustc_middle::ty::{Ty, TyCtxt}; </del> <ins> use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; </ins> use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::{Abi, LayoutOf as _, Primitive, Size};

let name = tcx.item_name(def_id); Ok(match name { sym::type_name => { <ins> if tp_ty.needs_subst() { throw_inval!(TooGeneric); } </ins> let alloc = type_name::alloc_type_name(tcx, tp_ty); ConstValue::Slice { data: alloc, start: 0, end: alloc.len() } }

}; ConstValue::from_machine_usize(n, &tcx) } <del> sym::type_id => ConstValue::from_u64(tcx.type_id_hash(tp_ty)), </del> <ins> sym::type_id => { if tp_ty.needs_subst() { throw_inval!(TooGeneric); } ConstValue::from_u64(tcx.type_id_hash(tp_ty)) } </ins> sym::variant_count => { if let ty::Adt(ref adt, _) = tp_ty.kind { ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx)

<ins> // check-pass // // This test is complement to the test in issue-73976-polymorphic.rs. // In that test we ensure that polymorphic use of type_id and type_name in patterns // will be properly rejected. This test will ensure that monomorphic use of these // would not be wrongly rejected in patterns. #![feature(const_type_id)] #![feature(const_type_name)] use std::any::{self, TypeId}; pub struct GetTypeId<T>(T); impl<T: 'static> GetTypeId<T> { pub const VALUE: TypeId = TypeId::of::<T>(); } const fn check_type_id<T: 'static>() -> bool { matches!(GetTypeId::<T>::VALUE, GetTypeId::<usize>::VALUE) } pub struct GetTypeNameLen<T>(T); impl<T: 'static> GetTypeNameLen<T> { pub const VALUE: usize = any::type_name::<T>().len(); } const fn check_type_name_len<T: 'static>() -> bool { matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<usize>::VALUE) } fn main() { assert!(check_type_id::<usize>()); assert!(check_type_name_len::<usize>()); } </ins>

<ins> // This test is from #73976. We previously did not check if a type is monomorphized // before calculating its type id, which leads to the bizzare behaviour below that // TypeId of a generic type does not match itself. // // This test case should either run-pass or be rejected at compile time. // Currently we just disallow this usage and require pattern is monomorphic. #![feature(const_type_id)] #![feature(const_type_name)] use std::any::{self, TypeId}; pub struct GetTypeId<T>(T); impl<T: 'static> GetTypeId<T> { pub const VALUE: TypeId = TypeId::of::<T>(); } const fn check_type_id<T: 'static>() -> bool { matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) //~^ ERROR could not evaluate constant pattern //~| ERROR could not evaluate constant pattern } pub struct GetTypeNameLen<T>(T); impl<T: 'static> GetTypeNameLen<T> { pub const VALUE: usize = any::type_name::<T>().len(); } const fn check_type_name_len<T: 'static>() -> bool { matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) //~^ ERROR could not evaluate constant pattern //~| ERROR could not evaluate constant pattern } fn main() { assert!(check_type_id::<usize>()); assert!(check_type_name_len::<usize>()); } </ins>

<ins> error: could not evaluate constant pattern --> $DIR/issue-73976-polymorphic.rs:20:37 | LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) |                                     ^^^^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern --> $DIR/issue-73976-polymorphic.rs:32:42 | LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern --> $DIR/issue-73976-polymorphic.rs:20:37 | LL |     matches!(GetTypeId::<T>::VALUE, GetTypeId::<T>::VALUE) |                                     ^^^^^^^^^^^^^^^^^^^^^ error: could not evaluate constant pattern --> $DIR/issue-73976-polymorphic.rs:32:42 | LL |     matches!(GetTypeNameLen::<T>::VALUE, GetTypeNameLen::<T>::VALUE) |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors </ins>