about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeSeulArtichaut <leseulartichaut@gmail.com>2021-05-13 23:36:19 +0200
committerLeSeulArtichaut <leseulartichaut@gmail.com>2021-05-22 16:21:33 +0200
commit6dfdea9800fddeeed8a94ea2bbd4afeab96bb05c (patch)
treea354df7f3551d24d75ec997a385cf43067002fdb
parent6f64eb1fe65f37c3895375c03374cb8680bcd09e (diff)
downloadrust-6dfdea9800fddeeed8a94ea2bbd4afeab96bb05c.tar.gz
rust-6dfdea9800fddeeed8a94ea2bbd4afeab96bb05c.zip
Make the THIR unsafeck use the `thir_body` query
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs12
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs32
-rw-r--r--compiler/rustc_mir_build/src/thir/visit.rs3
-rw-r--r--src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr44
-rw-r--r--src/test/ui/issues/issue-16538.thir.stderr16
5 files changed, 53 insertions, 54 deletions
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 153a1f6de5d..b5d26e81a51 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -46,6 +46,18 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
     let body_owner_kind = tcx.hir().body_owner_kind(id);
     let typeck_results = tcx.typeck_opt_const_arg(def);
 
+    if tcx.sess.opts.debugging_opts.thir_unsafeck {
+        // Ensure unsafeck is ran before we steal the THIR.
+        match def {
+            ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => {
+                tcx.ensure().thir_check_unsafety_for_const_arg((did, const_param_did))
+            }
+            ty::WithOptConstParam { did, const_param_did: None } => {
+                tcx.ensure().thir_check_unsafety(did)
+            }
+        }
+    }
+
     // Figure out what primary body this item has.
     let (body_id, return_ty_span, span_with_body) = match tcx.hir().get(id) {
         Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) => {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index aa8193dab5d..d0d376bd3e3 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -1,8 +1,8 @@
 use crate::thir::visit::{self, Visitor};
-use crate::thir::*;
 
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_middle::thir::*;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
 use rustc_session::lint::Level;
@@ -328,13 +328,10 @@ impl UnsafeOpKind {
 
 // FIXME: checking unsafety for closures should be handled by their parent body,
 // as they inherit their "safety context" from their declaration site.
-pub fn check_unsafety<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    thir: &Thir<'tcx>,
-    expr: ExprId,
-    def_id: LocalDefId,
-    hir_id: hir::HirId,
-) {
+pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) {
+    let (thir, expr) = tcx.thir_body(def);
+    let thir = &thir.borrow();
+    let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
     let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
         if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
             BodyUnsafety::Unsafe(fn_sig.span)
@@ -342,12 +339,12 @@ pub fn check_unsafety<'tcx>(
             BodyUnsafety::Safe
         }
     });
-    let body_target_features = &tcx.codegen_fn_attrs(def_id).target_features;
+    let body_target_features = &tcx.codegen_fn_attrs(def.did).target_features;
     let safety_context =
         if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
     let is_const = match tcx.hir().body_owner_kind(hir_id) {
         hir::BodyOwnerKind::Closure => false,
-        hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def_id.to_def_id()),
+        hir::BodyOwnerKind::Fn => tcx.is_const_fn_raw(def.did.to_def_id()),
         hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => true,
     };
     let mut visitor = UnsafetyVisitor {
@@ -362,22 +359,11 @@ pub fn check_unsafety<'tcx>(
     visitor.visit_expr(&thir[expr]);
 }
 
-crate fn thir_check_unsafety_inner<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    def: ty::WithOptConstParam<LocalDefId>,
-) {
-    let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
-    let body_id = tcx.hir().body_owned_by(hir_id);
-    let body = tcx.hir().body(body_id);
-    let (thir, expr) = cx::build_thir(tcx, def, &body.value);
-    check_unsafety(tcx, &thir, expr, def.did, hir_id);
-}
-
 crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
     if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) {
         tcx.thir_check_unsafety_for_const_arg(def)
     } else {
-        thir_check_unsafety_inner(tcx, ty::WithOptConstParam::unknown(def_id))
+        check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id))
     }
 }
 
