diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2020-10-21 13:59:43 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-21 13:59:43 +0900 |
| commit | 83f126bedf227103463f6f505398d72d4efedd42 (patch) | |
| tree | 69f0bc8150091aa84a322a863816eabaeed8b778 | |
| parent | 72ae00bc1df1e2f5b9a68d608347a0aa9b0dede5 (diff) | |
| parent | 153e843c490d569f4faf8f2e625dc7b837df584f (diff) | |
| download | rust-83f126bedf227103463f6f505398d72d4efedd42.tar.gz rust-83f126bedf227103463f6f505398d72d4efedd42.zip | |
Rollup merge of #78101 - RalfJung:foreign-static, r=oli-obk
fix static_ptr_ty for foreign statics Cc https://github.com/rust-lang/rust/issues/74840 This does not fix that issue but fixes a problem in `static_ptr_ty` that we noticed while discussing that issue. I also added and updated a few comments. The one about `internal` locals being ignored does not seem to have been true [even in the commit that introduced it](https://github.com/rust-lang/rust/pull/44700/files#diff-ae2f3c7e2f9744f7ef43e96072b10e98d4e3fe74a3a399a3ad8a810fbe56c520R139). r? @oli-obk
6 files changed, 25 insertions, 17 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b38efedbf60..fa40995407f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> { /// flag drop flags to avoid triggering this check as they are introduced /// after typeck. /// - /// Unsafety checking will also ignore dereferences of these locals, - /// so they can be used for raw pointers only used in a desugaring. - /// /// This should be sound because the drop flags are fully algebraic, and /// therefore don't affect the OIBIT or outlives properties of the /// generator. @@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> { } /// Returns `Some` if this is a reference to a static item that is used to - /// access that static + /// access that static. pub fn is_ref_to_static(&self) -> bool { matches!(self.local_info, Some(box LocalInfo::StaticRef { .. })) } - /// Returns `Some` if this is a reference to a static item that is used to - /// access that static + /// Returns `Some` if this is a reference to a thread-local static item that is used to + /// access that static. pub fn is_ref_to_thread_local(&self) -> bool { match self.local_info { Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local, diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index b9e4f6fb12e..f0bfdae261c 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> { tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count)) } Rvalue::ThreadLocalRef(did) => { + let static_ty = tcx.type_of(did); if tcx.is_mutable_static(did) { - tcx.mk_mut_ptr(tcx.type_of(did)) + tcx.mk_mut_ptr(static_ty) + } else if tcx.is_foreign_item(did) { + tcx.mk_imm_ptr(static_ty) } else { - tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did)) + // FIXME: These things don't *really* have 'static lifetime. + tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty) } } Rvalue::Ref(reg, bk, ref place) => { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index b0f0f0ba57f..4a20e1c32f9 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> { // Make sure that any constants in the static's type are evaluated. let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)); + // Make sure that accesses to unsafe statics end up using raw pointers. + // For thread-locals, this needs to be kept in sync with `Rvalue::ty`. if self.is_mutable_static(def_id) { self.mk_mut_ptr(static_ty) + } else if self.is_foreign_item(def_id) { + self.mk_imm_ptr(static_ty) } else { self.mk_imm_ref(self.lifetimes.re_erased, static_ty) } diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index 7309a4129e4..3d68b862df2 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if let [] = proj_base { let decl = &self.body.local_decls[place.local]; if decl.internal { + // If the projection root is an artifical local that we introduced when + // desugaring `static`, give a more specific error message + // (avoid the general "raw pointer" clause below, that would only be confusing). if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { if self.tcx.is_mutable_static(def_id) { self.require_unsafe( diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir index 0d5760b4cd5..88d583b815a 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].ConstProp.after.mir @@ -4,17 +4,17 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let mut _3: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 bb0: { - _3 = const {alloc2: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 // ty::Const - // + ty: &i32 + // + ty: *const i32 // + val: Value(Scalar(alloc2)) // mir::Constant // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) } - _2 = _3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } + _2 = &(*_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index a392334e0c9..82277b2a21c 100644 --- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -7,7 +7,7 @@ let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let _5: *const i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 scope 1 { } @@ -18,16 +18,16 @@ - StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:13:32: 13:45 - StorageLive(_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 -- _5 = const {alloc2: &i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 +- _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 // ty::Const -- // + ty: &i32 +- // + ty: *const i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] + // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0])) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 -- // + literal: Const { ty: &i32, val: Value(Scalar(alloc2)) } +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } - _4 = &(*_5); // scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 - _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 |
