Rollup merge of #71688 - ecstatic-morse:const-downcast, r=oli-obk
Allow `Downcast` projections unconditionally in const-checking `ProjectionElem::Downcast` sounds scary, but it's really just the projection we use to access a particular enum variant. They usually appear in the lowering of a `match` statement, so they have been associated with control flow in const-checking, but they don't do any control flow by themselves. We already have a HIR pass that looks for `if` and `match` (even ones that have 1 or fewer reachable branches). That pass is double-checked by a MIR pass that looks for `SwitchInt`s and `FakeRead`s for match scrutinees. In my opinion, there's no need to look for `Downcast` as well. r? @oli-obk
This commit is contained in:
commit
a8e0511b32
9 changed files with 6 additions and 47 deletions
|
@ -53,15 +53,6 @@ pub trait NonConstOp: std::fmt::Debug {
|
|||
}
|
||||
}
|
||||
|
||||
/// A `Downcast` projection.
|
||||
#[derive(Debug)]
|
||||
pub struct Downcast;
|
||||
impl NonConstOp for Downcast {
|
||||
fn feature_gate() -> Option<Symbol> {
|
||||
Some(sym::const_if_match)
|
||||
}
|
||||
}
|
||||
|
||||
/// A function call where the callee is a pointer.
|
||||
#[derive(Debug)]
|
||||
pub struct FnCallIndirect;
|
||||
|
|
|
@ -472,6 +472,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Field(..)
|
||||
| ProjectionElem::Index(_) => {
|
||||
|
@ -484,10 +485,6 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
ProjectionElem::Downcast(..) => {
|
||||
self.check_op(ops::Downcast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -286,11 +286,6 @@ fn check_place(
|
|||
while let &[ref proj_base @ .., elem] = cursor {
|
||||
cursor = proj_base;
|
||||
match elem {
|
||||
ProjectionElem::Downcast(..) if !feature_allowed(tcx, def_id, sym::const_if_match) => {
|
||||
return Err((span, "`match` or `if let` in `const fn` is unstable".into()));
|
||||
}
|
||||
ProjectionElem::Downcast(_symbol, _variant_index) => {}
|
||||
|
||||
ProjectionElem::Field(..) => {
|
||||
let base_ty = Place::ty_from(place.local, &proj_base, body, tcx).ty;
|
||||
if let Some(def) = base_ty.ty_adt_def() {
|
||||
|
@ -303,6 +298,7 @@ fn check_place(
|
|||
}
|
||||
}
|
||||
ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Downcast(..)
|
||||
| ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Deref
|
||||
| ProjectionElem::Index(_) => {}
|
||||
|
|
|
@ -10,7 +10,6 @@ const fn f(x: usize) -> usize {
|
|||
//~| ERROR E0658
|
||||
//~| ERROR E0080
|
||||
//~| ERROR E0744
|
||||
//~| ERROR E0019
|
||||
sum += i;
|
||||
}
|
||||
sum
|
||||
|
|
|
@ -11,6 +11,5 @@ fn main() {
|
|||
//~| ERROR calls in constants are limited to constant functions
|
||||
//~| ERROR references in constants may only refer to immutable values
|
||||
//~| ERROR calls in constants are limited to constant functions
|
||||
//~| ERROR constant contains unimplemented expression type
|
||||
//~| ERROR evaluation of constant value failed
|
||||
}
|
||||
|
|
|
@ -113,6 +113,5 @@ fn main() { //[if_match]~ ERROR fatal error triggered by #[rustc_error]
|
|||
//[stock]~^ ERROR `match` is not allowed in a `const`
|
||||
if let Some(x) = Some(x) { x } else { 1 }
|
||||
//[stock]~^ ERROR `if` is not allowed in a `const`
|
||||
//[stock]~| ERROR constant contains unimplemented expression type
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -237,13 +237,6 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
|||
= note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/feature-gate-const-if-match.rs:114:21
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^
|
||||
error: aborting due to 24 previous errors
|
||||
|
||||
error: aborting due to 25 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0658.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
|
@ -30,8 +30,6 @@ fn main() {
|
|||
let x = Ok(3);
|
||||
let Ok(y) | Err(y) = x;
|
||||
//~^ ERROR or-pattern is not allowed in a `const`
|
||||
//~| ERROR constant contains unimplemented expression type
|
||||
//~| ERROR constant contains unimplemented expression type
|
||||
2
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -52,19 +52,6 @@ LL | let Ok(y) | Err(y) = x;
|
|||
= note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/feature-gate-const-fn.rs:31:25
|
||||
|
|
||||
LL | let Ok(y) | Err(y) = x;
|
||||
| ^
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/feature-gate-const-fn.rs:31:16
|
||||
|
|
||||
LL | let Ok(y) | Err(y) = x;
|
||||
| ^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0019, E0658.
|
||||
For more information about an error, try `rustc --explain E0019`.
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue