1
Fork 0

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:
Tyler Mandry 2020-04-30 15:23:17 -07:00 committed by GitHub
commit a8e0511b32
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 6 additions and 47 deletions

View file

@ -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. /// A function call where the callee is a pointer.
#[derive(Debug)] #[derive(Debug)]
pub struct FnCallIndirect; pub struct FnCallIndirect;

View file

@ -472,6 +472,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
} }
ProjectionElem::ConstantIndex { .. } ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Downcast(..)
| ProjectionElem::Subslice { .. } | ProjectionElem::Subslice { .. }
| ProjectionElem::Field(..) | ProjectionElem::Field(..)
| ProjectionElem::Index(_) => { | ProjectionElem::Index(_) => {
@ -484,10 +485,6 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
_ => {} _ => {}
} }
} }
ProjectionElem::Downcast(..) => {
self.check_op(ops::Downcast);
}
} }
} }

View file

@ -286,11 +286,6 @@ fn check_place(
while let &[ref proj_base @ .., elem] = cursor { while let &[ref proj_base @ .., elem] = cursor {
cursor = proj_base; cursor = proj_base;
match elem { 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(..) => { ProjectionElem::Field(..) => {
let base_ty = Place::ty_from(place.local, &proj_base, body, tcx).ty; let base_ty = Place::ty_from(place.local, &proj_base, body, tcx).ty;
if let Some(def) = base_ty.ty_adt_def() { if let Some(def) = base_ty.ty_adt_def() {
@ -303,6 +298,7 @@ fn check_place(
} }
} }
ProjectionElem::ConstantIndex { .. } ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Downcast(..)
| ProjectionElem::Subslice { .. } | ProjectionElem::Subslice { .. }
| ProjectionElem::Deref | ProjectionElem::Deref
| ProjectionElem::Index(_) => {} | ProjectionElem::Index(_) => {}

View file

@ -10,7 +10,6 @@ const fn f(x: usize) -> usize {
//~| ERROR E0658 //~| ERROR E0658
//~| ERROR E0080 //~| ERROR E0080
//~| ERROR E0744 //~| ERROR E0744
//~| ERROR E0019
sum += i; sum += i;
} }
sum sum

View file

@ -11,6 +11,5 @@ fn main() {
//~| ERROR calls in constants are limited to constant functions //~| ERROR calls in constants are limited to constant functions
//~| ERROR references in constants may only refer to immutable values //~| ERROR references in constants may only refer to immutable values
//~| ERROR calls in constants are limited to constant functions //~| ERROR calls in constants are limited to constant functions
//~| ERROR constant contains unimplemented expression type
//~| ERROR evaluation of constant value failed //~| ERROR evaluation of constant value failed
} }

View file

@ -113,6 +113,5 @@ fn main() { //[if_match]~ ERROR fatal error triggered by #[rustc_error]
//[stock]~^ ERROR `match` is not allowed in a `const` //[stock]~^ ERROR `match` is not allowed in a `const`
if let Some(x) = Some(x) { x } else { 1 } if let Some(x) = Some(x) { x } else { 1 }
//[stock]~^ ERROR `if` is not allowed in a `const` //[stock]~^ ERROR `if` is not allowed in a `const`
//[stock]~| ERROR constant contains unimplemented expression type
}]; }];
} }

View file

@ -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 = 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 = help: add `#![feature(const_if_match)]` to the crate attributes to enable
error[E0019]: constant contains unimplemented expression type error: aborting due to 24 previous errors
--> $DIR/feature-gate-const-if-match.rs:114:21
|
LL | if let Some(x) = Some(x) { x } else { 1 }
| ^
error: aborting due to 25 previous errors For more information about this error, try `rustc --explain E0658`.
Some errors have detailed explanations: E0019, E0658.
For more information about an error, try `rustc --explain E0019`.

View file

@ -30,8 +30,6 @@ fn main() {
let x = Ok(3); let x = Ok(3);
let Ok(y) | Err(y) = x; let Ok(y) | Err(y) = x;
//~^ ERROR or-pattern is not allowed in a `const` //~^ ERROR or-pattern is not allowed in a `const`
//~| ERROR constant contains unimplemented expression type
//~| ERROR constant contains unimplemented expression type
2 2
}]; }];
} }

View file

@ -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 = 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 = help: add `#![feature(const_if_match)]` to the crate attributes to enable
error[E0019]: constant contains unimplemented expression type error: aborting due to 6 previous errors
--> $DIR/feature-gate-const-fn.rs:31:25
|
LL | let Ok(y) | Err(y) = x;
| ^
error[E0019]: constant contains unimplemented expression type For more information about this error, try `rustc --explain E0658`.
--> $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`.