@@ -385,5 +371,5 @@ crate fn thir_check_unsafety_for_const_arg<'tcx>(
     tcx: TyCtxt<'tcx>,
     (did, param_did): (LocalDefId, DefId),
 ) {
-    thir_check_unsafety_inner(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
+    check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) })
 }
diff --git a/compiler/rustc_mir_build/src/thir/visit.rs b/compiler/rustc_mir_build/src/thir/visit.rs
index 671d1fe9b03..1a60b1de7fd 100644
--- a/compiler/rustc_mir_build/src/thir/visit.rs
+++ b/compiler/rustc_mir_build/src/thir/visit.rs
@@ -1,4 +1,5 @@
-use crate::thir::*;
+use rustc_middle::thir::*;
+use rustc_middle::ty::Const;
 
 pub trait Visitor<'a, 'tcx: 'a>: Sized {
     fn thir(&self) -> &'a Thir<'tcx>;
diff --git a/src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr b/src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr
index 04efea0b230..df0de7a9590 100644
--- a/src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr
+++ b/src/test/ui/feature-gates/feature-gate-const_fn_transmute.thir.stderr
@@ -58,6 +58,14 @@ LL | const unsafe fn unsafe_transmute_fn_core_intrinsic() -> u32 { core::intrins
    = help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
    = note: `transmute` is only allowed in constants and statics for now
 
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+  --> $DIR/feature-gate-const_fn_transmute.rs:29:39
+   |
+LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
 error[E0658]: `transmute` is not allowed in constant functions
   --> $DIR/feature-gate-const_fn_transmute.rs:29:39
    |
@@ -68,49 +76,41 @@ LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
    = help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
    = note: `transmute` is only allowed in constants and statics for now
 
-error[E0658]: `transmute` is not allowed in constant functions
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
   --> $DIR/feature-gate-const_fn_transmute.rs:33:49
    |
 LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
    |
-   = note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
-   = help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
-   = note: `transmute` is only allowed in constants and statics for now
+   = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0658]: `transmute` is not allowed in constant functions
-  --> $DIR/feature-gate-const_fn_transmute.rs:37:54
+  --> $DIR/feature-gate-const_fn_transmute.rs:33:49
    |
-LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
-   |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
    = help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
    = note: `transmute` is only allowed in constants and statics for now
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-const_fn_transmute.rs:29:39
-   |
-LL | const fn safe_transmute_fn() -> u32 { mem::transmute(Foo(3)) }
-   |                                       ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
-   |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
-
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-const_fn_transmute.rs:33:49
+  --> $DIR/feature-gate-const_fn_transmute.rs:37:54
    |
-LL | const fn safe_transmute_fn_intrinsic() -> u32 { std::intrinsics::transmute(Foo(3)) }
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
+   |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
-error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+error[E0658]: `transmute` is not allowed in constant functions
   --> $DIR/feature-gate-const_fn_transmute.rs:37:54
    |
 LL | const fn safe_transmute_fn_core_intrinsic() -> u32 { core::intrinsics::transmute(Foo(3)) }
-   |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+   |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consult the function's documentation for information on how to avoid undefined behavior
+   = note: see issue #53605 <https://github.com/rust-lang/rust/issues/53605> for more information
+   = help: add `#![feature(const_fn_transmute)]` to the crate attributes to enable
+   = note: `transmute` is only allowed in constants and statics for now
 
 error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/issues/issue-16538.thir.stderr b/src/test/ui/issues/issue-16538.thir.stderr
index d7e8c08bb01..435334c3228 100644
--- a/src/test/ui/issues/issue-16538.thir.stderr
+++ b/src/test/ui/issues/issue-16538.thir.stderr
@@ -1,3 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/issue-16538.rs:14:34
+   |
+LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
+   |                                  ^^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
 error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
   --> $DIR/issue-16538.rs:14:27
    |
@@ -13,14 +21,6 @@ LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
    = help: the trait `Sync` is not implemented for `*const usize`
    = note: shared static variables must have a type that implements `Sync`
 
-error[E0133]: use of extern static is unsafe and requires unsafe function or block
-  --> $DIR/issue-16538.rs:14:34
-   |
-LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
-   |                                  ^^^^ use of extern static
-   |
-   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-
 error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0015, E0133, E0277.