Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove qualify_min_const_fn pass #68940

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3851,6 +3851,7 @@ dependencies = [
"rustc_feature",
"rustc_hir",
"rustc_index",
"rustc_mir",
"rustc_session",
"rustc_span",
"rustc_target",
265 changes: 209 additions & 56 deletions src/librustc_mir/transform/check_consts/ops.rs

Large diffs are not rendered by default.

265 changes: 195 additions & 70 deletions src/librustc_mir/transform/check_consts/validation.rs

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@ pub mod inline;
pub mod instcombine;
pub mod no_landing_pads;
pub mod promote_consts;
pub mod qualify_min_const_fn;
pub mod remove_noop_landing_pads;
pub mod rustc_peek;
pub mod simplify;
@@ -205,7 +204,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
};

let mut validator = check_consts::validation::Validator::new(&item);
validator.check_body();
validator.check_item();

// We return the qualifs in the return place for every MIR body, even though it is only used
// when deciding to promote a reference to a `const` for now.
380 changes: 0 additions & 380 deletions src/librustc_mir/transform/qualify_min_const_fn.rs

This file was deleted.

1 change: 1 addition & 0 deletions src/librustc_passes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
rustc_errors = { path = "../librustc_errors" }
rustc_feature = { path = "../librustc_feature" }
rustc_hir = { path = "../librustc_hir" }
rustc_mir = { path = "../librustc_mir" }
rustc_index = { path = "../librustc_index" }
rustc_session = { path = "../librustc_session" }
rustc_target = { path = "../librustc_target" }
54 changes: 44 additions & 10 deletions src/librustc_passes/check_const.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
//! through, but errors for structured control flow in a `const` should be emitted here.
use rustc::hir::map::Map;
use rustc::hir::Hir;
use rustc::session::config::nightly_options;
use rustc::session::parse::feature_err;
use rustc::ty::query::Providers;
@@ -17,6 +16,7 @@ use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_mir::const_eval::is_min_const_fn;
use rustc_span::{sym, Span, Symbol};
use syntax::ast::Mutability;

@@ -28,6 +28,8 @@ enum NonConstExpr {
Loop(hir::LoopSource),
Match(hir::MatchSource),
OrPattern,
LogicalOr,
LogicalAnd,
}

impl NonConstExpr {
@@ -36,6 +38,8 @@ impl NonConstExpr {
Self::Loop(src) => format!("`{}`", src.name()),
Self::Match(src) => format!("`{}`", src.name()),
Self::OrPattern => format!("or-pattern"),
Self::LogicalOr => format!("`||`"),
Self::LogicalAnd => format!("`&&`"),
}
}

@@ -47,6 +51,8 @@ impl NonConstExpr {
Self::Match(Normal)
| Self::Match(IfDesugar { .. })
| Self::Match(IfLetDesugar { .. })
| Self::LogicalOr
| Self::LogicalAnd
| Self::OrPattern => &[sym::const_if_match],

Self::Loop(Loop) => &[sym::const_loop],
@@ -65,26 +71,34 @@ impl NonConstExpr {
}
}

#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Eq)]
enum ConstKind {
Static,
StaticMut,
ConstFn,
MinConstFn,
Const,
AnonConst,
}

impl ConstKind {
fn for_body(body: &hir::Body<'_>, hir_map: Hir<'_>) -> Option<Self> {
let is_const_fn = |id| hir_map.fn_sig_by_hir_id(id).unwrap().header.is_const();

let owner = hir_map.body_owner(body.id());
let const_kind = match hir_map.body_owner_kind(owner) {
fn for_body(tcx: TyCtxt<'_>, body: &hir::Body<'_>) -> Option<Self> {
let owner = tcx.hir().body_owner(body.id());
let const_kind = match tcx.hir().body_owner_kind(owner) {
hir::BodyOwnerKind::Const => Self::Const,
hir::BodyOwnerKind::Static(Mutability::Mut) => Self::StaticMut,
hir::BodyOwnerKind::Static(Mutability::Not) => Self::Static,

hir::BodyOwnerKind::Fn if is_const_fn(owner) => Self::ConstFn,
hir::BodyOwnerKind::Fn if is_min_const_fn(tcx, tcx.hir().local_def_id(owner)) => {
Self::MinConstFn
}

// Use `is_const_fn_raw` here since we need to check the bodies of unstable `const fn`
// as well as stable ones.
hir::BodyOwnerKind::Fn if tcx.is_const_fn_raw(tcx.hir().local_def_id(owner)) => {
Self::ConstFn
}

hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure => return None,
};

@@ -98,7 +112,7 @@ impl fmt::Display for ConstKind {
Self::Static => "static",
Self::StaticMut => "static mut",
Self::Const | Self::AnonConst => "const",
Self::ConstFn => "const fn",
Self::MinConstFn | Self::ConstFn => "const fn",
};

write!(f, "{}", s)
@@ -212,7 +226,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
}

fn visit_body(&mut self, body: &'tcx hir::Body<'tcx>) {
let kind = ConstKind::for_body(body, self.tcx.hir());
let kind = ConstKind::for_body(self.tcx, body);
self.recurse_into(kind, |this| intravisit::walk_body(this, body));
}

@@ -230,6 +244,26 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
// Skip the following checks if we are not currently in a const context.
_ if self.const_kind.is_none() => {}

// Short-circuiting operators were forbidden outright in the min_const_fn checks. In
// other contexts, they are converted to non-short-circuiting operators while lowering
// to MIR and marked as "control-flow destroyed". Bodies whose control-flow has been
// altered in this manner are rejected during MIR const-checking if they have any
// user-declared locals, since the user could observe the change like so:
//
// let mut altered_control_flow = false;
// true && { altered_control_flow = true; false }
hir::ExprKind::Binary(kind, _, _) if self.const_kind == Some(ConstKind::MinConstFn) => {
let expr = match kind.node {
hir::BinOpKind::And => Some(NonConstExpr::LogicalAnd),
hir::BinOpKind::Or => Some(NonConstExpr::LogicalOr),
_ => None,
};

if let Some(expr) = expr {
self.const_check_violated(expr, e.span);
}
}

hir::ExprKind::Loop(_, _, source) => {
self.const_check_violated(NonConstExpr::Loop(*source), e.span);
}
4 changes: 0 additions & 4 deletions src/test/ui/consts/min_const_fn/min_const_fn.rs
Original file line number Diff line number Diff line change
@@ -98,10 +98,6 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize }
const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
//~^ ERROR casting pointers to ints is unstable
const fn foo30_6() -> bool { let x = true; x }
const fn foo36(a: bool, b: bool) -> bool { a && b }
//~^ ERROR loops and conditional expressions are not stable in const fn
const fn foo37(a: bool, b: bool) -> bool { a || b }
//~^ ERROR loops and conditional expressions are not stable in const fn
const fn inc(x: &mut i32) { *x += 1 }
//~^ ERROR mutable references in const fn are unstable

6 changes: 6 additions & 0 deletions src/test/ui/consts/min_const_fn/short_circuiting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const fn and(a: bool, b: bool) -> bool { a && b }
//~^ ERROR `&&` is not allowed in a `const fn`
const fn or(a: bool, b: bool) -> bool { a || b }
//~^ ERROR `||` is not allowed in a `const fn`

fn main() {}
21 changes: 21 additions & 0 deletions src/test/ui/consts/min_const_fn/short_circuiting.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0658]: `&&` is not allowed in a `const fn`
--> $DIR/short_circuiting.rs:1:42
|
LL | const fn and(a: bool, b: bool) -> bool { a && b }
| ^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error[E0658]: `||` is not allowed in a `const fn`
--> $DIR/short_circuiting.rs:3:41
|
LL | const fn or(a: bool, b: bool) -> bool { a || b }
| ^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/49146
= help: add `#![feature(const_if_match)]` to the crate attributes to enable

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.