From 08298acb0f10a33b0091028aa7d6615ae63c055b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 21 Sep 2020 18:47:29 +0200 Subject: [PATCH 1/2] Stop generating an intermediate deref when taking references to statics --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 3 +- compiler/rustc_middle/src/mir/tcx.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 13 +-- .../src/transform/check_consts/validation.rs | 28 +++--- .../rustc_mir/src/transform/check_unsafety.rs | 46 +++++----- compiler/rustc_mir_build/src/thir/cx/expr.rs | 85 +++++++++++++++---- ...static.BAR-promoted[0].ConstProp.after.mir | 8 +- ...motion_extern_static.BAR.PromoteTemps.diff | 17 ++-- ...static.FOO-promoted[0].ConstProp.after.mir | 6 +- ...motion_extern_static.FOO.PromoteTemps.diff | 14 ++- ...table_variable_no_prop.main.ConstProp.diff | 8 +- ...ls_access.main.SimplifyCfg-final.after.mir | 4 +- .../assign-to-static-within-other-static.rs | 2 +- .../ui/consts/const-fn-not-safe-for-const.rs | 1 + .../consts/const-fn-not-safe-for-const.stderr | 14 ++- .../ui/consts/const-points-to-static.stderr | 4 +- .../const-prop-read-static-in-const.stderr | 5 ++ .../consts/min_const_fn/min_const_fn.stderr | 4 +- .../const_refers_to_static.stderr | 4 +- .../const_refers_to_static2.stderr | 8 +- .../const_refers_to_static_cross_crate.stderr | 19 +++-- ...ic_mut_containing_mut_ref2.mut_refs.stderr | 8 +- .../consts/static_mut_containing_mut_ref2.rs | 3 +- ...tatic_mut_containing_mut_ref2.stock.stderr | 17 +--- src/test/ui/error-codes/E0017.rs | 7 +- src/test/ui/error-codes/E0017.stderr | 30 ++----- src/test/ui/error-codes/E0388.rs | 5 +- src/test/ui/error-codes/E0388.stderr | 24 ++---- .../ui/issues/issue-17718-const-bad-values.rs | 2 - .../issue-17718-const-bad-values.stderr | 20 +---- src/test/ui/issues/issue-17718-references.rs | 2 + .../ui/issues/issue-17718-references.stderr | 24 +++++- src/test/ui/issues/issue-18118-2.stderr | 4 +- src/test/ui/issues/issue-52060.rs | 1 + src/test/ui/issues/issue-52060.stderr | 10 ++- ...ead-local-static-mut-borrow-outlives-fn.rs | 6 +- ...local-static-mut-borrow-outlives-fn.stderr | 12 +++ .../static-mut-foreign-requires-unsafe.stderr | 4 +- .../static/static-mut-requires-unsafe.stderr | 4 +- .../rfc-2585-unsafe_op_in_unsafe_fn.stderr | 4 +- 40 files changed, 253 insertions(+), 229 deletions(-) create mode 100644 src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 7ce110dcbfc48..79f27098096c8 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -540,7 +540,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::ThreadLocalRef(def_id) => { 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(bx.cx().tcx().mk_imm_ptr(bx.cx().tcx().static_ty(def_id))); let operand = OperandRef::from_immediate_or_packed_pair(&mut bx, static_, layout); (bx, operand) } diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index b9e4f6fb12eb1..e2a211f153576 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -153,7 +153,7 @@ impl<'tcx> Rvalue<'tcx> { } Rvalue::ThreadLocalRef(did) => { if tcx.is_mutable_static(did) { - tcx.mk_mut_ptr(tcx.type_of(did)) + tcx.mk_mut_ref(tcx.lifetimes.re_static, tcx.type_of(did)) } else { tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.type_of(did)) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4127b6535bca6..0bdf9a539b5cc 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -538,16 +538,11 @@ impl<'tcx> TyCtxt<'tcx> { self.static_mutability(def_id) == Some(hir::Mutability::Mut) } - /// Get the type of the pointer to the static that we use in MIR. - pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { + /// Get the type of the static with all constant's in the static's type fully + /// evaluated. + pub fn static_ty(self, def_id: DefId) -> Ty<'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)); - - if self.is_mutable_static(def_id) { - self.mk_mut_ptr(static_ty) - } else { - self.mk_imm_ref(self.lifetimes.re_erased, static_ty) - } + self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)) } /// Expands the given impl trait type, stopping if the type is recursive. diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index e8411b121e394..52064d4dc48b9 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -425,18 +425,20 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { match elem { ProjectionElem::Deref => { - let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty; - if let ty::RawPtr(_) = base_ty.kind() { - if proj_base.is_empty() { - if let (local, []) = (place_local, proj_base) { - let decl = &self.body.local_decls[local]; - if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { - let span = decl.source_info.span; - self.check_static(def_id, span); - return; - } + if proj_base.is_empty() { + if let (local, []) = (place_local, proj_base) { + let decl = &self.body.local_decls[local]; + if let Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }) = + decl.local_info + { + let span = decl.source_info.span; + self.check_static(def_id, span); + return; } } + } + let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty; + if let ty::RawPtr(_) = base_ty.kind() { self.check_op(ops::RawPtrDeref); } @@ -636,12 +638,6 @@ fn place_as_reborrow( return None; } - // A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const` - // that points to the allocation for the static. Don't treat these as reborrows. - if body.local_decls[place.local].is_ref_to_static() { - return None; - } - // Ensure the type being derefed is a reference and not a raw pointer. // // This is sufficient to prevent an access to a `static mut` from being marked as a diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index 7309a4129e468..a27c23dce8982 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -165,11 +165,19 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { _ => {} } } + Rvalue::ThreadLocalRef(did) => self.check_static(*did), _ => {} } self.super_rvalue(rvalue, location); } + fn visit_constant(&mut self, constant: &Constant<'tcx>, _location: Location) { + // Accesses to statics are encoded as constants with `&STATIC` or `&mut STATIC` value. + if let Some(did) = constant.check_static_ptr(self.tcx) { + self.check_static(did); + } + } + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { // On types with `scalar_valid_range`, prevent // * `&mut x.field` @@ -204,26 +212,10 @@ 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 let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { - if self.tcx.is_mutable_static(def_id) { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfMutableStatic, - ); - return; - } else if self.tcx.is_foreign_item(def_id) { - self.require_unsafe( - UnsafetyViolationKind::General, - UnsafetyViolationDetails::UseOfExternStatic, - ); - return; - } - } else { - // Internal locals are used in the `move_val_init` desugaring. - // We want to check unsafety against the source info of the - // desugaring, rather than the source info of the RHS. - self.source_info = self.body.local_decls[place.local].source_info; - } + // Internal locals are used in the `move_val_init` desugaring. + // We want to check unsafety against the source info of the + // desugaring, rather than the source info of the RHS. + self.source_info = self.body.local_decls[place.local].source_info; } } let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty; @@ -273,6 +265,20 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { } impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { + fn check_static(&mut self, did: DefId) { + if self.tcx.is_mutable_static(did) { + self.require_unsafe( + UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfMutableStatic, + ) + } else if self.tcx.is_foreign_item(did) { + self.require_unsafe( + UnsafetyViolationKind::General, + UnsafetyViolationDetails::UseOfExternStatic, + ) + } + } + fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) { let source_info = self.source_info; let lint_root = self.body.source_scopes[self.source_info.scope] diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 13e69474cfb96..50da9d76fdbf5 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 }, @@ -859,20 +855,23 @@ fn convert_path_expr<'a, 'tcx>( } // We encode uses of statics as a `*&STATIC` where the `&STATIC` part is - // a constant reference (or constant raw pointer for `static mut`) in MIR + // a constant reference in MIR 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) + let static_ty = cx.tcx.static_ty(id); + let ty = if cx.tcx.is_mutable_static(id) { + cx.tcx.mk_mut_ref(cx.tcx.lifetimes.re_erased, static_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, - } + cx.tcx.mk_imm_ref(cx.tcx.lifetimes.re_erased, static_ty) }; - ExprKind::Deref { arg: Expr { ty, temp_lifetime, span: expr.span, kind }.to_ref() } + ExprKind::Deref { + arg: Expr { + ty, + temp_lifetime: cx.region_scope_tree.temporary_scope(expr.hir_id.local_id), + span: expr.span, + kind: convert_static_ref(cx, id, ty), + } + .to_ref(), + } } Res::Local(var_hir_id) => convert_var(cx, expr, var_hir_id), @@ -881,6 +880,58 @@ 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) + } 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 { + // FIXME(oli-obk): can we give TLS the same treatment? I was not able to figure out + // how to coax mir borrowck to be able to handle TLS directly from the `Rvalue` instead + // of going through the local. + if !cx.tcx.is_thread_local_static(id) { + let ty = cx.tcx.static_ty(id); + // Taking a mutable reference to an immutable static should not yield a mutable + // reference. So we do not do this optimization for things that will error anyway. + if mutability == hir::Mutability::Not || cx.tcx.is_mutable_static(id) { + let tm = ty::TypeAndMut { ty, 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); + } else { + cx.tcx.sess.delay_span_bug(arg.span, "mutable reference to immutable static"); + } + } + } + } + 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/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/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff index f6e173620ecb2..13df1254278b7 100644 --- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff @@ -6,7 +6,7 @@ let mut _1: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:7:9: 7:14 let _2: (); // in scope 0 at $DIR/mutable_variable_no_prop.rs:8:5: 10:6 let mut _3: u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 - let mut _4: *mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 + let mut _4: &mut u32; // in scope 0 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 scope 1 { debug x => _1; // in scope 1 at $DIR/mutable_variable_no_prop.rs:7:9: 7:14 let _5: u32; // in scope 1 at $DIR/mutable_variable_no_prop.rs:11:9: 11:10 @@ -23,13 +23,13 @@ StorageLive(_2); // scope 1 at $DIR/mutable_variable_no_prop.rs:8:5: 10:6 StorageLive(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 StorageLive(_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 - _4 = const {alloc0: *mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 + _4 = const {alloc0: &mut u32}; // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 // ty::Const - // + ty: *mut u32 + // + ty: &mut u32 // + val: Value(Scalar(alloc0)) // mir::Constant // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19 - // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc0)) } + // + literal: Const { ty: &mut u32, val: Value(Scalar(alloc0)) } _3 = (*_4); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19 _1 = move _3; // scope 2 at $DIR/mutable_variable_no_prop.rs:9:9: 9:19 StorageDead(_3); // scope 2 at $DIR/mutable_variable_no_prop.rs:9:18: 9:19 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..ba333d8c39ee5 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,8 @@ 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 _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 scope 1 { let _1: &u8; // in scope 1 at $DIR/tls-access.rs:8:13: 8:14 scope 2 { diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs index 648caae30b427..db472609bf191 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs @@ -8,7 +8,7 @@ use std::cell::UnsafeCell; static mut FOO: u32 = 42; static BOO: () = unsafe { FOO = 5; - //~^ could not evaluate static initializer [E0080] + //~^ ERROR could not evaluate static initializer }; fn main() {} diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.rs b/src/test/ui/consts/const-fn-not-safe-for-const.rs index 085ff5c58e60c..3d2c8f30a77c3 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.rs +++ b/src/test/ui/consts/const-fn-not-safe-for-const.rs @@ -19,6 +19,7 @@ static Y: u32 = 0; const fn get_Y() -> u32 { Y //~^ ERROR E0013 + //~| ERROR E0013 } const fn get_Y_addr() -> &'static u32 { diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr index df793d7dd7ec9..ad2ceee2ca211 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr +++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr @@ -13,14 +13,22 @@ LL | Y = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0013]: constant functions cannot refer to statics - --> $DIR/const-fn-not-safe-for-const.rs:25:6 + --> $DIR/const-fn-not-safe-for-const.rs:20:5 + | +LL | Y + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constant functions cannot refer to statics + --> $DIR/const-fn-not-safe-for-const.rs:26:5 | LL | &Y - | ^ + | ^^ | = help: consider extracting the value of the `static` to a `const`, and referring to that -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0013, E0015. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/const-points-to-static.stderr b/src/test/ui/consts/const-points-to-static.stderr index 465537fb3d5ea..ee0660be3215d 100644 --- a/src/test/ui/consts/const-points-to-static.stderr +++ b/src/test/ui/consts/const-points-to-static.stderr @@ -9,10 +9,10 @@ LL | const TEST: &u8 = &MY_STATIC; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const-points-to-static.rs:5:20 + --> $DIR/const-points-to-static.rs:5:19 | LL | const TEST: &u8 = &MY_STATIC; - | ^^^^^^^^^ + | ^^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/consts/const-prop-read-static-in-const.stderr b/src/test/ui/consts/const-prop-read-static-in-const.stderr index 7a517d1d7b363..f6c1181b7665c 100644 --- a/src/test/ui/consts/const-prop-read-static-in-const.stderr +++ b/src/test/ui/consts/const-prop-read-static-in-const.stderr @@ -15,6 +15,11 @@ help: skipping check that does not even have a feature gate | LL | const TEST: u8 = MY_STATIC; | ^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const-prop-read-static-in-const.rs:5:18 + | +LL | const TEST: u8 = MY_STATIC; + | ^^^^^^^^^ error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 9b55b6c6f3bbc..42f3db7af1fc3 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -122,10 +122,10 @@ LL | const fn foo25() -> u32 { BAR } = help: add `#![feature(const_fn)]` to the crate attributes to enable error[E0723]: cannot access `static` items in const fn - --> $DIR/min_const_fn.rs:91:37 + --> $DIR/min_const_fn.rs:91:36 | LL | const fn foo26() -> &'static u32 { &BAR } - | ^^^ + | ^^^^ | = note: see issue #57563 for more information = help: add `#![feature(const_fn)]` to the crate attributes to enable diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index e5cd86b3d6c2f..a72b9baac8769 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -29,10 +29,10 @@ help: skipping check that does not even have a feature gate LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static.rs:18:17 + --> $DIR/const_refers_to_static.rs:18:16 | LL | unsafe { *(&FOO as *const _ as *const usize) } - | ^^^ + | ^^^^ help: skipping check for `const_raw_ptr_deref` feature --> $DIR/const_refers_to_static.rs:18:14 | diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr index 2e40b38dac768..94abbf74e524c 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static2.stderr @@ -27,20 +27,20 @@ LL | | }; warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:14:18 + --> $DIR/const_refers_to_static2.rs:14:17 | LL | unsafe { &*(&FOO as *const _ as *const usize) } - | ^^^ + | ^^^^ help: skipping check for `const_raw_ptr_deref` feature --> $DIR/const_refers_to_static2.rs:14:14 | LL | unsafe { &*(&FOO as *const _ as *const usize) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static2.rs:22:6 + --> $DIR/const_refers_to_static2.rs:22:5 | LL | &FOO - | ^^^ + | ^^^^ error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index 52662ef9eaf5a..123306695825a 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -107,15 +107,10 @@ LL | U8_MUT3 => true, warning: skipping const checks | help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:14:15 + --> $DIR/const_refers_to_static_cross_crate.rs:14:14 | LL | unsafe { &static_cross_crate::ZERO } - | ^^^^^^^^^^^^^^^^^^^^^^^^ -help: skipping check that does not even have a feature gate - --> $DIR/const_refers_to_static_cross_crate.rs:14:15 - | -LL | unsafe { &static_cross_crate::ZERO } - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate --> $DIR/const_refers_to_static_cross_crate.rs:20:15 | @@ -136,6 +131,16 @@ help: skipping check that does not even have a feature gate | LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:26:17 + | +LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: skipping check that does not even have a feature gate + --> $DIR/const_refers_to_static_cross_crate.rs:26:17 + | +LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: skipping check that does not even have a feature gate --> $DIR/const_refers_to_static_cross_crate.rs:32:20 | diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr index 36c280ca5c607..8db75dd63cf2a 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.mut_refs.stderr @@ -1,9 +1,9 @@ -error[E0764]: mutable references are not allowed in statics - --> $DIR/static_mut_containing_mut_ref2.rs:7:46 +error[E0080]: could not evaluate static initializer + --> $DIR/static_mut_containing_mut_ref2.rs:7:45 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer error: aborting due to previous error -For more information about this error, try `rustc --explain E0764`. +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs index a6bbe8d6ec24c..f18466970cf91 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs @@ -5,7 +5,6 @@ static mut STDERR_BUFFER_SPACE: u8 = 0; pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; -//~^ ERROR mutable references are not allowed in statics -//[stock]~| ERROR static contains unimplemented expression type +//~^ ERROR could not evaluate static initializer fn main() {} diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr index 57fb27e642e6f..8db75dd63cf2a 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stock.stderr @@ -1,18 +1,9 @@ -error[E0764]: mutable references are not allowed in statics - --> $DIR/static_mut_containing_mut_ref2.rs:7:46 - | -LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error[E0019]: static contains unimplemented expression type +error[E0080]: could not evaluate static initializer --> $DIR/static_mut_containing_mut_ref2.rs:7:45 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0019, E0764. -For more information about an error, try `rustc --explain E0019`. +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs index 54d3cc54a84d9..918cb57b2cd22 100644 --- a/src/test/ui/error-codes/E0017.rs +++ b/src/test/ui/error-codes/E0017.rs @@ -4,10 +4,9 @@ static mut M: i32 = 3; const CR: &'static mut i32 = &mut C; //~ ERROR E0764 //~| WARN taking a mutable -static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764 - //~| ERROR E0019 - //~| ERROR cannot borrow +static STATIC_REF: &'static mut i32 = &mut X; +//~^ ERROR cannot borrow immutable static item `X` as mutable [E0596] static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 //~| WARN taking a mutable -static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; //~ ERROR E0764 +static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; fn main() {} diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 40ef6bd97b3b0..6ce658e7231be 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -19,20 +19,6 @@ error[E0764]: mutable references are not allowed in constants LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ `&mut` is only allowed in `const fn` -error[E0019]: static contains unimplemented expression type - --> $DIR/E0017.rs:7:39 - | -LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:7:39 - | -LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ `&mut` is only allowed in `const fn` - error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:7:39 | @@ -40,7 +26,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; | ^^^^^^ cannot borrow as mutable warning: taking a mutable reference to a `const` item - --> $DIR/E0017.rs:10:38 + --> $DIR/E0017.rs:9:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -54,18 +40,12 @@ LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:10:38 + --> $DIR/E0017.rs:9:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ `&mut` is only allowed in `const fn` -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:12:52 - | -LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; - | ^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 6 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0019, E0596, E0764. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0596, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/error-codes/E0388.rs b/src/test/ui/error-codes/E0388.rs index 8ad586bb30f1e..da014456fe8b9 100644 --- a/src/test/ui/error-codes/E0388.rs +++ b/src/test/ui/error-codes/E0388.rs @@ -3,9 +3,8 @@ const C: i32 = 2; const CR: &'static mut i32 = &mut C; //~ ERROR E0764 //~| WARN taking a mutable -static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0019 - //~| ERROR cannot borrow - //~| ERROR E0764 +static STATIC_REF: &'static mut i32 = &mut X; + //~^ ERROR E0596 static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 //~| WARN taking a mutable diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 39bc717ceec3e..538fa5cb61050 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -19,20 +19,6 @@ error[E0764]: mutable references are not allowed in constants LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ `&mut` is only allowed in `const fn` -error[E0019]: static contains unimplemented expression type - --> $DIR/E0388.rs:6:39 - | -LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ - | - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0388.rs:6:39 - | -LL | static STATIC_REF: &'static mut i32 = &mut X; - | ^^^^^^ `&mut` is only allowed in `const fn` - error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0388.rs:6:39 | @@ -40,7 +26,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; | ^^^^^^ cannot borrow as mutable warning: taking a mutable reference to a `const` item - --> $DIR/E0388.rs:9:38 + --> $DIR/E0388.rs:8:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -54,12 +40,12 @@ LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ error[E0764]: mutable references are not allowed in statics - --> $DIR/E0388.rs:9:38 + --> $DIR/E0388.rs:8:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ `&mut` is only allowed in `const fn` -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0019, E0596, E0764. -For more information about an error, try `rustc --explain E0019`. +Some errors have detailed explanations: E0596, E0764. +For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-17718-const-bad-values.rs b/src/test/ui/issues/issue-17718-const-bad-values.rs index 49023f18ddbfb..8e3145d156fab 100644 --- a/src/test/ui/issues/issue-17718-const-bad-values.rs +++ b/src/test/ui/issues/issue-17718-const-bad-values.rs @@ -4,7 +4,5 @@ const C1: &'static mut [usize] = &mut []; static mut S: usize = 3; const C2: &'static mut usize = unsafe { &mut S }; //~^ ERROR: constants cannot refer to statics -//~| ERROR: constants cannot refer to statics -//~| ERROR: mutable references are not allowed in constants fn main() {} diff --git a/src/test/ui/issues/issue-17718-const-bad-values.stderr b/src/test/ui/issues/issue-17718-const-bad-values.stderr index 7c50978d4ebb8..6e7a85482d81e 100644 --- a/src/test/ui/issues/issue-17718-const-bad-values.stderr +++ b/src/test/ui/issues/issue-17718-const-bad-values.stderr @@ -5,28 +5,14 @@ LL | const C1: &'static mut [usize] = &mut []; | ^^^^^^^ `&mut` is only allowed in `const fn` error[E0013]: constants cannot refer to statics - --> $DIR/issue-17718-const-bad-values.rs:5:46 - | -LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^ - | - = help: consider extracting the value of the `static` to a `const`, and referring to that - -error[E0013]: constants cannot refer to statics - --> $DIR/issue-17718-const-bad-values.rs:5:46 + --> $DIR/issue-17718-const-bad-values.rs:5:41 | LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^ + | ^^^^^^ | = help: consider extracting the value of the `static` to a `const`, and referring to that -error[E0764]: mutable references are not allowed in constants - --> $DIR/issue-17718-const-bad-values.rs:5:41 - | -LL | const C2: &'static mut usize = unsafe { &mut S }; - | ^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0013, E0764. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/issues/issue-17718-references.rs b/src/test/ui/issues/issue-17718-references.rs index 03d5f8bb3f1c9..eec2b3e6c02c5 100644 --- a/src/test/ui/issues/issue-17718-references.rs +++ b/src/test/ui/issues/issue-17718-references.rs @@ -12,12 +12,14 @@ static T4: &'static usize = &S; const T5: usize = C; const T6: usize = S; //~ ERROR: constants cannot refer to statics +//~^ ERROR: constants cannot refer to statics static T7: usize = C; static T8: usize = S; const T9: Struct = Struct { a: C }; const T10: Struct = Struct { a: S }; //~^ ERROR: constants cannot refer to statics +//~| ERROR: constants cannot refer to statics static T11: Struct = Struct { a: C }; static T12: Struct = Struct { a: S }; diff --git a/src/test/ui/issues/issue-17718-references.stderr b/src/test/ui/issues/issue-17718-references.stderr index e3c3b369ffb32..1a69c11e807df 100644 --- a/src/test/ui/issues/issue-17718-references.stderr +++ b/src/test/ui/issues/issue-17718-references.stderr @@ -1,8 +1,8 @@ error[E0013]: constants cannot refer to statics - --> $DIR/issue-17718-references.rs:9:29 + --> $DIR/issue-17718-references.rs:9:28 | LL | const T2: &'static usize = &S; - | ^ + | ^^ | = help: consider extracting the value of the `static` to a `const`, and referring to that @@ -15,13 +15,29 @@ LL | const T6: usize = S; = help: consider extracting the value of the `static` to a `const`, and referring to that error[E0013]: constants cannot refer to statics - --> $DIR/issue-17718-references.rs:19:33 + --> $DIR/issue-17718-references.rs:14:19 + | +LL | const T6: usize = S; + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/issue-17718-references.rs:20:33 + | +LL | const T10: Struct = Struct { a: S }; + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + +error[E0013]: constants cannot refer to statics + --> $DIR/issue-17718-references.rs:20:33 | LL | const T10: Struct = Struct { a: S }; | ^ | = help: consider extracting the value of the `static` to a `const`, and referring to that -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0013`. diff --git a/src/test/ui/issues/issue-18118-2.stderr b/src/test/ui/issues/issue-18118-2.stderr index 4fc3ca78f961c..98793b9114065 100644 --- a/src/test/ui/issues/issue-18118-2.stderr +++ b/src/test/ui/issues/issue-18118-2.stderr @@ -1,8 +1,8 @@ error[E0013]: constants cannot refer to statics - --> $DIR/issue-18118-2.rs:4:10 + --> $DIR/issue-18118-2.rs:4:9 | LL | &p - | ^ + | ^^ | = help: consider extracting the value of the `static` to a `const`, and referring to that diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/issues/issue-52060.rs index fed08902c8b9d..7dbefee808964 100644 --- a/src/test/ui/issues/issue-52060.rs +++ b/src/test/ui/issues/issue-52060.rs @@ -4,5 +4,6 @@ static A: &'static [u32] = &[1]; static B: [u32; 1] = [0; A.len()]; //~^ ERROR [E0013] //~| ERROR evaluation of constant value failed +//~| ERROR constants cannot refer to statics fn main() {} diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr index 502825e9766e3..184f292748f55 100644 --- a/src/test/ui/issues/issue-52060.stderr +++ b/src/test/ui/issues/issue-52060.stderr @@ -6,13 +6,21 @@ LL | static B: [u32; 1] = [0; A.len()]; | = help: consider extracting the value of the `static` to a `const`, and referring to that +error[E0013]: constants cannot refer to statics + --> $DIR/issue-52060.rs:4:26 + | +LL | static B: [u32; 1] = [0; A.len()]; + | ^ + | + = help: consider extracting the value of the `static` to a `const`, and referring to that + error[E0080]: evaluation of constant value failed --> $DIR/issue-52060.rs:4:26 | LL | static B: [u32; 1] = [0; A.len()]; | ^ constant accesses static -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0013, E0080. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs index 7d3b00dfc7163..c1c47e111c582 100644 --- a/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs +++ b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs @@ -1,8 +1,3 @@ -// -// run-pass -// -// FIXME(#54366) - We probably shouldn't allow #[thread_local] static mut to get a 'static lifetime. - #![feature(thread_local)] #[thread_local] @@ -16,6 +11,7 @@ impl S1 { fn new(_x: u64) -> S1 { S1 { a: unsafe { &mut X1 }, + //~^ ERROR thread-local variable borrowed past end of function } } } diff --git a/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr new file mode 100644 index 0000000000000..6d2dd81dae07b --- /dev/null +++ b/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr @@ -0,0 +1,12 @@ +error[E0712]: thread-local variable borrowed past end of function + --> $DIR/borrowck-thread-local-static-mut-borrow-outlives-fn.rs:13:25 + | +LL | a: unsafe { &mut X1 }, + | ^^^^^^^ thread-local variables cannot be borrowed beyond the end of the function +... +LL | } + | - end of enclosing function is here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0712`. diff --git a/src/test/ui/static/static-mut-foreign-requires-unsafe.stderr b/src/test/ui/static/static-mut-foreign-requires-unsafe.stderr index e7ed0b710b2f3..022f7e9fb1655 100644 --- a/src/test/ui/static/static-mut-foreign-requires-unsafe.stderr +++ b/src/test/ui/static/static-mut-foreign-requires-unsafe.stderr @@ -2,7 +2,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-foreign-requires-unsafe.rs:6:5 | LL | a += 3; - | ^^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -10,7 +10,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-foreign-requires-unsafe.rs:7:5 | LL | a = 4; - | ^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/src/test/ui/static/static-mut-requires-unsafe.stderr b/src/test/ui/static/static-mut-requires-unsafe.stderr index 85e468b333c28..30be0220cf65a 100644 --- a/src/test/ui/static/static-mut-requires-unsafe.stderr +++ b/src/test/ui/static/static-mut-requires-unsafe.stderr @@ -2,7 +2,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-requires-unsafe.rs:4:5 | LL | a += 3; - | ^^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -10,7 +10,7 @@ error[E0133]: use of mutable static is unsafe and requires unsafe function or bl --> $DIR/static-mut-requires-unsafe.rs:5:5 | LL | a = 4; - | ^^^^^ use of mutable static + | ^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr index cc595df12cc44..0a0f1926f341d 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.stderr @@ -23,7 +23,7 @@ error: use of mutable static is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 | LL | VOID = (); - | ^^^^^^^^^ use of mutable static + | ^^^^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior @@ -53,7 +53,7 @@ error: use of mutable static is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:5 | LL | VOID = (); - | ^^^^^^^^^ use of mutable static + | ^^^^ use of mutable static | = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior From ae30d9324837389243efbcb26f963625e4c2fabd Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 21 Sep 2020 23:42:31 +0200 Subject: [PATCH 2/2] Simplify and document the permitted deref in constants --- .../src/transform/check_consts/validation.rs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 52064d4dc48b9..8afde69d41c3e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -425,16 +425,18 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { match elem { ProjectionElem::Deref => { + // Allow dereferencing if the reference/pointer is a synthetic pointer from the + // mir building for accesses to statics. We check that the projection list is empty, + // because we don't want to allow dereferencing pointers *stored* within a static. if proj_base.is_empty() { - if let (local, []) = (place_local, proj_base) { - let decl = &self.body.local_decls[local]; - if let Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }) = - decl.local_info - { - let span = decl.source_info.span; - self.check_static(def_id, span); - return; - } + let decl = &self.body.local_decls[place_local]; + // Don't check thread locals here, they are checked via `Rvalue::ThreadLocalRef` + if let Some(box LocalInfo::StaticRef { def_id, is_thread_local: false }) = + decl.local_info + { + let span = decl.source_info.span; + self.check_static(def_id, span); + return; } } let base_ty = Place::ty_from(place_local, proj_base, self.body, self.tcx).ty;