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
This commit is contained in:
commit
83f126bedf
6 changed files with 25 additions and 17 deletions
|
@ -821,9 +821,6 @@ pub struct LocalDecl<'tcx> {
|
||||||
/// flag drop flags to avoid triggering this check as they are introduced
|
/// flag drop flags to avoid triggering this check as they are introduced
|
||||||
/// after typeck.
|
/// 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
|
/// This should be sound because the drop flags are fully algebraic, and
|
||||||
/// therefore don't affect the OIBIT or outlives properties of the
|
/// therefore don't affect the OIBIT or outlives properties of the
|
||||||
/// generator.
|
/// generator.
|
||||||
|
@ -1010,13 +1007,13 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some` if this is a reference to a static item that is used to
|
/// 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 {
|
pub fn is_ref_to_static(&self) -> bool {
|
||||||
matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
|
matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some` if this is a reference to a static item that is used to
|
/// Returns `Some` if this is a reference to a thread-local static item that is used to
|
||||||
/// access that static
|
/// access that static.
|
||||||
pub fn is_ref_to_thread_local(&self) -> bool {
|
pub fn is_ref_to_thread_local(&self) -> bool {
|
||||||
match self.local_info {
|
match self.local_info {
|
||||||
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
|
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
|
||||||
|
|
|
@ -152,10 +152,14 @@ impl<'tcx> Rvalue<'tcx> {
|
||||||
tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
|
tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count))
|
||||||
}
|
}
|
||||||
Rvalue::ThreadLocalRef(did) => {
|
Rvalue::ThreadLocalRef(did) => {
|
||||||
|
let static_ty = tcx.type_of(did);
|
||||||
if tcx.is_mutable_static(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 {
|
} 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) => {
|
Rvalue::Ref(reg, bk, ref place) => {
|
||||||
|
|
|
@ -529,8 +529,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
// Make sure that any constants in the static's type are evaluated.
|
// 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));
|
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) {
|
if self.is_mutable_static(def_id) {
|
||||||
self.mk_mut_ptr(static_ty)
|
self.mk_mut_ptr(static_ty)
|
||||||
|
} else if self.is_foreign_item(def_id) {
|
||||||
|
self.mk_imm_ptr(static_ty)
|
||||||
} else {
|
} else {
|
||||||
self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
|
self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||||
if let [] = proj_base {
|
if let [] = proj_base {
|
||||||
let decl = &self.body.local_decls[place.local];
|
let decl = &self.body.local_decls[place.local];
|
||||||
if decl.internal {
|
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 let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
|
||||||
if self.tcx.is_mutable_static(def_id) {
|
if self.tcx.is_mutable_static(def_id) {
|
||||||
self.require_unsafe(
|
self.require_unsafe(
|
||||||
|
|
|
@ -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 _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 _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 _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: {
|
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::Const
|
||||||
// + ty: &i32
|
// + ty: *const i32
|
||||||
// + val: Value(Scalar(alloc2))
|
// + val: Value(Scalar(alloc2))
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
|
// + 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)) }
|
||||||
_2 = _3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43
|
_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
|
_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
|
_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
|
return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
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 _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 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
|
+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||||
scope 1 {
|
scope 1 {
|
||||||
}
|
}
|
||||||
|
@ -18,16 +18,16 @@
|
||||||
- StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
- 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(_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
|
- 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
|
+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||||
// ty::Const
|
// ty::Const
|
||||||
- // + ty: &i32
|
- // + ty: *const i32
|
||||||
- // + val: Value(Scalar(alloc2))
|
- // + val: Value(Scalar(alloc2))
|
||||||
+ // + ty: &[&i32; 1]
|
+ // + ty: &[&i32; 1]
|
||||||
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0]))
|
+ // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO), const_param_did: None }, [], Some(promoted[0]))
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
|
- // + 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
|
- _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
|
- _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
|
- _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue