about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2019-10-28 10:26:16 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2019-11-15 10:33:32 -0800
commit55da0c03680f9ce30423cb640256b11ed6c8cabd (patch)
tree19d4fcaa275227b2aa59babdaeaa760faa41205b /src
parent973b16ab4b2d044f777616f59a2d33fbbbc0fe49 (diff)
downloadrust-55da0c03680f9ce30423cb640256b11ed6c8cabd.tar.gz
rust-55da0c03680f9ce30423cb640256b11ed6c8cabd.zip
Use new const-checker for `mir_const_qualif`
Now `mir_const_qualif` must be called for `static`s and `const fn`s as
well as `const`s since it is responsible for const-checking. We return
the qualifs in the return place for everything, even though they will
only be used for `const`s.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/transform/mod.rs39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 02ed12eda67..64649e93481 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -2,7 +2,7 @@ use crate::{build, shim};
 use rustc_index::vec::IndexVec;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::mir::{Body, MirPhase, Promoted};
-use rustc::ty::{TyCtxt, InstanceDef};
+use rustc::ty::{TyCtxt, InstanceDef, TypeFoldable};
 use rustc::ty::query::Providers;
 use rustc::ty::steal::Steal;
 use rustc::hir;
@@ -39,12 +39,12 @@ pub mod uniform_array_move_out;
 pub mod uninhabited_enum_branching;
 
 pub(crate) fn provide(providers: &mut Providers<'_>) {
-    self::qualify_consts::provide(providers);
     self::check_unsafety::provide(providers);
     *providers = Providers {
         mir_keys,
         mir_built,
         mir_const,
+        mir_const_qualif,
         mir_validated,
         optimized_mir,
         is_mir_available,
@@ -185,6 +185,41 @@ pub fn run_passes(
     body.phase = mir_phase;
 }
 
+fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> u8 {
+    let const_kind = check_consts::ConstKind::for_item(tcx, def_id);
+
+    // No need to const-check a non-const `fn`.
+    if const_kind.is_none() {
+        return 0;
+    }
+
+    // N.B., this `borrow()` is guaranteed to be valid (i.e., the value
+    // cannot yet be stolen), because `mir_validated()`, which steals
+    // from `mir_const(), forces this query to execute before
+    // performing the steal.
+    let body = &tcx.mir_const(def_id).borrow();
+
+    if body.return_ty().references_error() {
+        tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
+        return 0;
+    }
+
+    let item = check_consts::Item {
+        body,
+        tcx,
+        def_id,
+        const_kind,
+        param_env: tcx.param_env(def_id),
+    };
+
+    let mut validator = check_consts::validation::Validator::new(&item);
+    validator.check_body();
+
+    // 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.
+    validator.qualifs_in_return_place().into()
+}
+
 fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     // Unsafety check uses the raw mir, so make sure it is run
     let _ = tcx.unsafety_check_result(def_id);