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

fix static_ptr_ty for foreign statics #78101

Merged
merged 3 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
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
9 changes: 3 additions & 6 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_middle/src/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +155 to +162
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be deduplicated with the other site by putting it in a function. I see no danger in eagerly normalizing static items' types (so doing it here, too).

Copy link
Member Author

@RalfJung RalfJung Oct 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did that at first, but the lifetime differs. That lead to ICEs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uff, right

}
}
Rvalue::Ref(reg, bk, ref place) => {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir/src/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
}
Expand All @@ -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
Expand Down