diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 7ce110dcbfc48..e1af5ba7334fb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -537,10 +537,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let operand = OperandRef { val: OperandValue::Immediate(val), layout: box_layout }; (bx, operand) } - mir::Rvalue::ThreadLocalRef(def_id) => { + mir::Rvalue::ThreadLocalRef(def_id, ty) => { assert!(bx.cx().tcx().is_static(def_id)); let static_ = bx.get_static(def_id); - let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id)); + let layout = bx.layout_of(ty); let operand = OperandRef::from_immediate_or_packed_pair(&mut bx, static_, layout); (bx, operand) } @@ -767,7 +767,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::UnaryOp(..) | mir::Rvalue::Discriminant(..) | mir::Rvalue::NullaryOp(..) | - mir::Rvalue::ThreadLocalRef(_) | + mir::Rvalue::ThreadLocalRef(..) | mir::Rvalue::Use(..) => // (*) true, mir::Rvalue::Repeat(..) | diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 12dc1c1226449..b816fe2e456a6 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2008,7 +2008,9 @@ pub enum Rvalue<'tcx> { /// Accessing a thread local static. This is inherently a runtime operation, even if llvm /// treats it as an access to a static. This `Rvalue` yields a reference to the thread local /// static. - ThreadLocalRef(DefId), + /// The `Ty` field is the type at which the access is happening, so e.g. a + /// `&raw SOME_TLS` will yield a raw pointer, while `&SOME_TLS` will yield a reference. + ThreadLocalRef(DefId, Ty<'tcx>), /// Create a raw pointer to the given place /// Can be generated by raw address of expressions (`&raw const x`), @@ -2149,9 +2151,14 @@ impl<'tcx> Debug for Rvalue<'tcx> { UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Discriminant(ref place) => write!(fmt, "discriminant({:?})", place), NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t), - ThreadLocalRef(did) => ty::tls::with(|tcx| { - let muta = tcx.static_mutability(did).unwrap().prefix_str(); - write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did)) + ThreadLocalRef(did, ty) => ty::tls::with(|tcx| { + let muta = ty.builtin_deref(true).unwrap().mutbl.prefix_str(); + let raw = match ty.kind() { + ty::Ref(..) => "", + ty::RawPtr(..) => "raw ", + _ => bug!("Rvalue::ThreadLocalRef types can only be pointer or reference"), + }; + write!(fmt, "&{}/*tls*/ {}{}", raw, muta, tcx.def_path_str(did)) }), Ref(region, borrow_kind, ref place) => { let kind_str = match borrow_kind { diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index b9e4f6fb12eb1..f044b6afe8b3d 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -151,13 +151,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Repeat(ref operand, count) => { tcx.mk_ty(ty::Array(operand.ty(local_decls, tcx), count)) } - Rvalue::ThreadLocalRef(did) => { - if tcx.is_mutable_static(did) { - tcx.mk_mut_ptr(tcx.type_of(did)) - } else { - tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did)) - } - } + Rvalue::ThreadLocalRef(_, ty) => ty, Rvalue::Ref(reg, bk, ref place) => { let place_ty = place.ty(local_decls, tcx).ty; tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() }) diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ad2eae0298cec..fc8d1dd2b5816 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -176,7 +176,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { match *self { Use(ref op) => Use(op.fold_with(folder)), Repeat(ref op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)), - ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)), + ThreadLocalRef(did, ty) => ThreadLocalRef(did.fold_with(folder), ty.fold_with(folder)), Ref(region, bk, ref place) => { Ref(region.fold_with(folder), bk, place.fold_with(folder)) } @@ -220,7 +220,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { match *self { Use(ref op) => op.visit_with(visitor), Repeat(ref op, _) => op.visit_with(visitor), - ThreadLocalRef(did) => did.visit_with(visitor), + ThreadLocalRef(did, ty) => did.visit_with(visitor) || ty.visit_with(visitor), Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor), AddressOf(_, ref place) => place.visit_with(visitor), Len(ref place) => place.visit_with(visitor), diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index a008bd5f75fa0..7bf41196bb486 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -608,7 +608,7 @@ macro_rules! make_mir_visitor { self.visit_operand(value, location); } - Rvalue::ThreadLocalRef(_) => {} + Rvalue::ThreadLocalRef(_, ty) => self.visit_ty(ty, TyContext::Location(location)), Rvalue::Ref(r, bk, path) => { self.visit_region(r, location); diff --git a/compiler/rustc_mir/src/borrow_check/invalidation.rs b/compiler/rustc_mir/src/borrow_check/invalidation.rs index c84ccafaff5b8..627915672b5b7 100644 --- a/compiler/rustc_mir/src/borrow_check/invalidation.rs +++ b/compiler/rustc_mir/src/borrow_check/invalidation.rs @@ -303,7 +303,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { self.access_place(location, place, access_kind, LocalMutationIsAllowed::No); } - Rvalue::ThreadLocalRef(_) => {} + Rvalue::ThreadLocalRef(..) => {} Rvalue::Use(ref operand) | Rvalue::Repeat(ref operand, _) diff --git a/compiler/rustc_mir/src/borrow_check/mod.rs b/compiler/rustc_mir/src/borrow_check/mod.rs index 64ad0627720aa..a46c5f348593d 100644 --- a/compiler/rustc_mir/src/borrow_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/mod.rs @@ -1319,7 +1319,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } - Rvalue::ThreadLocalRef(_) => {} + Rvalue::ThreadLocalRef(..) => {} Rvalue::Use(ref operand) | Rvalue::Repeat(ref operand, _) diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index 3ace14610e2a7..196d58c7108cd 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -2369,7 +2369,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn rvalue_user_ty(&self, rvalue: &Rvalue<'tcx>) -> Option { match rvalue { Rvalue::Use(_) - | Rvalue::ThreadLocalRef(_) + | Rvalue::ThreadLocalRef(..) | Rvalue::Repeat(..) | Rvalue::Ref(..) | Rvalue::AddressOf(..) diff --git a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs index 5c3e353840180..8c91aac6c64e8 100644 --- a/compiler/rustc_mir/src/dataflow/move_paths/builder.rs +++ b/compiler/rustc_mir/src/dataflow/move_paths/builder.rs @@ -324,7 +324,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) { match *rvalue { - Rvalue::ThreadLocalRef(_) => {} // not-a-move + Rvalue::ThreadLocalRef(..) => {} // not-a-move Rvalue::Use(ref operand) | Rvalue::Repeat(ref operand, _) | Rvalue::Cast(_, ref operand, _) diff --git a/compiler/rustc_mir/src/interpret/step.rs b/compiler/rustc_mir/src/interpret/step.rs index 156da84f2910a..8b1d9497983a8 100644 --- a/compiler/rustc_mir/src/interpret/step.rs +++ b/compiler/rustc_mir/src/interpret/step.rs @@ -155,7 +155,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { use rustc_middle::mir::Rvalue::*; match *rvalue { - ThreadLocalRef(did) => { + ThreadLocalRef(did, _) => { let id = M::thread_local_static_alloc_id(self, did)?; let val = self.global_base_pointer(id.into())?; self.write_scalar(val, dest)?; diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs index 4ef871b05f47f..3bbe4e15f5cdc 100644 --- a/compiler/rustc_mir/src/monomorphize/collector.rs +++ b/compiler/rustc_mir/src/monomorphize/collector.rs @@ -610,7 +610,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.output.push(create_fn_mono_item(self.tcx, instance, span)); } } - mir::Rvalue::ThreadLocalRef(def_id) => { + mir::Rvalue::ThreadLocalRef(def_id, _) => { assert!(self.tcx.is_thread_local_static(def_id)); let instance = Instance::mono(self.tcx, def_id); if should_codegen_locally(self.tcx, &instance) { diff --git a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs index 3f4b3ca2eedb4..c3853ddd452d1 100644 --- a/compiler/rustc_mir/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_mir/src/transform/check_consts/qualifs.rs @@ -149,7 +149,7 @@ where F: FnMut(Local) -> bool, { match rvalue { - Rvalue::ThreadLocalRef(_) | Rvalue::NullaryOp(..) => { + Rvalue::ThreadLocalRef(..) | Rvalue::NullaryOp(..) => { Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index e8411b121e394..85a647ae40f2d 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -305,7 +305,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { self.super_rvalue(rvalue, location); match *rvalue { - Rvalue::ThreadLocalRef(_) => self.check_op(ops::ThreadLocalAccess), + Rvalue::ThreadLocalRef(..) => self.check_op(ops::ThreadLocalAccess), Rvalue::Use(_) | Rvalue::Repeat(..) diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index aa88719c26a49..3b34cb0b9bec5 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -684,8 +684,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { return None; } - Rvalue::ThreadLocalRef(def_id) => { - trace!("skipping ThreadLocalRef({:?})", def_id); + Rvalue::ThreadLocalRef(def_id, ty) => { + trace!("skipping ThreadLocalRef({:?}, {})", def_id, ty); return None; } diff --git a/compiler/rustc_mir/src/transform/promote_consts.rs b/compiler/rustc_mir/src/transform/promote_consts.rs index 37202276161c7..6d621bdda0c59 100644 --- a/compiler/rustc_mir/src/transform/promote_consts.rs +++ b/compiler/rustc_mir/src/transform/promote_consts.rs @@ -645,7 +645,7 @@ impl<'tcx> Validator<'_, 'tcx> { } match rvalue { - Rvalue::ThreadLocalRef(_) => Err(Unpromotable), + Rvalue::ThreadLocalRef(..) => Err(Unpromotable), Rvalue::NullaryOp(..) => Ok(()), diff --git a/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs index 5e102f5151d0c..b817eb9e826a8 100644 --- a/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs +++ b/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs @@ -158,7 +158,7 @@ fn check_rvalue( span: Span, ) -> McfResult { match rvalue { - Rvalue::ThreadLocalRef(_) => { + Rvalue::ThreadLocalRef(..) => { Err((span, "cannot access thread local storage in const fn".into())) } Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 39dbb6dd3ff92..cb6bd4be86e4a 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -258,7 +258,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::InlineAsm { .. } | ExprKind::LlvmInlineAsm { .. } | ExprKind::Yield { .. } - | ExprKind::ThreadLocalRef(_) + | ExprKind::ThreadLocalRef(..) | ExprKind::Call { .. } => { // these are not places, so we need to make a temporary. debug_assert!(match Category::of(&expr.kind) { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 9c5fddc6b77c0..16179f6cdba65 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -53,7 +53,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = this.source_info(expr_span); match expr.kind { - ExprKind::ThreadLocalRef(did) => block.and(Rvalue::ThreadLocalRef(did)), + ExprKind::ThreadLocalRef(did, ty) => block.and(Rvalue::ThreadLocalRef(did, ty)), ExprKind::Scope { region_scope, lint_level, value } => { let region_scope = (region_scope, source_info); this.in_scope(region_scope, lint_level, |this| this.as_rvalue(block, scope, value)) diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index 9984b527ffdb4..ee2d7c91334a6 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs @@ -70,7 +70,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { local_decl.local_info = Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }); } - ExprKind::ThreadLocalRef(def_id) => { + ExprKind::ThreadLocalRef(def_id, _) => { assert!(this.hir.tcx().is_thread_local_static(def_id)); local_decl.internal = true; local_decl.local_info = diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index 9cabd186d8460..b4db22322366c 100644 --- a/compiler/rustc_mir_build/src/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs @@ -65,7 +65,7 @@ impl Category { | ExprKind::Repeat { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } - | ExprKind::ThreadLocalRef(_) + | ExprKind::ThreadLocalRef(..) | ExprKind::LlvmInlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => Some(Category::Constant), diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 319fae5009e09..a8f0be0593873 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -457,7 +457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::Tuple { .. } | ExprKind::Closure { .. } | ExprKind::Literal { .. } - | ExprKind::ThreadLocalRef(_) + | ExprKind::ThreadLocalRef(..) | ExprKind::StaticRef { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { // should be handled above diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 13e69474cfb96..f18bb43bf7731 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -229,12 +229,8 @@ fn make_mirror_unadjusted<'a, 'tcx>( } } - hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, ref arg) => { - ExprKind::Borrow { borrow_kind: mutbl.to_borrow_kind(), arg: arg.to_ref() } - } - - hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, ref arg) => { - ExprKind::AddressOf { mutability, arg: arg.to_ref() } + hir::ExprKind::AddrOf(kind, mutability, arg) => { + convert_addr_of_expr(cx, kind, mutability, arg) } hir::ExprKind::Block(ref blk, _) => ExprKind::Block { body: &blk }, @@ -863,15 +859,7 @@ fn convert_path_expr<'a, 'tcx>( Res::Def(DefKind::Static, id) => { let ty = cx.tcx.static_ptr_ty(id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); - let kind = if cx.tcx.is_thread_local_static(id) { - ExprKind::ThreadLocalRef(id) - } else { - let ptr = cx.tcx.create_static_alloc(id); - ExprKind::StaticRef { - literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty), - def_id: id, - } - }; + let kind = convert_static_ref(cx, id, ty); ExprKind::Deref { arg: Expr { ty, temp_lifetime, span: expr.span, kind }.to_ref() } } @@ -881,6 +869,47 @@ fn convert_path_expr<'a, 'tcx>( } } +fn convert_static_ref<'tcx>(cx: &mut Cx<'_, 'tcx>, id: DefId, ty: Ty<'tcx>) -> ExprKind<'tcx> { + if cx.tcx.is_thread_local_static(id) { + ExprKind::ThreadLocalRef(id, ty) + } else { + let ptr = cx.tcx.create_static_alloc(id); + ExprKind::StaticRef { + literal: ty::Const::from_scalar(cx.tcx, Scalar::Ptr(ptr.into()), ty), + def_id: id, + } + } +} + +fn convert_addr_of_expr<'tcx>( + cx: &mut Cx<'_, 'tcx>, + kind: hir::BorrowKind, + mutability: hir::Mutability, + arg: &'tcx hir::Expr<'tcx>, +) -> ExprKind<'tcx> { + // Fast path so that taking a reference to a static doesn't end up + // as `&*&STATIC` but just `&STATIC` + if let hir::ExprKind::Path(qpath) = &arg.kind { + let res = cx.typeck_results().qpath_res(qpath, arg.hir_id); + if let Res::Def(DefKind::Static, id) = res { + let mut tm = cx.tcx.static_ptr_ty(id).builtin_deref(true).unwrap(); + tm.mutbl = mutability; + let ty = match kind { + hir::BorrowKind::Ref => cx.tcx.mk_ref(cx.tcx.lifetimes.re_erased, tm), + hir::BorrowKind::Raw => cx.tcx.mk_ptr(tm), + }; + return convert_static_ref(cx, id, ty); + } + } + match kind { + hir::BorrowKind::Ref => { + ExprKind::Borrow { borrow_kind: mutability.to_borrow_kind(), arg: arg.to_ref() } + } + + hir::BorrowKind::Raw => ExprKind::AddressOf { mutability, arg: arg.to_ref() }, + } +} + fn convert_var<'tcx>( cx: &mut Cx<'_, 'tcx>, expr: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs index 4d57fd5c64f8d..61400ae01849e 100644 --- a/compiler/rustc_mir_build/src/thir/mod.rs +++ b/compiler/rustc_mir_build/src/thir/mod.rs @@ -293,7 +293,7 @@ crate enum ExprKind<'tcx> { line_spans: &'tcx [Span], }, /// An expression taking a reference to a thread local. - ThreadLocalRef(DefId), + ThreadLocalRef(DefId, Ty<'tcx>), LlvmInlineAsm { asm: &'tcx hir::LlvmInlineAsmInner, outputs: Vec>, diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir index 509947071b0c1..b28a720c605ab 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir +++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].ConstProp.after.mir @@ -3,19 +3,15 @@ promoted[0] in BAR: &[&i32; 1] = { let mut _0: &[&i32; 1]; // return place in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 let mut _1: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - let mut _2: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34 - let mut _3: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 bb0: { - _3 = const {alloc0: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 + _1 = [const {alloc0: &i32}]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 // ty::Const // + ty: &i32 // + val: Value(Scalar(alloc0)) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 + // + span: $DIR/const-promotion-extern-static.rs:9:32: 9:34 // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) } - _2 = _3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34 - _1 = [move _2]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _0 = &_1; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 return; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 } diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff index 6acb8e46e75c1..0f1461b86c295 100644 --- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff +++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff @@ -6,32 +6,26 @@ let mut _1: &[&i32]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 let mut _2: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 let _3: [&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - let mut _4: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34 - let _5: &i32; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 -+ let mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 ++ let mut _4: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 bb0: { StorageLive(_1); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 StorageLive(_2); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - StorageLive(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 -- StorageLive(_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34 -- StorageLive(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 -- _5 = const {alloc0: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34 -+ _6 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 +- _3 = [const {alloc0: &i32}]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 ++ _4 = const BAR::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 // ty::Const - // + ty: &i32 - // + val: Value(Scalar(alloc0)) + // + ty: &[&i32; 1] + // + val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), const_param_did: None }, [], Some(promoted[0])) // mir::Constant -- // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34 +- // + span: $DIR/const-promotion-extern-static.rs:9:32: 9:34 - // + literal: Const { ty: &i32, val: Value(Scalar(alloc0)) } -- _4 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:32: 9:34 -- _3 = [move _4]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 - _2 = &_3; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 + // + span: $DIR/const-promotion-extern-static.rs:9:31: 9:35 + // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:6 ~ const_promotion_extern_static[317d]::BAR[0]), const_param_did: None }, [], Some(promoted[0])) } -+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 ++ _2 = &(*_4); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:35 _0 = core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44 // mir::Constant @@ -44,7 +38,6 @@ } bb2: { -- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:9:43: 9:44 - StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:9:43: 9:44 return; // scope 0 at $DIR/const-promotion-extern-static.rs:9:1: 9:45 } 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 d9c6b4f0029a3..a00928aafda9c 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,19 +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 scope 1 { } bb0: { - _3 = const {alloc2: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43 + _2 = const {alloc2: &i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 // ty::Const // + ty: &i32 // + val: Value(Scalar(alloc2)) // mir::Constant - // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 + // + span: $DIR/const-promotion-extern-static.rs:13:41: 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 _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 2f7a2d7288447..0b72157115622 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,8 +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 mut _6: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 ++ let mut _5: &[&i32; 1]; // in scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 scope 1 { } @@ -17,23 +16,21 @@ StorageLive(_2); // 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(_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 -+ _6 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 +- _4 = const {alloc2: &i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:41: 13:43 ++ _5 = const FOO::promoted[0]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 // ty::Const - // + ty: &i32 - // + val: Value(Scalar(alloc2)) + // + ty: &[&i32; 1] + // + val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), const_param_did: None }, [], Some(promoted[0])) // mir::Constant -- // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43 +- // + span: $DIR/const-promotion-extern-static.rs:13:41: 13:43 - // + literal: Const { ty: &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 + // + span: $DIR/const-promotion-extern-static.rs:13:31: 13:46 + // + literal: Const { ty: &[&i32; 1], val: Unevaluated(WithOptConstParam { did: DefId(0:7 ~ const_promotion_extern_static[317d]::FOO[0]), const_param_did: None }, [], Some(promoted[0])) } -+ _2 = &(*_6); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 ++ _2 = &(*_5); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _1 = move _2 as &[&i32] (Pointer(Unsize)); // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:46 _0 = core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55 // mir::Constant @@ -46,7 +43,6 @@ } bb2: { -- StorageDead(_5); // scope 0 at $DIR/const-promotion-extern-static.rs:13:54: 13:55 - StorageDead(_3); // scope 0 at $DIR/const-promotion-extern-static.rs:13:54: 13:55 return; // scope 0 at $DIR/const-promotion-extern-static.rs:13:1: 13:56 } diff --git a/src/test/mir-opt/extern-static-ref.rs b/src/test/mir-opt/extern-static-ref.rs new file mode 100644 index 0000000000000..4c7bbad821b9a --- /dev/null +++ b/src/test/mir-opt/extern-static-ref.rs @@ -0,0 +1,21 @@ +#![feature(never_type)] +#![feature(raw_ref_macros)] +#![feature(raw_ref_op)] + +extern "C" { + static FOO: !; +} + +mod foo { + #[no_mangle] + static FOO: u32 = 5; +} + +#[inline(never)] +fn bar(_: T) {} + +// EMIT_MIR extern_static_ref.main.PreCodegen.after.mir +fn main() { + bar(unsafe { core::ptr::raw_const!(FOO) }); + bar(unsafe { &raw const FOO }); +} diff --git a/src/test/mir-opt/extern_static_ref.main.PreCodegen.after.mir b/src/test/mir-opt/extern_static_ref.main.PreCodegen.after.mir new file mode 100644 index 0000000000000..3305e9661b915 --- /dev/null +++ b/src/test/mir-opt/extern_static_ref.main.PreCodegen.after.mir @@ -0,0 +1,47 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/extern-static-ref.rs:18:11: 18:11 + let _1: (); // in scope 0 at $DIR/extern-static-ref.rs:19:5: 19:47 + let _2: (); // in scope 0 at $DIR/extern-static-ref.rs:20:5: 20:35 + scope 1 { + } + scope 2 { + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/extern-static-ref.rs:19:5: 19:47 + _1 = bar::<*const !>(const {alloc0: *const !}) -> bb1; // scope 0 at $DIR/extern-static-ref.rs:19:5: 19:47 + // mir::Constant + // + span: $DIR/extern-static-ref.rs:19:5: 19:8 + // + literal: Const { ty: fn(*const !) {bar::<*const !>}, val: Value(Scalar()) } + // ty::Const + // + ty: *const ! + // + val: Value(Scalar(alloc0)) + // mir::Constant + // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL + // + literal: Const { ty: *const !, val: Value(Scalar(alloc0)) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/extern-static-ref.rs:19:47: 19:48 + StorageLive(_2); // scope 0 at $DIR/extern-static-ref.rs:20:5: 20:35 + _2 = bar::<*const !>(const {alloc0: *const !}) -> bb2; // scope 0 at $DIR/extern-static-ref.rs:20:5: 20:35 + // mir::Constant + // + span: $DIR/extern-static-ref.rs:20:5: 20:8 + // + literal: Const { ty: fn(*const !) {bar::<*const !>}, val: Value(Scalar()) } + // ty::Const + // + ty: *const ! + // + val: Value(Scalar(alloc0)) + // mir::Constant + // + span: $DIR/extern-static-ref.rs:20:18: 20:32 + // + literal: Const { ty: *const !, val: Value(Scalar(alloc0)) } + } + + bb2: { + StorageDead(_2); // scope 0 at $DIR/extern-static-ref.rs:20:35: 20:36 + unreachable; // scope 0 at $DIR/extern-static-ref.rs:18:11: 21:2 + } +} + +alloc0 (extern static: FOO) diff --git a/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir b/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir index 06161373be284..8a1acc8c8df38 100644 --- a/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir +++ b/src/test/mir-opt/tls_access.main.SimplifyCfg-final.after.mir @@ -2,8 +2,7 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/tls-access.rs:6:11: 6:11 - let _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:8:18: 8:21 - let mut _3: *mut u8; // in scope 0 at $DIR/tls-access.rs:9:9: 9:12 + let mut _2: *mut u8; // in scope 0 at $DIR/tls-access.rs:9:9: 9:12 scope 1 { let _1: &u8; // in scope 1 at $DIR/tls-access.rs:8:13: 8:14 scope 2 { @@ -13,15 +12,12 @@ fn main() -> () { bb0: { StorageLive(_1); // scope 1 at $DIR/tls-access.rs:8:13: 8:14 - StorageLive(_2); // scope 1 at $DIR/tls-access.rs:8:18: 8:21 - _2 = &/*tls*/ mut FOO; // scope 1 at $DIR/tls-access.rs:8:18: 8:21 - _1 = &(*_2); // scope 1 at $DIR/tls-access.rs:8:17: 8:21 - StorageLive(_3); // scope 2 at $DIR/tls-access.rs:9:9: 9:12 - _3 = &/*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:9:9: 9:12 - (*_3) = const 42_u8; // scope 2 at $DIR/tls-access.rs:9:9: 9:17 - StorageDead(_3); // scope 2 at $DIR/tls-access.rs:9:17: 9:18 + _1 = &/*tls*/ FOO; // scope 1 at $DIR/tls-access.rs:8:17: 8:21 + StorageLive(_2); // scope 2 at $DIR/tls-access.rs:9:9: 9:12 + _2 = &raw /*tls*/ mut FOO; // scope 2 at $DIR/tls-access.rs:9:9: 9:12 + (*_2) = const 42_u8; // scope 2 at $DIR/tls-access.rs:9:9: 9:17 + StorageDead(_2); // scope 2 at $DIR/tls-access.rs:9:17: 9:18 _0 = const (); // scope 1 at $DIR/tls-access.rs:7:5: 10:6 - StorageDead(_2); // scope 1 at $DIR/tls-access.rs:10:5: 10:6 StorageDead(_1); // scope 1 at $DIR/tls-access.rs:10:5: 10:6 return; // scope 0 at $DIR/tls-access.rs:11:2: 11:2 }