diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 8391cc6d9ba99..5753557a102aa 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -521,6 +521,7 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> { InvalidNullPointerUsage | ReadPointerAsBytes | ReadBytesAsPointer | + ReadForeignStatic | InvalidPointerMath | ReadUndefBytes | DeadLocal | diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 86427bb2382cb..7e2c144e0a71d 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -188,6 +188,7 @@ pub enum EvalErrorKind<'tcx, O> { InvalidNullPointerUsage, ReadPointerAsBytes, ReadBytesAsPointer, + ReadForeignStatic, InvalidPointerMath, ReadUndefBytes, DeadLocal, @@ -304,6 +305,8 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> { "a raw memory access tried to access part of a pointer value as raw bytes", ReadBytesAsPointer => "a memory access tried to interpret some bytes as a pointer", + ReadForeignStatic => + "tried to read from foreign (extern) static", InvalidPointerMath => "attempted to do invalid arithmetic on pointers that would leak base addresses, e.g. comparing pointers into different allocations", ReadUndefBytes => diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index a648dc6e7e788..c84999a7e5990 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -506,6 +506,7 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> { InvalidNullPointerUsage => InvalidNullPointerUsage, ReadPointerAsBytes => ReadPointerAsBytes, ReadBytesAsPointer => ReadBytesAsPointer, + ReadForeignStatic => ReadForeignStatic, InvalidPointerMath => InvalidPointerMath, ReadUndefBytes => ReadUndefBytes, DeadLocal => DeadLocal, diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index c2da1bee3954a..3c751d52b0664 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -1145,33 +1145,6 @@ fn main() { ``` "##, -E0394: r##" -A static was referred to by value by another static. - -Erroneous code examples: - -```compile_fail,E0394 -static A: u32 = 0; -static B: u32 = A; // error: cannot refer to other statics by value, use the - // address-of operator or a constant instead -``` - -A static cannot be referred by value. To fix this issue, either use a -constant: - -``` -const A: u32 = 0; // `A` is now a constant -static B: u32 = A; // ok! -``` - -Or refer to `A` by reference: - -``` -static A: u32 = 0; -static B: &'static u32 = &A; // ok! -``` -"##, - E0395: r##" The value assigned to a constant scalar must be known at compile time, which is not the case when comparing raw pointers. @@ -1333,34 +1306,6 @@ Remember this solution is unsafe! You will have to ensure that accesses to the cell are synchronized. "##, -E0494: r##" -A reference of an interior static was assigned to another const/static. -Erroneous code example: - -```compile_fail,E0494 -struct Foo { - a: u32 -} - -static S : Foo = Foo { a : 0 }; -static A : &'static u32 = &S.a; -// error: cannot refer to the interior of another static, use a -// constant instead -``` - -The "base" variable has to be a const if you want another static/const variable -to refer to one of its fields. Example: - -``` -struct Foo { - a: u32 -} - -const S : Foo = Foo { a : 0 }; -static A : &'static u32 = &S.a; // ok! -``` -"##, - E0499: r##" A variable was borrowed as mutable more than once. Erroneous code example: diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 35422b11bd733..749c0d04ae91f 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -374,7 +374,7 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator { Ok(None) } else { Err( - ConstEvalError::NeedsRfc("Pointer arithmetic or comparison".to_string()).into(), + ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(), ) } } @@ -404,7 +404,7 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator { _dest: Place, ) -> EvalResult<'tcx> { Err( - ConstEvalError::NeedsRfc("Heap allocations via `box` keyword".to_string()).into(), + ConstEvalError::NeedsRfc("heap allocations via `box` keyword".to_string()).into(), ) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3cd492c50eeca..f5da65ae44db7 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -279,6 +279,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { /// Allocation accessors impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { fn const_eval_static(&self, def_id: DefId) -> EvalResult<'tcx, &'tcx Allocation> { + if self.tcx.is_foreign_item(def_id) { + return err!(ReadForeignStatic); + } let instance = Instance::mono(self.tcx.tcx, def_id); let gid = GlobalId { instance, @@ -302,7 +305,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { Some(alloc) => Ok(alloc), None => { // static alloc? - match self.tcx.alloc_map.lock().get(id) { + let alloc = self.tcx.alloc_map.lock().get(id); + match alloc { Some(AllocType::Memory(mem)) => Ok(mem), Some(AllocType::Function(..)) => { Err(EvalErrorKind::DerefFunctionPointer.into()) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 144ebce76e14c..986957d5a8267 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -56,19 +56,13 @@ bitflags! { // Function argument. const FN_ARGUMENT = 1 << 2; - // Static place or move from a static. - const STATIC = 1 << 3; - - // Reference to a static. - const STATIC_REF = 1 << 4; - // Not constant at all - non-`const fn` calls, asm!, // pointer comparisons, ptr-to-int casts, etc. - const NOT_CONST = 1 << 5; + const NOT_CONST = 1 << 3; // Refers to temporaries which cannot be promoted as // promote_consts decided they weren't simple enough. - const NOT_PROMOTABLE = 1 << 6; + const NOT_PROMOTABLE = 1 << 4; // Const items can only have MUTABLE_INTERIOR // and NOT_PROMOTABLE without producing an error. @@ -226,42 +220,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { self.add(original); } - /// Check if a Local with the current qualifications is promotable. - fn can_promote(&self, qualif: Qualif) -> bool { - // References to statics are allowed, but only in other statics. - if self.mode == Mode::Static || self.mode == Mode::StaticMut { - (qualif - Qualif::STATIC_REF).is_empty() - } else { - qualif.is_empty() - } - } - - /// Check if a Place with the current qualifications could - /// be consumed, by either an operand or a Deref projection. - fn try_consume(&mut self) -> bool { - if self.qualif.intersects(Qualif::STATIC) && self.mode != Mode::Fn { - let msg = if self.mode == Mode::Static || - self.mode == Mode::StaticMut { - "cannot refer to other statics by value, use the \ - address-of operator or a constant instead" - } else { - "cannot refer to statics by value, use a constant instead" - }; - struct_span_err!(self.tcx.sess, self.span, E0394, "{}", msg) - .span_label(self.span, "referring to another static by value") - .note("use the address-of operator or a constant instead") - .emit(); - - // Replace STATIC with NOT_CONST to avoid further errors. - self.qualif = self.qualif - Qualif::STATIC; - self.add(Qualif::NOT_CONST); - - false - } else { - true - } - } - /// Assign the current qualification to the given destination. fn assign(&mut self, dest: &Place<'tcx>, location: Location) { trace!("assign: {:?}", dest); @@ -305,7 +263,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { }) if self.mir.local_kind(index) == LocalKind::Temp && self.mir.local_decls[index].ty.is_box() && self.local_qualif[index].map_or(false, |qualif| { - qualif.intersects(Qualif::NOT_CONST) + qualif.contains(Qualif::NOT_CONST) }) => { // Part of `box expr`, we should've errored // already for the Box allocation Rvalue. @@ -492,21 +450,26 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { match *place { Place::Local(ref local) => self.visit_local(local, context, location), Place::Static(ref global) => { - self.add(Qualif::STATIC); - - if self.mode != Mode::Fn { - for attr in &self.tcx.get_attrs(global.def_id)[..] { - if attr.check_name("thread_local") { - span_err!(self.tcx.sess, self.span, E0625, - "thread-local statics cannot be \ - accessed at compile-time"); - self.add(Qualif::NOT_CONST); - return; - } + if self.tcx + .get_attrs(global.def_id) + .iter() + .any(|attr| attr.check_name("thread_local")) { + if self.mode != Mode::Fn { + span_err!(self.tcx.sess, self.span, E0625, + "thread-local statics cannot be \ + accessed at compile-time"); } + self.add(Qualif::NOT_CONST); + return; + } + + // Only allow statics (not consts) to refer to other statics. + if self.mode == Mode::Static || self.mode == Mode::StaticMut { + return; } + self.add(Qualif::NOT_CONST); - if self.mode == Mode::Const || self.mode == Mode::ConstFn { + if self.mode != Mode::Fn { let mut err = struct_span_err!(self.tcx.sess, self.span, E0013, "{}s cannot refer to statics, use \ a constant instead", self.mode); @@ -527,15 +490,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.super_place(place, context, location); match proj.elem { ProjectionElem::Deref => { - if !this.try_consume() { - return; - } - - if this.qualif.intersects(Qualif::STATIC_REF) { - this.qualif = this.qualif - Qualif::STATIC_REF; - this.add(Qualif::STATIC); - } - this.add(Qualif::NOT_CONST); let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); @@ -573,11 +527,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.not_const(); } } - } else if this.qualif.intersects(Qualif::STATIC) { - span_err!(this.tcx.sess, this.span, E0494, - "cannot refer to the interior of another \ - static, use a constant instead"); } + let ty = place.ty(this.mir, this.tcx).to_ty(this.tcx); this.qualif.restrict(ty, this.tcx, this.param_env); } @@ -594,14 +545,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { + self.super_operand(operand, location); + match *operand { Operand::Copy(_) | Operand::Move(_) => { - self.nest(|this| { - this.super_operand(operand, location); - this.try_consume(); - }); - // Mark the consumed locals to indicate later drops are noops. if let Operand::Move(Place::Local(local)) = *operand { self.local_qualif[local] = self.local_qualif[local].map(|q| @@ -646,20 +594,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } if is_reborrow { - self.nest(|this| { - this.super_place(place, PlaceContext::Borrow { - region, - kind - }, location); - if !this.try_consume() { - return; - } - - if this.qualif.intersects(Qualif::STATIC_REF) { - this.qualif = this.qualif - Qualif::STATIC_REF; - this.add(Qualif::STATIC); - } - }); + self.super_place(place, PlaceContext::Borrow { + region, + kind + }, location); } else { self.super_rvalue(rvalue, location); } @@ -678,22 +616,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { Rvalue::Cast(CastKind::UnsafeFnPointer, ..) | Rvalue::Cast(CastKind::ClosureFnPointer, ..) | Rvalue::Cast(CastKind::Unsize, ..) | - Rvalue::Discriminant(..) => {} - - Rvalue::Len(_) => { - // Static places in consts would have errored already, - // don't treat length checks as reads from statics. - self.qualif = self.qualif - Qualif::STATIC; - } + Rvalue::Discriminant(..) | + Rvalue::Len(_) => {} Rvalue::Ref(_, kind, ref place) => { - // Static places in consts would have errored already, - // only keep track of references to them here. - if self.qualif.intersects(Qualif::STATIC) { - self.qualif = self.qualif - Qualif::STATIC; - self.add(Qualif::STATIC_REF); - } - let ty = place.ty(self.mir, self.tcx).to_ty(self.tcx); // Default to forbidding the borrow and/or its promotion, @@ -744,7 +670,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // Constants cannot be borrowed if they contain interior mutability as // it means that our "silent insertion of statics" could change // initializer values (very bad). - if self.qualif.intersects(Qualif::MUTABLE_INTERIOR) { + if self.qualif.contains(Qualif::MUTABLE_INTERIOR) { // A reference of a MUTABLE_INTERIOR place is instead // NOT_CONST (see `if forbidden_mut` below), to avoid // duplicate errors (from reborrowing, for example). @@ -781,7 +707,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { // This allows borrowing fields which don't have // `MUTABLE_INTERIOR`, from a type that does, e.g.: // `let _: &'static _ = &(Cell::new(1), 2).1;` - if self.can_promote(qualif - Qualif::MUTABLE_INTERIOR) { + if (qualif - Qualif::MUTABLE_INTERIOR).is_empty() { self.promotion_candidates.push(candidate); } } @@ -889,7 +815,7 @@ This does not pose a problem by itself because they can't be accessed directly." if Some(def.did) == self.tcx.lang_items().unsafe_cell_type() { let ty = rvalue.ty(self.mir, self.tcx); self.add_type(ty); - assert!(self.qualif.intersects(Qualif::MUTABLE_INTERIOR)); + assert!(self.qualif.contains(Qualif::MUTABLE_INTERIOR)); } } } @@ -949,7 +875,7 @@ This does not pose a problem by itself because they can't be accessed directly." } let candidate = Candidate::Argument { bb, index: i }; if is_shuffle && i == 2 { - if this.can_promote(this.qualif) { + if this.qualif.is_empty() { this.promotion_candidates.push(candidate); } else { span_err!(this.tcx.sess, this.span, E0526, @@ -965,7 +891,7 @@ This does not pose a problem by itself because they can't be accessed directly." if !constant_arguments.contains(&i) { return } - if this.can_promote(this.qualif) { + if this.qualif.is_empty() { this.promotion_candidates.push(candidate); } else { this.tcx.sess.span_err(this.span, @@ -1059,7 +985,7 @@ This does not pose a problem by itself because they can't be accessed directly." // HACK(eddyb) Emulate a bit of dataflow analysis, // conservatively, that drop elaboration will do. let needs_drop = if let Place::Local(local) = *place { - if self.local_qualif[local].map_or(true, |q| q.intersects(Qualif::NEEDS_DROP)) { + if self.local_qualif[local].map_or(true, |q| q.contains(Qualif::NEEDS_DROP)) { Some(self.mir.local_decls[local].source_info.span) } else { None @@ -1111,7 +1037,7 @@ This does not pose a problem by itself because they can't be accessed directly." } // Avoid a generic error for other uses of arguments. - if self.qualif.intersects(Qualif::FN_ARGUMENT) { + if self.qualif.contains(Qualif::FN_ARGUMENT) { let decl = &self.mir.local_decls[index]; let mut err = feature_err( &self.tcx.sess.parse_sess, diff --git a/src/test/compile-fail/const-fn-not-safe-for-const.rs b/src/test/compile-fail/const-fn-not-safe-for-const.rs index d985bae1f2477..341cc7bb49116 100644 --- a/src/test/compile-fail/const-fn-not-safe-for-const.rs +++ b/src/test/compile-fail/const-fn-not-safe-for-const.rs @@ -29,7 +29,6 @@ static Y: u32 = 0; const fn get_Y() -> u32 { Y //~^ ERROR E0013 - //~| ERROR cannot refer to statics by value } const fn get_Y_addr() -> &'static u32 { @@ -49,5 +48,4 @@ const fn get() -> u32 { //~| ERROR let bindings in constant functions are unstable } -fn main() { -} +fn main() {} diff --git a/src/test/compile-fail/issue-14227.rs b/src/test/compile-fail/issue-14227.rs index d8f9f5543e439..95f017061a257 100644 --- a/src/test/compile-fail/issue-14227.rs +++ b/src/test/compile-fail/issue-14227.rs @@ -13,6 +13,10 @@ extern { pub static symbol: (); } -static CRASH: () = symbol; //~ cannot refer to other statics by value +static CRASH: () = symbol; +//~^ ERROR could not evaluate static initializer +//~| tried to read from foreign (extern) static +//~^^^ ERROR could not evaluate static initializer +//~| tried to read from foreign (extern) static fn main() {} diff --git a/src/test/compile-fail/issue-16538.rs b/src/test/compile-fail/issue-16538.rs index 7df445c676c9c..cc65211937716 100644 --- a/src/test/compile-fail/issue-16538.rs +++ b/src/test/compile-fail/issue-16538.rs @@ -22,7 +22,6 @@ mod Y { static foo: *const Y::X = Y::foo(Y::x as *const Y::X); //~^ ERROR `*const usize` cannot be shared between threads safely [E0277] -//~| ERROR cannot refer to other statics by value, use the address-of operator or a constant instead //~| ERROR E0015 fn main() {} diff --git a/src/test/compile-fail/issue-17718-references.rs b/src/test/compile-fail/issue-17718-references.rs index 8e0df283cdbeb..586cfebcd161c 100644 --- a/src/test/compile-fail/issue-17718-references.rs +++ b/src/test/compile-fail/issue-17718-references.rs @@ -22,14 +22,13 @@ static T4: &'static usize = &S; const T5: usize = C; const T6: usize = S; //~ ERROR: constants cannot refer to statics -//~^ cannot refer to statics static T7: usize = C; -static T8: usize = S; //~ ERROR: cannot refer to other statics by value +static T8: usize = S; const T9: Struct = Struct { a: C }; -const T10: Struct = Struct { a: S }; //~ ERROR: cannot refer to statics by value +const T10: Struct = Struct { a: S }; //~^ ERROR: constants cannot refer to statics static T11: Struct = Struct { a: C }; -static T12: Struct = Struct { a: S }; //~ ERROR: cannot refer to other statics by value +static T12: Struct = Struct { a: S }; fn main() {} diff --git a/src/test/compile-fail/issue-28324.rs b/src/test/compile-fail/issue-28324.rs index 3c4d6b42b503d..8512238dd31ca 100644 --- a/src/test/compile-fail/issue-28324.rs +++ b/src/test/compile-fail/issue-28324.rs @@ -15,6 +15,9 @@ extern { } pub static BAZ: u32 = *&error_message_count; -//~^ ERROR cannot refer to other statics by value +//~^ ERROR could not evaluate static initializer +//~| tried to read from foreign (extern) static +//~^^^ ERROR could not evaluate static initializer +//~| tried to read from foreign (extern) static fn main() {} diff --git a/src/test/ui/error-codes/E0494.rs b/src/test/compile-fail/recursive-static-definition.rs similarity index 68% rename from src/test/ui/error-codes/E0494.rs rename to src/test/compile-fail/recursive-static-definition.rs index 5f8632ac1c23d..62c1859e09d3a 100644 --- a/src/test/ui/error-codes/E0494.rs +++ b/src/test/compile-fail/recursive-static-definition.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,12 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -struct Foo { - a: u32 -} +pub static FOO: u32 = FOO; +//~^ ERROR cycle detected when const-evaluating `FOO` -static S : Foo = Foo { a : 0 }; -static A : &'static u32 = &S.a; //~ ERROR E0494 - -fn main() { -} +fn main() {} diff --git a/src/test/compile-fail/thread-local-in-ctfe.rs b/src/test/compile-fail/thread-local-in-ctfe.rs index dc220bd1cc94f..62e26f28b0667 100644 --- a/src/test/compile-fail/thread-local-in-ctfe.rs +++ b/src/test/compile-fail/thread-local-in-ctfe.rs @@ -15,14 +15,12 @@ static A: u32 = 1; static B: u32 = A; //~^ ERROR thread-local statics cannot be accessed at compile-time -//~| ERROR cannot refer to other statics by value static C: &u32 = &A; //~^ ERROR thread-local statics cannot be accessed at compile-time const D: u32 = A; //~^ ERROR thread-local statics cannot be accessed at compile-time -//~| ERROR cannot refer to statics by value const E: &u32 = &A; //~^ ERROR thread-local statics cannot be accessed at compile-time @@ -30,7 +28,6 @@ const E: &u32 = &A; const fn f() -> u32 { A //~^ ERROR thread-local statics cannot be accessed at compile-time - //~| ERROR cannot refer to statics by value } fn main() {} diff --git a/src/test/compile-fail/write-to-static-mut-in-static.rs b/src/test/compile-fail/write-to-static-mut-in-static.rs new file mode 100644 index 0000000000000..1ea74f73723b7 --- /dev/null +++ b/src/test/compile-fail/write-to-static-mut-in-static.rs @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_let)] + +pub static mut A: u32 = 0; +pub static mut B: () = unsafe { A = 1; }; +//~^ ERROR statements in statics are unstable + +pub static mut C: u32 = unsafe { C = 1; 0 }; +//~^ ERROR statements in statics are unstable + +pub static D: u32 = D; + +fn main() {} diff --git a/src/test/incremental/static_refering_to_other_static3/issue.rs b/src/test/incremental/static_refering_to_other_static3/issue.rs new file mode 100644 index 0000000000000..f19ae9e0e8d11 --- /dev/null +++ b/src/test/incremental/static_refering_to_other_static3/issue.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// revisions:rpass1 rpass2 + +#[cfg(rpass1)] +pub static A: u8 = 42; +#[cfg(rpass2)] +pub static A: u8 = 43; + +static B: &u8 = &C.1; +static C: (&&u8, u8) = (&B, A); + +fn main() { + assert_eq!(*B, A); + assert_eq!(**C.0, A); + assert_eq!(C.1, A); +} diff --git a/src/test/compile-fail/auxiliary/pub_static_array.rs b/src/test/run-pass/auxiliary/pub_static_array.rs similarity index 100% rename from src/test/compile-fail/auxiliary/pub_static_array.rs rename to src/test/run-pass/auxiliary/pub_static_array.rs diff --git a/src/test/compile-fail/issue-17450.rs b/src/test/run-pass/issue-17450.rs similarity index 79% rename from src/test/compile-fail/issue-17450.rs rename to src/test/run-pass/issue-17450.rs index cde1bbbe4927a..242d8c20cd759 100644 --- a/src/test/compile-fail/issue-17450.rs +++ b/src/test/run-pass/issue-17450.rs @@ -11,9 +11,6 @@ #![allow(dead_code, warnings)] static mut x: isize = 3; -static mut y: isize = unsafe { - x -//~^ ERROR cannot refer to other statics by value, use the address-of operator or a constant instea -}; +static mut y: isize = unsafe { x }; fn main() {} diff --git a/src/test/compile-fail/issue-17718-borrow-interior.rs b/src/test/run-pass/issue-17718-borrow-interior.rs similarity index 66% rename from src/test/compile-fail/issue-17718-borrow-interior.rs rename to src/test/run-pass/issue-17718-borrow-interior.rs index 31352c57f1bc3..cafc037525782 100644 --- a/src/test/compile-fail/issue-17718-borrow-interior.rs +++ b/src/test/run-pass/issue-17718-borrow-interior.rs @@ -9,17 +9,19 @@ // except according to those terms. struct S { a: usize } -static A: S = S { a: 3 }; + +static A: S = S { a: 3 }; static B: &'static usize = &A.a; -//~^ ERROR: cannot refer to the interior of another static static C: &'static usize = &(A.a); -//~^ ERROR: cannot refer to the interior of another static static D: [usize; 1] = [1]; static E: usize = D[0]; -//~^ ERROR: cannot refer to the interior of another static -//~^^ ERROR: cannot refer to other statics by value static F: &'static usize = &D[0]; -//~^ ERROR: cannot refer to the interior of another static -fn main() {} +fn main() { + assert_eq!(*B, A.a); + assert_eq!(*B, A.a); + + assert_eq!(E, D[0]); + assert_eq!(*F, D[0]); +} diff --git a/src/test/compile-fail/issue-34194.rs b/src/test/run-pass/issue-34194.rs similarity index 92% rename from src/test/compile-fail/issue-34194.rs rename to src/test/run-pass/issue-34194.rs index dd607ebad623d..e1aef8996196d 100644 --- a/src/test/compile-fail/issue-34194.rs +++ b/src/test/run-pass/issue-34194.rs @@ -16,6 +16,5 @@ struct A { static B: &'static A = &A { a: &() }; static C: &'static A = &B; -//~^ ERROR cannot refer to other statics by value fn main() {} diff --git a/src/test/compile-fail/issue-6991.rs b/src/test/run-pass/issue-6991.rs similarity index 82% rename from src/test/compile-fail/issue-6991.rs rename to src/test/run-pass/issue-6991.rs index 0cc5898adfca1..32a9a055d49b8 100644 --- a/src/test/compile-fail/issue-6991.rs +++ b/src/test/run-pass/issue-6991.rs @@ -10,6 +10,5 @@ static x: &'static usize = &1; static y: usize = *x; -//~^ ERROR cannot refer to other statics by value, -// use the address-of operator or a constant instead + fn main() {} diff --git a/src/test/ui/error-codes/E0394.rs b/src/test/run-pass/refer-to-other-statics-by-value.rs similarity index 74% rename from src/test/ui/error-codes/E0394.rs rename to src/test/run-pass/refer-to-other-statics-by-value.rs index dae8e14c5ef18..94c98ff95aba2 100644 --- a/src/test/ui/error-codes/E0394.rs +++ b/src/test/run-pass/refer-to-other-statics-by-value.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,11 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![allow(warnings)] - -static A: u32 = 0; -static B: u32 = A; -//~^ ERROR E0394 +static A: usize = 42; +static B: usize = A; fn main() { + assert_eq!(B, 42); } diff --git a/src/test/compile-fail/static-array-across-crate.rs b/src/test/run-pass/static-array-across-crate.rs similarity index 70% rename from src/test/compile-fail/static-array-across-crate.rs rename to src/test/run-pass/static-array-across-crate.rs index d101432f6d124..732d94cee8ed3 100644 --- a/src/test/compile-fail/static-array-across-crate.rs +++ b/src/test/run-pass/static-array-across-crate.rs @@ -15,13 +15,7 @@ extern crate pub_static_array as array; use array::ARRAY; static X: &'static u8 = &ARRAY[0]; -//~^ ERROR: cannot refer to the interior of another static, use a constant - static Y: &'static u8 = &(&ARRAY)[0]; -//~^ ERROR: cannot refer to the interior of another static, use a constant - static Z: u8 = (&ARRAY)[0]; -//~^ ERROR: cannot refer to the interior of another static, use a constant -//~^^ ERROR: cannot refer to other statics by value pub fn main() {} diff --git a/src/test/ui/error-codes/E0394.stderr b/src/test/ui/error-codes/E0394.stderr deleted file mode 100644 index 6c89957de07e3..0000000000000 --- a/src/test/ui/error-codes/E0394.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0394]: cannot refer to other statics by value, use the address-of operator or a constant instead - --> $DIR/E0394.rs:14:17 - | -LL | static B: u32 = A; - | ^ referring to another static by value - | - = note: use the address-of operator or a constant instead - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0394`. diff --git a/src/test/ui/error-codes/E0494.stderr b/src/test/ui/error-codes/E0494.stderr deleted file mode 100644 index 65e6b1fe670f1..0000000000000 --- a/src/test/ui/error-codes/E0494.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0494]: cannot refer to the interior of another static, use a constant instead - --> $DIR/E0494.rs:16:27 - | -LL | static A : &'static u32 = &S.a; //~ ERROR E0494 - | ^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0494`.