Skip to content

Commit bb73ea6

Browse files
authored
Rollup merge of #79231 - wusyong:issue-79137, r=lcnr
Exhaustively match in variant count instrinsic Fix #79137
2 parents 5d428ca + bc43380 commit bb73ea6

File tree

4 files changed

+81
-7
lines changed

4 files changed

+81
-7
lines changed

compiler/rustc_mir/src/interpret/intrinsics.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,35 @@ crate fn eval_nullary_intrinsic<'tcx>(
7575
ensure_monomorphic_enough(tcx, tp_ty)?;
7676
ConstValue::from_u64(tcx.type_id_hash(tp_ty))
7777
}
78-
sym::variant_count => {
79-
if let ty::Adt(ref adt, _) = tp_ty.kind() {
80-
ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx)
81-
} else {
82-
ConstValue::from_machine_usize(0u64, &tcx)
83-
}
84-
}
78+
sym::variant_count => match tp_ty.kind() {
79+
ty::Adt(ref adt, _) => ConstValue::from_machine_usize(adt.variants.len() as u64, &tcx),
80+
ty::Projection(_)
81+
| ty::Opaque(_, _)
82+
| ty::Param(_)
83+
| ty::Bound(_, _)
84+
| ty::Placeholder(_)
85+
| ty::Infer(_) => throw_inval!(TooGeneric),
86+
ty::Bool
87+
| ty::Char
88+
| ty::Int(_)
89+
| ty::Uint(_)
90+
| ty::Float(_)
91+
| ty::Foreign(_)
92+
| ty::Str
93+
| ty::Array(_, _)
94+
| ty::Slice(_)
95+
| ty::RawPtr(_)
96+
| ty::Ref(_, _, _)
97+
| ty::FnDef(_, _)
98+
| ty::FnPtr(_)
99+
| ty::Dynamic(_, _)
100+
| ty::Closure(_, _)
101+
| ty::Generator(_, _, _)
102+
| ty::GeneratorWitness(_)
103+
| ty::Never
104+
| ty::Tuple(_)
105+
| ty::Error(_) => ConstValue::from_machine_usize(0u64, &tcx),
106+
},
85107
other => bug!("`{}` is not a zero arg intrinsic", other),
86108
})
87109
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// check-pass
2+
3+
// Verify that variant count intrinsic can still evaluate for types like `Option<T>`.
4+
5+
#![feature(variant_count)]
6+
7+
pub struct GetVariantCount<T>(T);
8+
9+
impl<T> GetVariantCount<T> {
10+
pub const VALUE: usize = std::mem::variant_count::<T>();
11+
}
12+
13+
const fn check_variant_count<T>() -> bool {
14+
matches!(GetVariantCount::<Option<T>>::VALUE, GetVariantCount::<Option<()>>::VALUE)
15+
}
16+
17+
fn main() {
18+
assert!(check_variant_count::<()>());
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Test that `variant_count` only gets evaluated once the type is concrete enough.
2+
3+
#![feature(variant_count)]
4+
5+
pub struct GetVariantCount<T>(T);
6+
7+
impl<T> GetVariantCount<T> {
8+
pub const VALUE: usize = std::mem::variant_count::<T>();
9+
}
10+
11+
const fn check_variant_count<T>() -> bool {
12+
matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
13+
//~^ ERROR constant pattern depends on a generic parameter
14+
//~| ERROR constant pattern depends on a generic parameter
15+
}
16+
17+
fn main() {
18+
assert!(check_variant_count::<Option<()>>());
19+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: constant pattern depends on a generic parameter
2+
--> $DIR/issue-79137-toogeneric.rs:12:43
3+
|
4+
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: constant pattern depends on a generic parameter
8+
--> $DIR/issue-79137-toogeneric.rs:12:43
9+
|
10+
LL | matches!(GetVariantCount::<T>::VALUE, GetVariantCount::<T>::VALUE)
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

0 commit comments

Comments
 (0)