Exhaustively match in variant count instrinsic
This commit is contained in:
parent
172acf8f61
commit
459c83f980
@ -75,13 +75,16 @@ fn numeric_intrinsic<'tcx, Tag>(
|
||||
ensure_monomorphic_enough(tcx, tp_ty)?;
|
||||
ConstValue::from_u64(tcx.type_id_hash(tp_ty))
|
||||
}
|
||||
sym::variant_count => {
|
||||
if let ty::Adt(ref adt, _) = tp_ty.kind() {
|
||||
ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx)
|
||||
} else {
|
||||
ConstValue::from_machine_usize(0u64, &tcx)
|
||||
}
|
||||
}
|
||||
sym::variant_count => match tp_ty.kind() {
|
||||
ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
|
||||
ty::Projection(_)
|
||||
| ty::Opaque(_, _)
|
||||
| ty::Param(_)
|
||||
| ty::Bound(_, _)
|
||||
| ty::Placeholder(_)
|
||||
| ty::Infer(_) => throw_inval!(TooGeneric),
|
||||
_ => ConstValue::from_machine_usize(0u64, &tcx),
|
||||
},
|
||||
other => bug!("`{}` is not a zero arg intrinsic", other),
|
||||
})
|
||||
}
|
||||
|
19
src/test/ui/consts/issue-79137-monomorphic.rs
Normal file
19
src/test/ui/consts/issue-79137-monomorphic.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// check-pass
|
||||
|
||||
// Verify that variant count intrinsic can still evaluate for types like `Option<T>`.
|
||||
|
||||
#![feature(variant_count)]
|
||||
|
||||
pub struct GetVariantCount<T>(T);
|
||||
|
||||
impl<T> GetVariantCount<T> {
|
||||
pub const VALUE: usize = std::mem::variant_count::<T>();
|
||||
}
|
||||
|
||||
const fn check_variant_count<T>() -> bool {
|
||||
matches!(GetVariantCount::<Option<T>>::VALUE, GetVariantCount::<Option<()>>::VALUE)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert!(check_variant_count::<()>());
|
||||
}
|
21
src/test/ui/consts/issue-79137-toogeneric.rs
Normal file
21
src/test/ui/consts/issue-79137-toogeneric.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// The instrinsic call for variant count should exhaustively match on `tp_ty` and forbid
|
||||
// `ty::Projection`, `ty::Opaque`, `ty::Param`, `ty::Bound`, `ty::Placeholder` and `ty::Infer`
|
||||
// variant. This test checks that it will fail if it's too generic.
|
||||
|
||||
#![feature(variant_count)]
|
||||
|
||||
pub struct GetVariantCount<T>(T);
|
||||
|
||||
impl<T> GetVariantCount<T> {
|
||||
pub const VALUE: usize = std::mem::variant_count::<T>();
|
||||
}
|
||||
|
||||
const fn check_variant_count<T>() -> bool {
|
||||
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
//~^ ERROR constant pattern depends on a generic parameter
|
||||
//~| ERROR constant pattern depends on a generic parameter
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert!(check_variant_count::<Option<()>>());
|
||||
}
|
14
src/test/ui/consts/issue-79137-toogeneric.stderr
Normal file
14
src/test/ui/consts/issue-79137-toogeneric.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-79137-toogeneric.rs:14:43
|
||||
|
|
||||
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant pattern depends on a generic parameter
|
||||
--> $DIR/issue-79137-toogeneric.rs:14:43
|
||||
|
|
||||
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user