From 8098ac17064ee5a1d34ffe6bc8d35a9574f2bf6e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 20:54:41 +0100 Subject: Add test for assert!() hygiene in edition 2021. --- src/test/ui/hygiene/no_implicit_prelude-2021.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/hygiene/no_implicit_prelude-2021.rs (limited to 'src') diff --git a/src/test/ui/hygiene/no_implicit_prelude-2021.rs b/src/test/ui/hygiene/no_implicit_prelude-2021.rs new file mode 100644 index 00000000000..0fe9ae56c65 --- /dev/null +++ b/src/test/ui/hygiene/no_implicit_prelude-2021.rs @@ -0,0 +1,9 @@ +// check-pass +// edition:2021 + +#![no_implicit_prelude] + +fn main() { + assert!(true, "hoi"); + assert!(false, "hoi {}", 123); +} -- cgit 1.4.1-3-g733a5 From 99a1dea1b7727885d2660bae665cff165fb86a50 Mon Sep 17 00:00:00 2001 From: Tomasz Miąsko Date: Sat, 23 Jan 2021 00:00:00 +0000 Subject: Do not mark unit variants as used when in path pattern Record that we are processing a pattern so that code responsible for handling path resolution can correctly decide whether to mark it as used or not. --- compiler/rustc_passes/src/dead.rs | 2 +- src/test/ui/lint/dead-code/const-and-self.rs | 21 ++++++++++++++++++++- src/test/ui/lint/dead-code/const-and-self.stderr | 20 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/lint/dead-code/const-and-self.stderr (limited to 'src') diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 80a24c90421..3b1b53553d5 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -290,6 +290,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { } fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) { + self.in_pat = true; match pat.kind { PatKind::Struct(ref path, ref fields, _) => { let res = self.typeck_results().qpath_res(path, pat.hir_id); @@ -302,7 +303,6 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { _ => (), } - self.in_pat = true; intravisit::walk_pat(self, pat); self.in_pat = false; } diff --git a/src/test/ui/lint/dead-code/const-and-self.rs b/src/test/ui/lint/dead-code/const-and-self.rs index 1a7b3f43cda..0bcdd6edf0d 100644 --- a/src/test/ui/lint/dead-code/const-and-self.rs +++ b/src/test/ui/lint/dead-code/const-and-self.rs @@ -1,6 +1,6 @@ // check-pass -#![deny(dead_code)] +#![warn(dead_code)] const TLC: usize = 4; @@ -28,8 +28,27 @@ impl Foo for X { } } +enum E { + A, + B, //~ WARN variant is never constructed: `B` + C, //~ WARN variant is never constructed: `C` +} + +type F = E; + +impl E { + fn check(&self) -> bool { + match self { + Self::A => true, + Self::B => false, + F::C => false, + } + } +} + fn main() { let s = [0,1,2,3]; s.doit(); X::foo(); + E::A.check(); } diff --git a/src/test/ui/lint/dead-code/const-and-self.stderr b/src/test/ui/lint/dead-code/const-and-self.stderr new file mode 100644 index 00000000000..c0e406189e8 --- /dev/null +++ b/src/test/ui/lint/dead-code/const-and-self.stderr @@ -0,0 +1,20 @@ +warning: variant is never constructed: `B` + --> $DIR/const-and-self.rs:33:5 + | +LL | B, + | ^ + | +note: the lint level is defined here + --> $DIR/const-and-self.rs:3:9 + | +LL | #![warn(dead_code)] + | ^^^^^^^^^ + +warning: variant is never constructed: `C` + --> $DIR/const-and-self.rs:34:5 + | +LL | C, + | ^ + +warning: 2 warnings emitted + -- cgit 1.4.1-3-g733a5 From d118021f8bfbfda2cd93277c15c607b2c66ff93c Mon Sep 17 00:00:00 2001 From: oli Date: Sun, 3 Jan 2021 18:46:20 +0000 Subject: Permit mutable references in all const contexts --- .../rustc_mir/src/transform/check_consts/ops.rs | 71 ++++++++++++++-------- .../src/transform/check_consts/validation.rs | 29 ++++++++- src/test/ui/check-static-immutable-mut-slices.rs | 2 +- .../ui/check-static-immutable-mut-slices.stderr | 4 +- src/test/ui/consts/const-address-of-mut.stderr | 24 +++++--- src/test/ui/consts/const-eval/issue-65394.stderr | 9 ++- src/test/ui/consts/const-multi-ref.stderr | 10 +-- .../consts/const-mut-refs/const_mut_address_of.rs | 3 +- .../const-mut-refs/const_mut_address_of.stderr | 15 ----- .../ui/consts/const-mut-refs/const_mut_refs.rs | 4 +- .../ui/consts/const-mut-refs/const_mut_refs.stderr | 21 ------- .../ui/consts/const-mut-refs/mut_ref_in_final.rs | 24 ++++++++ .../consts/const-mut-refs/mut_ref_in_final.stderr | 9 +++ .../consts/const-mut-refs/mut_ref_in_final_ok.rs | 22 +++++++ .../const-mut-refs/mut_ref_in_final_ok.stderr | 13 ++++ src/test/ui/consts/const_let_assign3.stderr | 17 ++++-- src/test/ui/consts/issue-17718-const-bad-values.rs | 3 +- .../ui/consts/issue-17718-const-bad-values.stderr | 12 +--- .../ui/consts/projection_qualif.mut_refs.stderr | 11 +--- src/test/ui/consts/projection_qualif.rs | 2 +- src/test/ui/consts/projection_qualif.stock.stderr | 10 +-- src/test/ui/consts/read_from_static_mut_ref.rs | 5 +- src/test/ui/consts/read_from_static_mut_ref.stderr | 17 ++++-- .../static_mut_containing_mut_ref2.mut_refs.stderr | 8 +-- .../ui/consts/static_mut_containing_mut_ref2.rs | 3 +- .../static_mut_containing_mut_ref2.stock.stderr | 9 ++- src/test/ui/error-codes/E0017.rs | 9 +-- src/test/ui/error-codes/E0017.stderr | 35 +++++++---- src/test/ui/error-codes/E0388.rs | 7 ++- src/test/ui/error-codes/E0388.stderr | 29 ++++++--- src/test/ui/issues/issue-46604.rs | 2 +- src/test/ui/issues/issue-46604.stderr | 4 +- src/test/ui/never_type/issue-52443.stderr | 9 ++- src/test/ui/unsafe/ranged_ints2_const.rs | 6 ++ src/test/ui/unsafe/ranged_ints2_const.stderr | 11 +++- 35 files changed, 298 insertions(+), 171 deletions(-) delete mode 100644 src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr delete mode 100644 src/test/ui/consts/const-mut-refs/const_mut_refs.stderr create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 99ffb0edce9..23abd522cf0 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -268,43 +268,41 @@ impl NonConstOp for CellBorrow { } #[derive(Debug)] +/// This op is for `&mut` borrows in the trailing expression of a constant +/// which uses the "enclosing scopes rule" to leak its locals into anonymous +/// static or const items. pub struct MutBorrow(pub hir::BorrowKind); impl NonConstOp for MutBorrow { fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status { - // Forbid everywhere except in const fn with a feature gate - if ccx.const_kind() == hir::ConstContext::ConstFn { - Status::Unstable(sym::const_mut_refs) - } else { - Status::Forbidden + match ccx.const_kind() { + // Mutable statics can handle mutable references in their final value + hir::ConstContext::Static(hir::Mutability::Mut) => Status::Allowed, + _ => Status::Forbidden, } } + fn importance(&self) -> DiagnosticImportance { + // If there were primary errors (like non-const function calls), do not emit further + // errors about mutable references. + DiagnosticImportance::Secondary + } + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { let raw = match self.0 { hir::BorrowKind::Raw => "raw ", hir::BorrowKind::Ref => "", }; - let mut err = if ccx.const_kind() == hir::ConstContext::ConstFn { - feature_err( - &ccx.tcx.sess.parse_sess, - sym::const_mut_refs, - span, - &format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()), - ) - } else { - let mut err = struct_span_err!( - ccx.tcx.sess, - span, - E0764, - "{}mutable references are not allowed in {}s", - raw, - ccx.const_kind(), - ); - err.span_label(span, format!("`&{}mut` is only allowed in `const fn`", raw)); - err - }; + let mut err = struct_span_err!( + ccx.tcx.sess, + span, + E0764, + "{}mutable references are not allowed in final value of {}s", + raw, + ccx.const_kind(), + ); + if ccx.tcx.sess.teach(&err.get_code().unwrap()) { err.note( "References in statics and constants may only refer \ @@ -321,6 +319,29 @@ impl NonConstOp for MutBorrow { } } +#[derive(Debug)] +pub struct TransientMutBorrow(pub hir::BorrowKind); + +impl NonConstOp for TransientMutBorrow { + fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { + Status::Unstable(sym::const_mut_refs) + } + + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + let raw = match self.0 { + hir::BorrowKind::Raw => "raw ", + hir::BorrowKind::Ref => "", + }; + + feature_err( + &ccx.tcx.sess.parse_sess, + sym::const_mut_refs, + span, + &format!("{}mutable references are not allowed in {}s", raw, ccx.const_kind()), + ) + } +} + #[derive(Debug)] pub struct MutDeref; impl NonConstOp for MutDeref { @@ -329,7 +350,7 @@ impl NonConstOp for MutDeref { } fn importance(&self) -> DiagnosticImportance { - // Usually a side-effect of a `MutBorrow` somewhere. + // Usually a side-effect of a `TransientMutBorrow` somewhere. DiagnosticImportance::Secondary } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 08d969b27be..a92997dddac 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -466,6 +466,29 @@ impl Validator<'mir, 'tcx> { } } } + + fn check_mut_borrow(&mut self, local: Local, kind: hir::BorrowKind) { + match self.const_kind() { + // In a const fn all borrows are transient or point to the places given via + // references in the arguments (so we already checked them with + // TransientMutBorrow/MutBorrow as appropriate). + // The borrow checker guarantees that no new non-transient borrows are created. + // NOTE: Once we have heap allocations during CTFE we need to figure out + // how to prevent `const fn` to create long-lived allocations that point + // to mutable memory. + hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)), + _ => { + // Locals with StorageDead do not live beyond the evaluation and can + // thus safely be borrowed without being able to be leaked to the final + // value of the constant. + if self.local_has_storage_dead(local) { + self.check_op(ops::TransientMutBorrow(kind)); + } else { + self.check_op(ops::MutBorrow(kind)); + } + } + } + } } impl Visitor<'tcx> for Validator<'mir, 'tcx> { @@ -562,15 +585,15 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { if !is_allowed { if let BorrowKind::Mut { .. } = kind { - self.check_op(ops::MutBorrow(hir::BorrowKind::Ref)); + self.check_mut_borrow(place.local, hir::BorrowKind::Ref) } else { self.check_op(ops::CellBorrow); } } } - Rvalue::AddressOf(Mutability::Mut, _) => { - self.check_op(ops::MutBorrow(hir::BorrowKind::Raw)) + Rvalue::AddressOf(Mutability::Mut, ref place) => { + self.check_mut_borrow(place.local, hir::BorrowKind::Raw) } Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Shallow, ref place) diff --git a/src/test/ui/check-static-immutable-mut-slices.rs b/src/test/ui/check-static-immutable-mut-slices.rs index 3be02f6a0f6..8f9680778aa 100644 --- a/src/test/ui/check-static-immutable-mut-slices.rs +++ b/src/test/ui/check-static-immutable-mut-slices.rs @@ -1,6 +1,6 @@ // Checks that immutable static items can't have mutable slices static TEST: &'static mut [isize] = &mut []; -//~^ ERROR mutable references are not allowed in statics +//~^ ERROR mutable references are not allowed pub fn main() { } diff --git a/src/test/ui/check-static-immutable-mut-slices.stderr b/src/test/ui/check-static-immutable-mut-slices.stderr index 9ffbb483d13..fcc18cc584c 100644 --- a/src/test/ui/check-static-immutable-mut-slices.stderr +++ b/src/test/ui/check-static-immutable-mut-slices.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in statics +error[E0764]: mutable references are not allowed in final value of statics --> $DIR/check-static-immutable-mut-slices.rs:3:37 | LL | static TEST: &'static mut [isize] = &mut []; - | ^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-address-of-mut.stderr b/src/test/ui/consts/const-address-of-mut.stderr index ec2dac5a7d1..60cdcc7df74 100644 --- a/src/test/ui/consts/const-address-of-mut.stderr +++ b/src/test/ui/consts/const-address-of-mut.stderr @@ -1,20 +1,29 @@ -error[E0764]: raw mutable references are not allowed in constants +error[E0658]: raw mutable references are not allowed in constants --> $DIR/const-address-of-mut.rs:3:32 | LL | const A: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: raw mutable references are not allowed in statics +error[E0658]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:5:33 | LL | static B: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: raw mutable references are not allowed in statics +error[E0658]: raw mutable references are not allowed in statics --> $DIR/const-address-of-mut.rs:7:37 | LL | static mut C: () = { let mut x = 2; &raw mut x; }; - | ^^^^^^^^^^ `&raw mut` is only allowed in `const fn` + | ^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: raw mutable references are not allowed in constant functions --> $DIR/const-address-of-mut.rs:11:13 @@ -27,5 +36,4 @@ LL | let y = &raw mut x; error: aborting due to 4 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-eval/issue-65394.stderr b/src/test/ui/consts/const-eval/issue-65394.stderr index 771d368d783..ec229d7f53a 100644 --- a/src/test/ui/consts/const-eval/issue-65394.stderr +++ b/src/test/ui/consts/const-eval/issue-65394.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/issue-65394.rs:8:13 | LL | let r = &mut x; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/issue-65394.rs:7:9 @@ -15,5 +18,5 @@ LL | }; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0493, E0764. +Some errors have detailed explanations: E0493, E0658. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/const-multi-ref.stderr b/src/test/ui/consts/const-multi-ref.stderr index c0a320d46cb..dd5cadfe295 100644 --- a/src/test/ui/consts/const-multi-ref.stderr +++ b/src/test/ui/consts/const-multi-ref.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const-multi-ref.rs:6:13 | LL | let p = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability --> $DIR/const-multi-ref.rs:16:13 @@ -15,5 +18,4 @@ LL | let p = &a; error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs b/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs index 5819daa817a..24df647f05b 100644 --- a/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs +++ b/src/test/ui/consts/const-mut-refs/const_mut_address_of.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(const_mut_refs)] #![feature(const_fn)] #![feature(raw_ref_op)] @@ -22,9 +23,7 @@ const fn baz(foo: &mut Foo)-> *mut usize { const _: () = { foo().bar(); - //~^ ERROR mutable references are not allowed in constants baz(&mut foo()); - //~^ ERROR mutable references are not allowed in constants }; fn main() {} diff --git a/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr b/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr deleted file mode 100644 index 2214ce6ee1c..00000000000 --- a/src/test/ui/consts/const-mut-refs/const_mut_address_of.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_address_of.rs:24:5 - | -LL | foo().bar(); - | ^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_address_of.rs:26:9 - | -LL | baz(&mut foo()); - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs index 9099d5a1b8e..544458dfcd8 100644 --- a/src/test/ui/consts/const-mut-refs/const_mut_refs.rs +++ b/src/test/ui/consts/const-mut-refs/const_mut_refs.rs @@ -1,3 +1,4 @@ +// check-pass #![feature(const_mut_refs)] struct Foo { @@ -29,9 +30,6 @@ const fn bazz(foo: &mut Foo) -> usize { fn main() { let _: [(); foo().bar()] = [(); 1]; - //~^ ERROR mutable references are not allowed in constants let _: [(); baz(&mut foo())] = [(); 2]; - //~^ ERROR mutable references are not allowed in constants let _: [(); bazz(&mut foo())] = [(); 3]; - //~^ ERROR mutable references are not allowed in constants } diff --git a/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr b/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr deleted file mode 100644 index 4ca7b128b7c..00000000000 --- a/src/test/ui/consts/const-mut-refs/const_mut_refs.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:31:17 - | -LL | let _: [(); foo().bar()] = [(); 1]; - | ^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:33:21 - | -LL | let _: [(); baz(&mut foo())] = [(); 2]; - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error[E0764]: mutable references are not allowed in constants - --> $DIR/const_mut_refs.rs:35:22 - | -LL | let _: [(); bazz(&mut foo())] = [(); 3]; - | ^^^^^^^^^^ `&mut` is only allowed in `const fn` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs new file mode 100644 index 00000000000..c85acd3b849 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -0,0 +1,24 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] +const NULL: *mut i32 = std::ptr::null_mut(); +const A: *const i32 = &4; + +// It could be made sound to allow it to compile, +// but we do not want to allow this to compile, +// as that would be an enormous footgun in oli-obk's opinion. +const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed + +// Could be ok, but the same analysis that prevents the mutable one above will also bail out here +// Using a block with some complex content, because just `&45` would get promoted, +// which is not what we want to test here. +const C: *const i32 = &{ + let mut x = 42; + x += 3; + x +}; + +fn main() { + println!("{}", unsafe { *A }); + unsafe { *B = 4 } // Bad news +} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr new file mode 100644 index 00000000000..6d570052aeb --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -0,0 +1,9 @@ +error[E0764]: mutable references are not allowed in final value of constants + --> $DIR/mut_ref_in_final.rs:10:21 + | +LL | const B: *mut i32 = &mut 4; + | ^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0764`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs new file mode 100644 index 00000000000..3f2995df2d7 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs @@ -0,0 +1,22 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] + +use std::cell::UnsafeCell; +struct NotAMutex(UnsafeCell); + +unsafe impl Sync for NotAMutex {} + +const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +// `BAR` works, because `&42` promotes immediately instead of relying on +// "final value lifetime extension". +const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); + +fn main() { + unsafe { + **FOO.0.get() = 99; + assert_eq!(**FOO.0.get(), 99); + } +} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr new file mode 100644 index 00000000000..8b51e44e169 --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr @@ -0,0 +1,13 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final_ok.rs:10:65 + | +LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index dc86e178a42..3eac61c0ce6 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -7,19 +7,24 @@ LL | const fn foo(&mut self, x: u32) { = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const_let_assign3.rs:16:5 | LL | s.foo(3); - | ^ `&mut` is only allowed in `const fn` + | ^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/const_let_assign3.rs:22:13 | LL | let y = &mut x; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error: aborting due to 3 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/issue-17718-const-bad-values.rs b/src/test/ui/consts/issue-17718-const-bad-values.rs index 49023f18ddb..62bbb3b569c 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.rs +++ b/src/test/ui/consts/issue-17718-const-bad-values.rs @@ -1,10 +1,9 @@ const C1: &'static mut [usize] = &mut []; -//~^ ERROR: mutable references are not allowed in constants +//~^ ERROR: mutable references are not allowed 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/consts/issue-17718-const-bad-values.stderr b/src/test/ui/consts/issue-17718-const-bad-values.stderr index 7c50978d4eb..7e02fa4686f 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.stderr +++ b/src/test/ui/consts/issue-17718-const-bad-values.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/issue-17718-const-bad-values.rs:1:34 | 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 @@ -20,13 +20,7 @@ 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 3 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/consts/projection_qualif.mut_refs.stderr b/src/test/ui/consts/projection_qualif.mut_refs.stderr index fad8f011f75..0945a23f3b1 100644 --- a/src/test/ui/consts/projection_qualif.mut_refs.stderr +++ b/src/test/ui/consts/projection_qualif.mut_refs.stderr @@ -1,9 +1,3 @@ -error[E0764]: mutable references are not allowed in constants - --> $DIR/projection_qualif.rs:10:27 - | -LL | let b: *mut u32 = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` - error[E0658]: dereferencing raw pointers in constants is unstable --> $DIR/projection_qualif.rs:11:18 | @@ -13,7 +7,6 @@ LL | unsafe { *b = 5; } = note: see issue #51911 for more information = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 5e2584a6e95..d35df330bb8 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -7,7 +7,7 @@ use std::cell::Cell; const FOO: &u32 = { let mut a = 42; { - let b: *mut u32 = &mut a; //~ ERROR mutable references are not allowed in constants + let b: *mut u32 = &mut a; //[stock]~ ERROR mutable references are not allowed in constants unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants } &{a} diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/projection_qualif.stock.stderr index fad8f011f75..e451898caba 100644 --- a/src/test/ui/consts/projection_qualif.stock.stderr +++ b/src/test/ui/consts/projection_qualif.stock.stderr @@ -1,8 +1,11 @@ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/projection_qualif.rs:10:27 | LL | let b: *mut u32 = &mut a; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constants is unstable --> $DIR/projection_qualif.rs:11:18 @@ -15,5 +18,4 @@ LL | unsafe { *b = 5; } error: aborting due to 2 previous errors -Some errors have detailed explanations: E0658, E0764. -For more information about an error, try `rustc --explain E0658`. +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/read_from_static_mut_ref.rs b/src/test/ui/consts/read_from_static_mut_ref.rs index 5faa983ab09..665c305e961 100644 --- a/src/test/ui/consts/read_from_static_mut_ref.rs +++ b/src/test/ui/consts/read_from_static_mut_ref.rs @@ -1,9 +1,8 @@ -// We are keeping this test in case we decide to allow mutable references in statics again #![feature(const_mut_refs)] #![allow(const_err)] -static OH_NO: &mut i32 = &mut 42; -//~^ ERROR mutable references are not allowed in statics +static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable references are not allowed fn main() { assert_eq!(*OH_NO, 42); + *OH_NO = 43; //~ ERROR cannot assign to `*OH_NO`, as `OH_NO` is an immutable static } diff --git a/src/test/ui/consts/read_from_static_mut_ref.stderr b/src/test/ui/consts/read_from_static_mut_ref.stderr index c936ac0b7d5..373220878ec 100644 --- a/src/test/ui/consts/read_from_static_mut_ref.stderr +++ b/src/test/ui/consts/read_from_static_mut_ref.stderr @@ -1,9 +1,16 @@ -error[E0764]: mutable references are not allowed in statics - --> $DIR/read_from_static_mut_ref.rs:5:26 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/read_from_static_mut_ref.rs:4:26 | LL | static OH_NO: &mut i32 = &mut 42; - | ^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^ -error: aborting due to previous error +error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item + --> $DIR/read_from_static_mut_ref.rs:7:5 + | +LL | *OH_NO = 43; + | ^^^^^^^^^^^ cannot assign + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0764`. +Some errors have detailed explanations: E0594, E0764. +For more information about an error, try `rustc --explain E0594`. 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 36c280ca5c6..8db75dd63cf 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 2821d1a0154..61368546083 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs @@ -5,6 +5,7 @@ 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 +//[mut_refs]~^ ERROR could not evaluate static initializer +//[stock]~^^ ERROR mutable references are not allowed in statics 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 36c280ca5c6..5cdcea23231 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,9 +1,12 @@ -error[E0764]: mutable references are not allowed in statics +error[E0658]: 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` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable 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 E0658`. diff --git a/src/test/ui/error-codes/E0017.rs b/src/test/ui/error-codes/E0017.rs index 262f7bc72c7..c211ad1a2f8 100644 --- a/src/test/ui/error-codes/E0017.rs +++ b/src/test/ui/error-codes/E0017.rs @@ -2,12 +2,13 @@ static X: i32 = 1; const C: i32 = 2; static mut M: i32 = 3; -const CR: &'static mut i32 = &mut C; //~ ERROR E0764 +const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable -static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0764 +static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR E0658 //~| ERROR cannot borrow + //~| ERROR mutable references are not allowed -static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 +static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| 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 }; //~ ERROR mutable references are not fn main() {} diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index ea591587e6d..9b094b19757 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -13,17 +13,26 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/E0017.rs:5:30 | LL | const CR: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error[E0764]: mutable references are not allowed in statics +error[E0658]: mutation through a reference is 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` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:7:39 + | +LL | static STATIC_REF: &'static mut i32 = &mut X; + | ^^^^^^ error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0017.rs:7:39 @@ -32,7 +41,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:11:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -45,19 +54,19 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0017.rs:10:38 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:11: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 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0017.rs:13:52 | LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 6 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0596, E0764. +Some errors have detailed explanations: E0596, E0658, 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 bb0c4979b9a..6049d95f0d2 100644 --- a/src/test/ui/error-codes/E0388.rs +++ b/src/test/ui/error-codes/E0388.rs @@ -1,12 +1,13 @@ static X: i32 = 1; const C: i32 = 2; -const CR: &'static mut i32 = &mut C; //~ ERROR E0764 +const CR: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable static STATIC_REF: &'static mut i32 = &mut X; //~ ERROR cannot borrow - //~| ERROR E0764 + //~| ERROR E0658 + //~| ERROR mutable references are not allowed -static CONST_REF: &'static mut i32 = &mut C; //~ ERROR E0764 +static CONST_REF: &'static mut i32 = &mut C; //~ ERROR mutable references are not allowed //~| WARN taking a mutable fn main() {} diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 73e0b139cd0..74d6a92e170 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -13,17 +13,26 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0764]: mutable references are not allowed in final value of constants --> $DIR/E0388.rs:4:30 | LL | const CR: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error[E0764]: mutable references are not allowed in statics +error[E0658]: mutation through a reference is 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` + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0388.rs:6:39 + | +LL | static STATIC_REF: &'static mut i32 = &mut X; + | ^^^^^^ error[E0596]: cannot borrow immutable static item `X` as mutable --> $DIR/E0388.rs:6:39 @@ -32,7 +41,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:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ @@ -45,13 +54,13 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in statics - --> $DIR/E0388.rs:9:38 +error[E0764]: mutable references are not allowed in final value of statics + --> $DIR/E0388.rs:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; - | ^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^ -error: aborting due to 4 previous errors; 2 warnings emitted +error: aborting due to 5 previous errors; 2 warnings emitted -Some errors have detailed explanations: E0596, E0764. +Some errors have detailed explanations: E0596, E0658, E0764. For more information about an error, try `rustc --explain E0596`. diff --git a/src/test/ui/issues/issue-46604.rs b/src/test/ui/issues/issue-46604.rs index 273187a5a13..6ec6e7bdcb8 100644 --- a/src/test/ui/issues/issue-46604.rs +++ b/src/test/ui/issues/issue-46604.rs @@ -1,4 +1,4 @@ -static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR E0764 +static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; //~ ERROR mutable references are not allowed fn write>(buffer: T) { } fn main() { diff --git a/src/test/ui/issues/issue-46604.stderr b/src/test/ui/issues/issue-46604.stderr index 5421721dec2..488be0e7731 100644 --- a/src/test/ui/issues/issue-46604.stderr +++ b/src/test/ui/issues/issue-46604.stderr @@ -1,8 +1,8 @@ -error[E0764]: mutable references are not allowed in statics +error[E0764]: mutable references are not allowed in final value of statics --> $DIR/issue-46604.rs:1:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; - | ^^^^^^^^^^^^^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^^^^^^^^^^^^^ error[E0594]: cannot assign to `buf[_]`, as `buf` is an immutable static item --> $DIR/issue-46604.rs:6:5 diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 051896cb89c..1683841e9d7 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -39,11 +39,14 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct LL | [(); { for _ in 0usize.. {}; 0}]; | ^^^^^^^^ -error[E0764]: mutable references are not allowed in constants +error[E0658]: mutable references are not allowed in constants --> $DIR/issue-52443.rs:9:21 | LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ `&mut` is only allowed in `const fn` + | ^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants --> $DIR/issue-52443.rs:9:21 @@ -53,5 +56,5 @@ LL | [(); { for _ in 0usize.. {}; 0}]; error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0308, E0744, E0764. +Some errors have detailed explanations: E0015, E0308, E0658, E0744. For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs index 65e0d79308c..b7178c2b52b 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.rs +++ b/src/test/ui/unsafe/ranged_ints2_const.rs @@ -18,3 +18,9 @@ const fn bar() -> NonZero { let y = unsafe { &mut x.0 }; //~ ERROR mutable references unsafe { NonZero(1) } } + +const fn boo() -> NonZero { + let mut x = unsafe { NonZero(1) }; + unsafe { let y = &mut x.0; } //~ ERROR mutable references + unsafe { NonZero(1) } +} diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr index 5ce4296458e..a0dc950e76d 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.stderr +++ b/src/test/ui/unsafe/ranged_ints2_const.stderr @@ -16,6 +16,15 @@ LL | let y = unsafe { &mut x.0 }; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable +error[E0658]: mutable references are not allowed in constant functions + --> $DIR/ranged_ints2_const.rs:24:22 + | +LL | unsafe { let y = &mut x.0; } + | ^^^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block --> $DIR/ranged_ints2_const.rs:11:13 | @@ -24,7 +33,7 @@ LL | let y = &mut x.0; | = note: mutating layout constrained fields cannot statically be checked for valid values -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0133, E0658. For more information about an error, try `rustc --explain E0133`. -- cgit 1.4.1-3-g733a5 From b217fab9608f97fc99c77f4cac5909df0e59db0c Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 17:27:59 +0000 Subject: Rename tests to what their code actually does --- src/test/ui/consts/projection_qualif.rs | 16 ---------------- src/test/ui/consts/read_from_static_mut_ref.rs | 8 -------- src/test/ui/consts/write_to_mut_ref_dest.rs | 16 ++++++++++++++++ src/test/ui/consts/write_to_static_via_mut_ref.rs | 8 ++++++++ 4 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 src/test/ui/consts/projection_qualif.rs delete mode 100644 src/test/ui/consts/read_from_static_mut_ref.rs create mode 100644 src/test/ui/consts/write_to_mut_ref_dest.rs create mode 100644 src/test/ui/consts/write_to_static_via_mut_ref.rs (limited to 'src') diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs deleted file mode 100644 index d35df330bb8..00000000000 --- a/src/test/ui/consts/projection_qualif.rs +++ /dev/null @@ -1,16 +0,0 @@ -// revisions: stock mut_refs - -#![cfg_attr(mut_refs, feature(const_mut_refs))] - -use std::cell::Cell; - -const FOO: &u32 = { - let mut a = 42; - { - let b: *mut u32 = &mut a; //[stock]~ ERROR mutable references are not allowed in constants - unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants - } - &{a} -}; - -fn main() {} diff --git a/src/test/ui/consts/read_from_static_mut_ref.rs b/src/test/ui/consts/read_from_static_mut_ref.rs deleted file mode 100644 index 665c305e961..00000000000 --- a/src/test/ui/consts/read_from_static_mut_ref.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![feature(const_mut_refs)] -#![allow(const_err)] - -static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable references are not allowed -fn main() { - assert_eq!(*OH_NO, 42); - *OH_NO = 43; //~ ERROR cannot assign to `*OH_NO`, as `OH_NO` is an immutable static -} diff --git a/src/test/ui/consts/write_to_mut_ref_dest.rs b/src/test/ui/consts/write_to_mut_ref_dest.rs new file mode 100644 index 00000000000..d35df330bb8 --- /dev/null +++ b/src/test/ui/consts/write_to_mut_ref_dest.rs @@ -0,0 +1,16 @@ +// revisions: stock mut_refs + +#![cfg_attr(mut_refs, feature(const_mut_refs))] + +use std::cell::Cell; + +const FOO: &u32 = { + let mut a = 42; + { + let b: *mut u32 = &mut a; //[stock]~ ERROR mutable references are not allowed in constants + unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants + } + &{a} +}; + +fn main() {} diff --git a/src/test/ui/consts/write_to_static_via_mut_ref.rs b/src/test/ui/consts/write_to_static_via_mut_ref.rs new file mode 100644 index 00000000000..665c305e961 --- /dev/null +++ b/src/test/ui/consts/write_to_static_via_mut_ref.rs @@ -0,0 +1,8 @@ +#![feature(const_mut_refs)] +#![allow(const_err)] + +static OH_NO: &mut i32 = &mut 42; //~ ERROR mutable references are not allowed +fn main() { + assert_eq!(*OH_NO, 42); + *OH_NO = 43; //~ ERROR cannot assign to `*OH_NO`, as `OH_NO` is an immutable static +} -- cgit 1.4.1-3-g733a5 From 3cd0b46baca1848b577f2172935a139663697643 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 17:31:22 +0000 Subject: Fix a comment that only made sense in the context of a dataflow based mutability check --- src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index c85acd3b849..98960ec6c6e 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -9,9 +9,8 @@ const A: *const i32 = &4; // as that would be an enormous footgun in oli-obk's opinion. const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed -// Could be ok, but the same analysis that prevents the mutable one above will also bail out here -// Using a block with some complex content, because just `&45` would get promoted, -// which is not what we want to test here. +// Ok, because no references to mutable data exist here, since the `{}` moves +// its value and then takes a reference to that. const C: *const i32 = &{ let mut x = 42; x += 3; -- cgit 1.4.1-3-g733a5 From 00e62fabf101571c337fdce24544e94b0e0fda9c Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 16 Jan 2021 18:05:51 +0000 Subject: Adjust wording of a diagnostic --- .../rustc_mir/src/transform/check_consts/ops.rs | 2 +- .../ui/check-static-immutable-mut-slices.stderr | 2 +- .../consts/const-mut-refs/mut_ref_in_final.stderr | 2 +- .../ui/consts/issue-17718-const-bad-values.stderr | 2 +- .../ui/consts/projection_qualif.mut_refs.stderr | 12 ------------ src/test/ui/consts/projection_qualif.stock.stderr | 21 --------------------- src/test/ui/consts/read_from_static_mut_ref.stderr | 16 ---------------- .../ui/consts/write_to_mut_ref_dest.mut_refs.stderr | 12 ++++++++++++ .../ui/consts/write_to_mut_ref_dest.stock.stderr | 21 +++++++++++++++++++++ .../ui/consts/write_to_static_via_mut_ref.stderr | 16 ++++++++++++++++ src/test/ui/error-codes/E0017.stderr | 8 ++++---- src/test/ui/error-codes/E0388.stderr | 6 +++--- src/test/ui/issues/issue-46604.stderr | 2 +- 13 files changed, 61 insertions(+), 61 deletions(-) delete mode 100644 src/test/ui/consts/projection_qualif.mut_refs.stderr delete mode 100644 src/test/ui/consts/projection_qualif.stock.stderr delete mode 100644 src/test/ui/consts/read_from_static_mut_ref.stderr create mode 100644 src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr create mode 100644 src/test/ui/consts/write_to_mut_ref_dest.stock.stderr create mode 100644 src/test/ui/consts/write_to_static_via_mut_ref.stderr (limited to 'src') diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 23abd522cf0..6e726215177 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -298,7 +298,7 @@ impl NonConstOp for MutBorrow { ccx.tcx.sess, span, E0764, - "{}mutable references are not allowed in final value of {}s", + "{}mutable references are not allowed in the final value of {}s", raw, ccx.const_kind(), ); diff --git a/src/test/ui/check-static-immutable-mut-slices.stderr b/src/test/ui/check-static-immutable-mut-slices.stderr index fcc18cc584c..a32a94c1315 100644 --- a/src/test/ui/check-static-immutable-mut-slices.stderr +++ b/src/test/ui/check-static-immutable-mut-slices.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/check-static-immutable-mut-slices.rs:3:37 | LL | static TEST: &'static mut [isize] = &mut []; diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 6d570052aeb..57bf5f7395d 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/mut_ref_in_final.rs:10:21 | LL | const B: *mut i32 = &mut 4; diff --git a/src/test/ui/consts/issue-17718-const-bad-values.stderr b/src/test/ui/consts/issue-17718-const-bad-values.stderr index 7e02fa4686f..ce60aaa0797 100644 --- a/src/test/ui/consts/issue-17718-const-bad-values.stderr +++ b/src/test/ui/consts/issue-17718-const-bad-values.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/issue-17718-const-bad-values.rs:1:34 | LL | const C1: &'static mut [usize] = &mut []; diff --git a/src/test/ui/consts/projection_qualif.mut_refs.stderr b/src/test/ui/consts/projection_qualif.mut_refs.stderr deleted file mode 100644 index 0945a23f3b1..00000000000 --- a/src/test/ui/consts/projection_qualif.mut_refs.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: dereferencing raw pointers in constants is unstable - --> $DIR/projection_qualif.rs:11:18 - | -LL | unsafe { *b = 5; } - | ^^^^^^ - | - = note: see issue #51911 for more information - = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/projection_qualif.stock.stderr b/src/test/ui/consts/projection_qualif.stock.stderr deleted file mode 100644 index e451898caba..00000000000 --- a/src/test/ui/consts/projection_qualif.stock.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0658]: mutable references are not allowed in constants - --> $DIR/projection_qualif.rs:10:27 - | -LL | let b: *mut u32 = &mut a; - | ^^^^^^ - | - = note: see issue #57349 for more information - = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable - -error[E0658]: dereferencing raw pointers in constants is unstable - --> $DIR/projection_qualif.rs:11:18 - | -LL | unsafe { *b = 5; } - | ^^^^^^ - | - = note: see issue #51911 for more information - = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/read_from_static_mut_ref.stderr b/src/test/ui/consts/read_from_static_mut_ref.stderr deleted file mode 100644 index 373220878ec..00000000000 --- a/src/test/ui/consts/read_from_static_mut_ref.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0764]: mutable references are not allowed in final value of statics - --> $DIR/read_from_static_mut_ref.rs:4:26 - | -LL | static OH_NO: &mut i32 = &mut 42; - | ^^^^^^^ - -error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item - --> $DIR/read_from_static_mut_ref.rs:7:5 - | -LL | *OH_NO = 43; - | ^^^^^^^^^^^ cannot assign - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0594, E0764. -For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr b/src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr new file mode 100644 index 00000000000..3ee50907461 --- /dev/null +++ b/src/test/ui/consts/write_to_mut_ref_dest.mut_refs.stderr @@ -0,0 +1,12 @@ +error[E0658]: dereferencing raw pointers in constants is unstable + --> $DIR/write_to_mut_ref_dest.rs:11:18 + | +LL | unsafe { *b = 5; } + | ^^^^^^ + | + = note: see issue #51911 for more information + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/write_to_mut_ref_dest.stock.stderr b/src/test/ui/consts/write_to_mut_ref_dest.stock.stderr new file mode 100644 index 00000000000..2b6d1d3267b --- /dev/null +++ b/src/test/ui/consts/write_to_mut_ref_dest.stock.stderr @@ -0,0 +1,21 @@ +error[E0658]: mutable references are not allowed in constants + --> $DIR/write_to_mut_ref_dest.rs:10:27 + | +LL | let b: *mut u32 = &mut a; + | ^^^^^^ + | + = note: see issue #57349 for more information + = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable + +error[E0658]: dereferencing raw pointers in constants is unstable + --> $DIR/write_to_mut_ref_dest.rs:11:18 + | +LL | unsafe { *b = 5; } + | ^^^^^^ + | + = note: see issue #51911 for more information + = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/write_to_static_via_mut_ref.stderr b/src/test/ui/consts/write_to_static_via_mut_ref.stderr new file mode 100644 index 00000000000..d19e998d617 --- /dev/null +++ b/src/test/ui/consts/write_to_static_via_mut_ref.stderr @@ -0,0 +1,16 @@ +error[E0764]: mutable references are not allowed in the final value of statics + --> $DIR/write_to_static_via_mut_ref.rs:4:26 + | +LL | static OH_NO: &mut i32 = &mut 42; + | ^^^^^^^ + +error[E0594]: cannot assign to `*OH_NO`, as `OH_NO` is an immutable static item + --> $DIR/write_to_static_via_mut_ref.rs:7:5 + | +LL | *OH_NO = 43; + | ^^^^^^^^^^^ cannot assign + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0594, E0764. +For more information about an error, try `rustc --explain E0594`. diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 9b094b19757..7d959b6d148 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -13,7 +13,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0017.rs:5:30 | LL | const CR: &'static mut i32 = &mut C; @@ -28,7 +28,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:7:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; @@ -54,13 +54,13 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:11:38 | LL | static CONST_REF: &'static mut i32 = &mut C; | ^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0017.rs:13:52 | LL | static STATIC_MUT_REF: &'static mut i32 = unsafe { &mut M }; diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 74d6a92e170..4886a156d2e 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -13,7 +13,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of constants +error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0388.rs:4:30 | LL | const CR: &'static mut i32 = &mut C; @@ -28,7 +28,7 @@ LL | static STATIC_REF: &'static mut i32 = &mut X; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0388.rs:6:39 | LL | static STATIC_REF: &'static mut i32 = &mut X; @@ -54,7 +54,7 @@ note: `const` item defined here LL | const C: i32 = 2; | ^^^^^^^^^^^^^^^^^ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/E0388.rs:10:38 | LL | static CONST_REF: &'static mut i32 = &mut C; diff --git a/src/test/ui/issues/issue-46604.stderr b/src/test/ui/issues/issue-46604.stderr index 488be0e7731..7faa2d79ba4 100644 --- a/src/test/ui/issues/issue-46604.stderr +++ b/src/test/ui/issues/issue-46604.stderr @@ -1,4 +1,4 @@ -error[E0764]: mutable references are not allowed in final value of statics +error[E0764]: mutable references are not allowed in the final value of statics --> $DIR/issue-46604.rs:1:25 | LL | static buf: &mut [u8] = &mut [1u8,2,3,4,5,7]; -- cgit 1.4.1-3-g733a5 From cd0987115765efdf4f834f0f0bf24c4cef063b1a Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 23 Jan 2021 11:58:58 +0000 Subject: Cover more cases in the test suite --- .../ui/consts/const-mut-refs/mut_ref_in_final.rs | 45 +++++++++++++++++ .../consts/const-mut-refs/mut_ref_in_final.stderr | 57 ++++++++++++++++++++-- .../consts/const-mut-refs/mut_ref_in_final_ok.rs | 22 --------- .../const-mut-refs/mut_ref_in_final_ok.stderr | 13 ----- 4 files changed, 99 insertions(+), 38 deletions(-) delete mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs delete mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr (limited to 'src') diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index 98960ec6c6e..b2230697037 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,9 @@ #![feature(const_mut_refs)] #![feature(const_fn)] +#![feature(const_transmute)] #![feature(raw_ref_op)] +#![feature(const_raw_ptr_deref)] + const NULL: *mut i32 = std::ptr::null_mut(); const A: *const i32 = &4; @@ -9,6 +12,25 @@ const A: *const i32 = &4; // as that would be an enormous footgun in oli-obk's opinion. const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed +// Ok, no actual mutable allocation exists +const B2: Option<&mut i32> = None; + +// Not ok, can't prove that no mutable allocation ends up in final value +const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed + +const fn helper() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour, who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(42 as *mut i32)) +} } +// Check that we do not look into function bodies. +// We treat all functions as not returning a mutable reference, because there is no way to +// do that without causing the borrow checker to complain (see the B5/helper2 test below). +const B4: Option<&mut i32> = helper(); + +const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) } +const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed + // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. const C: *const i32 = &{ @@ -17,7 +39,30 @@ const C: *const i32 = &{ x }; +use std::cell::UnsafeCell; +struct NotAMutex(UnsafeCell); + +unsafe impl Sync for NotAMutex {} + +const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); +//~^ ERROR temporary value dropped while borrowed + +// `BAR` works, because `&42` promotes immediately instead of relying on +// the enclosing scope rule. +const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); + fn main() { println!("{}", unsafe { *A }); unsafe { *B = 4 } // Bad news + + unsafe { + **FOO.0.get() = 99; + assert_eq!(**FOO.0.get(), 99); + } } diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 57bf5f7395d..389b88955ce 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,9 +1,60 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:10:21 + --> $DIR/mut_ref_in_final.rs:13:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ -error: aborting due to previous error +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:19:40 + | +LL | const B3: Option<&mut i32> = Some(&mut 42); + | ----------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:32:43 + | +LL | const B5: Option<&mut i32> = helper2(&mut 42); + | -------------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:47:65 + | +LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a constant requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:50:67 + | +LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a static requires that borrow lasts for `'static` + +error[E0716]: temporary value dropped while borrowed + --> $DIR/mut_ref_in_final.rs:53:71 + | +LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); + | -------------------------------^^-- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use + | using this value as a static requires that borrow lasts for `'static` + +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0764`. +Some errors have detailed explanations: E0716, E0764. +For more information about an error, try `rustc --explain E0716`. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs deleted file mode 100644 index 3f2995df2d7..00000000000 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![feature(const_mut_refs)] -#![feature(const_fn)] -#![feature(raw_ref_op)] - -use std::cell::UnsafeCell; -struct NotAMutex(UnsafeCell); - -unsafe impl Sync for NotAMutex {} - -const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); -//~^ ERROR temporary value dropped while borrowed - -// `BAR` works, because `&42` promotes immediately instead of relying on -// "final value lifetime extension". -const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42)); - -fn main() { - unsafe { - **FOO.0.get() = 99; - assert_eq!(**FOO.0.get(), 99); - } -} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr deleted file mode 100644 index 8b51e44e169..00000000000 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_ok.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final_ok.rs:10:65 - | -LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); - | -------------------------------^^-- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use - | using this value as a constant requires that borrow lasts for `'static` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0716`. -- cgit 1.4.1-3-g733a5 From 819b008d8be8d154d9561bed1e4b770c741f23a2 Mon Sep 17 00:00:00 2001 From: oli Date: Sat, 23 Jan 2021 12:35:45 +0000 Subject: Put dynamic check tests into their own file --- .../ui/consts/const-mut-refs/mut_ref_in_final.rs | 15 ++---------- .../consts/const-mut-refs/mut_ref_in_final.stderr | 22 ++++++++--------- .../mut_ref_in_final_dynamic_check.rs | 28 ++++++++++++++++++++++ .../mut_ref_in_final_dynamic_check.stderr | 23 ++++++++++++++++++ 4 files changed, 64 insertions(+), 24 deletions(-) create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs create mode 100644 src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr (limited to 'src') diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs index b2230697037..166ba20f124 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.rs @@ -1,6 +1,5 @@ #![feature(const_mut_refs)] #![feature(const_fn)] -#![feature(const_transmute)] #![feature(raw_ref_op)] #![feature(const_raw_ptr_deref)] @@ -18,18 +17,8 @@ const B2: Option<&mut i32> = None; // Not ok, can't prove that no mutable allocation ends up in final value const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed -const fn helper() -> Option<&'static mut i32> { unsafe { - // Undefined behaviour, who doesn't love tests like this. - // This code never gets executed, because the static checks fail before that. - Some(&mut *(42 as *mut i32)) -} } -// Check that we do not look into function bodies. -// We treat all functions as not returning a mutable reference, because there is no way to -// do that without causing the borrow checker to complain (see the B5/helper2 test below). -const B4: Option<&mut i32> = helper(); - -const fn helper2(x: &mut i32) -> Option<&mut i32> { Some(x) } -const B5: Option<&mut i32> = helper2(&mut 42); //~ ERROR temporary value dropped while borrowed +const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) } +const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped while borrowed // Ok, because no references to mutable data exist here, since the `{}` moves // its value and then takes a reference to that. diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr index 389b88955ce..cbae74cce6f 100644 --- a/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final.stderr @@ -1,11 +1,11 @@ error[E0764]: mutable references are not allowed in the final value of constants - --> $DIR/mut_ref_in_final.rs:13:21 + --> $DIR/mut_ref_in_final.rs:12:21 | LL | const B: *mut i32 = &mut 4; | ^^^^^^ error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:19:40 + --> $DIR/mut_ref_in_final.rs:18:40 | LL | const B3: Option<&mut i32> = Some(&mut 42); | ----------^^- @@ -15,17 +15,17 @@ LL | const B3: Option<&mut i32> = Some(&mut 42); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:32:43 + --> $DIR/mut_ref_in_final.rs:21:42 | -LL | const B5: Option<&mut i32> = helper2(&mut 42); - | -------------^^- - | | | | - | | | temporary value is freed at the end of this statement - | | creates a temporary which is freed while still in use +LL | const B4: Option<&mut i32> = helper(&mut 42); + | ------------^^- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary which is freed while still in use | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:47:65 + --> $DIR/mut_ref_in_final.rs:36:65 | LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -35,7 +35,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a constant requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:50:67 + --> $DIR/mut_ref_in_final.rs:39:67 | LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- @@ -45,7 +45,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | using this value as a static requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/mut_ref_in_final.rs:53:71 + --> $DIR/mut_ref_in_final.rs:42:71 | LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42)); | -------------------------------^^-- diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs new file mode 100644 index 00000000000..1e856ec0a0a --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.rs @@ -0,0 +1,28 @@ +#![feature(const_mut_refs)] +#![feature(const_fn)] +#![feature(raw_ref_op)] +#![feature(const_raw_ptr_deref)] + +// This file checks that our dynamic checks catch things that the static checks miss. +// We do not have static checks for these, because we do not look into function bodies. +// We treat all functions as not returning a mutable reference, because there is no way to +// do that without causing the borrow checker to complain (see the B4/helper test in +// mut_ref_in_final.rs). + +const fn helper() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (integer as pointer), who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(42 as *mut i32)) //~ ERROR any use of this value will cause an error +} } +// The error is an evaluation error and not a validation error, so the error is reported +// directly at the site where it occurs. +const A: Option<&mut i32> = helper(); + +const fn helper2() -> Option<&'static mut i32> { unsafe { + // Undefined behaviour (dangling pointer), who doesn't love tests like this. + // This code never gets executed, because the static checks fail before that. + Some(&mut *(&mut 42 as *mut i32)) +} } +const B: Option<&mut i32> = helper2(); //~ ERROR encountered dangling pointer in final constant + +fn main() {} diff --git a/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr new file mode 100644 index 00000000000..0bbf84b71bb --- /dev/null +++ b/src/test/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr @@ -0,0 +1,23 @@ +error: any use of this value will cause an error + --> $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | +LL | Some(&mut *(42 as *mut i32)) + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | unable to turn bytes into a pointer + | inside `helper` at $DIR/mut_ref_in_final_dynamic_check.rs:15:10 + | inside `A` at $DIR/mut_ref_in_final_dynamic_check.rs:19:29 +... +LL | const A: Option<&mut i32> = helper(); + | ------------------------------------- + | + = note: `#[deny(const_err)]` on by default + +error: encountered dangling pointer in final constant + --> $DIR/mut_ref_in_final_dynamic_check.rs:26:1 + | +LL | const B: Option<&mut i32> = helper2(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + -- cgit 1.4.1-3-g733a5 From 1129e8678038cfc938559b90b4155dde8b84edf3 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 23 Jan 2021 18:05:59 +0100 Subject: Cleanup `render_stability_since_raw` to remove code duplication --- src/librustdoc/html/render/mod.rs | 43 ++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 26afd705740..f15d43b7b16 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2934,34 +2934,25 @@ fn render_stability_since_raw( containing_ver: Option<&str>, containing_const_ver: Option<&str>, ) { - let ver = ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None }); + let ver = ver.filter(|inner| !inner.is_empty()); + let const_ver = const_ver.filter(|inner| !inner.is_empty()); - let const_ver = const_ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None }); - - if let Some(v) = ver { - if let Some(cv) = const_ver { - if const_ver != containing_const_ver { - write!( - w, - "{0} (const: {1})", - v, cv - ); - } else if ver != containing_ver { - write!( - w, - "{0}", - v - ); - } - } else { - if ver != containing_ver { - write!( - w, - "{0}", - v - ); - } + match (ver, const_ver) { + (Some(v), Some(cv)) if const_ver != containing_const_ver => { + write!( + w, + "{0} (const: {1})", + v, cv + ); + } + (Some(v), _) if ver != containing_ver => { + write!( + w, + "{0}", + v + ); } + _ => {} } } -- cgit 1.4.1-3-g733a5 From 9b1d27d440d58edcb4c673798c60181c03c084c1 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Fri, 22 Jan 2021 10:54:53 +0100 Subject: Add option to control doctest run directory This option will allow splitting the compile-time from the run-time directory of doctest invocations and is one step to solve https://github.com/rust-lang/cargo/issues/8993#issuecomment-760088944 --- src/librustdoc/config.rs | 5 +++++ src/librustdoc/doctest.rs | 3 +++ src/librustdoc/lib.rs | 8 ++++++++ src/test/rustdoc-ui/run-directory.correct.stdout | 6 ++++++ src/test/rustdoc-ui/run-directory.incorrect.stdout | 6 ++++++ src/test/rustdoc-ui/run-directory.rs | 23 ++++++++++++++++++++++ 6 files changed, 51 insertions(+) create mode 100644 src/test/rustdoc-ui/run-directory.correct.stdout create mode 100644 src/test/rustdoc-ui/run-directory.incorrect.stdout create mode 100644 src/test/rustdoc-ui/run-directory.rs (limited to 'src') diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index e43ea965c04..508bed072e6 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -103,6 +103,8 @@ crate struct Options { crate should_test: bool, /// List of arguments to pass to the test harness, if running tests. crate test_args: Vec, + /// The working directory in which to run tests. + crate test_run_directory: Option, /// Optional path to persist the doctest executables to, defaults to a /// temporary directory if not set. crate persist_doctests: Option, @@ -175,6 +177,7 @@ impl fmt::Debug for Options { .field("lint_cap", &self.lint_cap) .field("should_test", &self.should_test) .field("test_args", &self.test_args) + .field("test_run_directory", &self.test_run_directory) .field("persist_doctests", &self.persist_doctests) .field("default_passes", &self.default_passes) .field("manual_passes", &self.manual_passes) @@ -572,6 +575,7 @@ impl Options { let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some(); let static_root_path = matches.opt_str("static-root-path"); let generate_search_filter = !matches.opt_present("disable-per-crate-search"); + let test_run_directory = matches.opt_str("test-run-directory").map(PathBuf::from); let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from); let test_builder = matches.opt_str("test-builder").map(PathBuf::from); let codegen_options_strs = matches.opt_strs("C"); @@ -613,6 +617,7 @@ impl Options { display_warnings, show_coverage, crate_version, + test_run_directory, persist_doctests, runtool, runtool_args, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index c87ab833f7a..09cbd94e4ac 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -365,6 +365,9 @@ fn run_test( } else { cmd = Command::new(output_file); } + if let Some(run_directory) = options.test_run_directory { + cmd.current_dir(run_directory); + } match cmd.output() { Err(e) => return Err(TestFailure::ExecutionError(e)), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 719aca612f5..d823f789013 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -167,6 +167,14 @@ fn opts() -> Vec { stable("test-args", |o| { o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS") }), + unstable("test-run-directory", |o| { + o.optopt( + "", + "test-run-directory", + "The working directory in which to run tests", + "PATH", + ) + }), stable("target", |o| o.optopt("", "target", "target triple to document", "TRIPLE")), stable("markdown-css", |o| { o.optmulti( diff --git a/src/test/rustdoc-ui/run-directory.correct.stdout b/src/test/rustdoc-ui/run-directory.correct.stdout new file mode 100644 index 00000000000..e9b2754794a --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.correct.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 10) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/run-directory.incorrect.stdout b/src/test/rustdoc-ui/run-directory.incorrect.stdout new file mode 100644 index 00000000000..97a5dbc5c0c --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.incorrect.stdout @@ -0,0 +1,6 @@ + +running 1 test +test $DIR/run-directory.rs - foo (line 19) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/src/test/rustdoc-ui/run-directory.rs b/src/test/rustdoc-ui/run-directory.rs new file mode 100644 index 00000000000..78431c0e80b --- /dev/null +++ b/src/test/rustdoc-ui/run-directory.rs @@ -0,0 +1,23 @@ +// this test asserts that the cwd of doctest invocations is set correctly. + +// revisions: correct incorrect +// check-pass +// [correct]compile-flags:--test --test-run-directory={{src-base}} +// [incorrect]compile-flags:--test --test-run-directory={{src-base}}/coverage +// normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" +// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +/// ``` +/// assert_eq!( +/// std::fs::read_to_string("run-directory.rs").unwrap(), +/// include_str!("run-directory.rs"), +/// ); +/// ``` +#[cfg(correct)] +pub fn foo() {} + +/// ``` +/// assert!(std::fs::read_to_string("run-directory.rs").is_err()); +/// ``` +#[cfg(incorrect)] +pub fn foo() {} -- cgit 1.4.1-3-g733a5 From 20a460e1cf23262b46a7e9672a02c5f07b91eff5 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sat, 23 Jan 2021 18:41:04 +0100 Subject: Fix rendering of stabilization version for trait implementors --- src/librustdoc/html/render/mod.rs | 8 ++++---- src/test/rustdoc/implementor-stable-version.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/test/rustdoc/implementor-stable-version.rs (limited to 'src') diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index f15d43b7b16..bfaadc38763 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2471,7 +2471,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: fn render_implementor( cx: &Context<'_>, implementor: &Impl, - parent: &clean::Item, + trait_: &clean::Item, w: &mut Buffer, implementor_dups: &FxHashMap, aliases: &[String], @@ -2491,11 +2491,11 @@ fn render_implementor( w, cx, implementor, - parent, + trait_, AssocItemLink::Anchor(None), RenderMode::Normal, - implementor.impl_item.stable_since(cx.tcx()).as_deref(), - implementor.impl_item.const_stable_since(cx.tcx()).as_deref(), + trait_.stable_since(cx.tcx()).as_deref(), + trait_.const_stable_since(cx.tcx()).as_deref(), false, Some(use_absolute), false, diff --git a/src/test/rustdoc/implementor-stable-version.rs b/src/test/rustdoc/implementor-stable-version.rs new file mode 100644 index 00000000000..0a065d8095b --- /dev/null +++ b/src/test/rustdoc/implementor-stable-version.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +#![feature(staged_api)] + +#[stable(feature = "bar", since = "OLD 1.0")] +pub trait Bar {} + +#[stable(feature = "baz", since = "OLD 1.0")] +pub trait Baz {} + +pub struct Foo; + +// @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' 'NEW 2.0' +#[stable(feature = "foobar", since = "NEW 2.0")] +impl Bar for Foo {} + +// @!has foo/trait.Baz.html '//div[@id="implementors-list"]//span[@class="since"]' 'OLD 1.0' +#[stable(feature = "foobaz", since = "OLD 1.0")] +impl Baz for Foo {} -- cgit 1.4.1-3-g733a5 From 14aa12fcc2ebee6edfd6092a51122a6a6ba78d4d Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 22 Jan 2021 06:57:33 +0100 Subject: Replace version_check dependency with own version parsing code This gives compiler maintainers a better degree of control over how the version gets parsed and is a good way to ensure that there are no changes of behaviour in the future. Also, issue a warning if the version is invalid instead of erroring so that we stay forwards compatible with possible future changes of the versioning scheme. Last, this improves the present test a little. --- Cargo.lock | 1 - compiler/rustc_attr/Cargo.toml | 1 - compiler/rustc_attr/src/builtin.rs | 32 +++++- .../ui/feature-gates/feature-gate-cfg-version.rs | 30 +++--- .../feature-gates/feature-gate-cfg-version.stderr | 110 +++++++++++++++++---- 5 files changed, 138 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index b2ae22b6abd..ee52e34163b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3568,7 +3568,6 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", - "version_check", ] [[package]] diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 5f941a0a650..dc0711a5b0f 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -18,4 +18,3 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_ast = { path = "../rustc_ast" } -version_check = "0.9" diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ead90f23ce7..26baaf07880 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -10,7 +10,6 @@ use rustc_session::Session; use rustc_span::hygiene::Transparency; use rustc_span::{symbol::sym, symbol::Symbol, Span}; use std::num::NonZeroU32; -use version_check::Version; pub fn is_builtin_attr(attr: &Attribute) -> bool { attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some() @@ -526,6 +525,26 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &ParseSess, features: &F } } +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] +struct Version { + major: u16, + minor: u16, + patch: u16, +} + +fn parse_version(s: &str, allow_appendix: bool) -> Option { + let mut components = s.split('-'); + let d = components.next()?; + if !allow_appendix && components.next().is_some() { + return None; + } + let mut digits = d.splitn(3, '.'); + let major = digits.next()?.parse().ok()?; + let minor = digits.next()?.parse().ok()?; + let patch = digits.next().unwrap_or("0").parse().ok()?; + Some(Version { major, minor, patch }) +} + /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to /// evaluate individual items. pub fn eval_condition( @@ -555,16 +574,21 @@ pub fn eval_condition( return false; } }; - let min_version = match Version::parse(&min_version.as_str()) { + let min_version = match parse_version(&min_version.as_str(), false) { Some(ver) => ver, None => { - sess.span_diagnostic.struct_span_err(*span, "invalid version literal").emit(); + sess.span_diagnostic + .struct_span_warn( + *span, + "unknown version literal format, assuming it refers to a future version", + ) + .emit(); return false; } }; let channel = env!("CFG_RELEASE_CHANNEL"); let nightly = channel == "nightly" || channel == "dev"; - let rustc_version = Version::parse(env!("CFG_RELEASE")).unwrap(); + let rustc_version = parse_version(env!("CFG_RELEASE"), true).unwrap(); // See https://github.com/rust-lang/rust/issues/64796#issuecomment-625474439 for details if nightly { rustc_version > min_version } else { rustc_version >= min_version } diff --git a/src/test/ui/feature-gates/feature-gate-cfg-version.rs b/src/test/ui/feature-gates/feature-gate-cfg-version.rs index c29ef99945e..e35784a68d1 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-version.rs +++ b/src/test/ui/feature-gates/feature-gate-cfg-version.rs @@ -1,3 +1,9 @@ +#[cfg(version(42))] //~ ERROR: expected a version literal +//~^ ERROR `cfg(version)` is experimental and subject to change +fn foo() {} +#[cfg(version(1.20))] //~ ERROR: expected a version literal +//~^ ERROR `cfg(version)` is experimental and subject to change +fn foo() -> bool { true } #[cfg(version("1.44"))] //~^ ERROR `cfg(version)` is experimental and subject to change fn foo() -> bool { true } @@ -11,30 +17,32 @@ fn bar() -> bool { false } #[cfg(version(false))] //~ ERROR: expected a version literal //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("foo"))] //~ ERROR: invalid version literal +#[cfg(version("foo"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("999"))] +#[cfg(version("999"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("-1"))] //~ ERROR: invalid version literal +#[cfg(version("-1"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("65536"))] //~ ERROR: invalid version literal +#[cfg(version("65536"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { false } -#[cfg(version("0"))] +#[cfg(version("0"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change fn bar() -> bool { true } - -#[cfg(version("1.65536.2"))] +#[cfg(version("1.0"))] +//~^ ERROR `cfg(version)` is experimental and subject to change +fn bar() -> bool { true } +#[cfg(version("1.65536.2"))] //~ WARNING: unknown version literal format +//~^ ERROR `cfg(version)` is experimental and subject to change +fn bar() -> bool { false } +#[cfg(version("1.20.0-stable"))] //~ WARNING: unknown version literal format //~^ ERROR `cfg(version)` is experimental and subject to change -fn version_check_bug() {} +fn bar() {} fn main() { - // This should fail but due to a bug in version_check `1.65536.2` is interpreted as `1.2`. - // See https://github.com/SergioBenitez/version_check/issues/11 - version_check_bug(); assert!(foo()); assert!(bar()); assert!(cfg!(version("1.42"))); //~ ERROR `cfg(version)` is experimental and subject to change diff --git a/src/test/ui/feature-gates/feature-gate-cfg-version.stderr b/src/test/ui/feature-gates/feature-gate-cfg-version.stderr index bdf160b5a02..ae899d409ec 100644 --- a/src/test/ui/feature-gates/feature-gate-cfg-version.stderr +++ b/src/test/ui/feature-gates/feature-gate-cfg-version.stderr @@ -1,6 +1,36 @@ error[E0658]: `cfg(version)` is experimental and subject to change --> $DIR/feature-gate-cfg-version.rs:1:7 | +LL | #[cfg(version(42))] + | ^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +error: expected a version literal + --> $DIR/feature-gate-cfg-version.rs:1:15 + | +LL | #[cfg(version(42))] + | ^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:4:7 + | +LL | #[cfg(version(1.20))] + | ^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +error: expected a version literal + --> $DIR/feature-gate-cfg-version.rs:4:15 + | +LL | #[cfg(version(1.20))] + | ^^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:7:7 + | LL | #[cfg(version("1.44"))] | ^^^^^^^^^^^^^^^ | @@ -8,7 +38,7 @@ LL | #[cfg(version("1.44"))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:4:11 + --> $DIR/feature-gate-cfg-version.rs:10:11 | LL | #[cfg(not(version("1.44")))] | ^^^^^^^^^^^^^^^ @@ -17,7 +47,7 @@ LL | #[cfg(not(version("1.44")))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:8:7 + --> $DIR/feature-gate-cfg-version.rs:14:7 | LL | #[cfg(version("1.43", "1.44", "1.45"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,13 +56,13 @@ LL | #[cfg(version("1.43", "1.44", "1.45"))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error: expected single version literal - --> $DIR/feature-gate-cfg-version.rs:8:7 + --> $DIR/feature-gate-cfg-version.rs:14:7 | LL | #[cfg(version("1.43", "1.44", "1.45"))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:11:7 + --> $DIR/feature-gate-cfg-version.rs:17:7 | LL | #[cfg(version(false))] | ^^^^^^^^^^^^^^ @@ -41,13 +71,13 @@ LL | #[cfg(version(false))] = help: add `#![feature(cfg_version)]` to the crate attributes to enable error: expected a version literal - --> $DIR/feature-gate-cfg-version.rs:11:15 + --> $DIR/feature-gate-cfg-version.rs:17:15 | LL | #[cfg(version(false))] | ^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:14:7 + --> $DIR/feature-gate-cfg-version.rs:20:7 | LL | #[cfg(version("foo"))] | ^^^^^^^^^^^^^^ @@ -55,14 +85,14 @@ LL | #[cfg(version("foo"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:14:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:20:15 | LL | #[cfg(version("foo"))] | ^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:17:7 + --> $DIR/feature-gate-cfg-version.rs:23:7 | LL | #[cfg(version("999"))] | ^^^^^^^^^^^^^^ @@ -70,8 +100,14 @@ LL | #[cfg(version("999"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:23:15 + | +LL | #[cfg(version("999"))] + | ^^^^^ + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:20:7 + --> $DIR/feature-gate-cfg-version.rs:26:7 | LL | #[cfg(version("-1"))] | ^^^^^^^^^^^^^ @@ -79,14 +115,14 @@ LL | #[cfg(version("-1"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:20:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:26:15 | LL | #[cfg(version("-1"))] | ^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:23:7 + --> $DIR/feature-gate-cfg-version.rs:29:7 | LL | #[cfg(version("65536"))] | ^^^^^^^^^^^^^^^^ @@ -94,14 +130,14 @@ LL | #[cfg(version("65536"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: invalid version literal - --> $DIR/feature-gate-cfg-version.rs:23:15 +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:29:15 | LL | #[cfg(version("65536"))] | ^^^^^^^ error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:26:7 + --> $DIR/feature-gate-cfg-version.rs:32:7 | LL | #[cfg(version("0"))] | ^^^^^^^^^^^^ @@ -109,8 +145,23 @@ LL | #[cfg(version("0"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:32:15 + | +LL | #[cfg(version("0"))] + | ^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:35:7 + | +LL | #[cfg(version("1.0"))] + | ^^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:30:7 + --> $DIR/feature-gate-cfg-version.rs:38:7 | LL | #[cfg(version("1.65536.2"))] | ^^^^^^^^^^^^^^^^^^^^ @@ -118,8 +169,29 @@ LL | #[cfg(version("1.65536.2"))] = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:38:15 + | +LL | #[cfg(version("1.65536.2"))] + | ^^^^^^^^^^^ + +error[E0658]: `cfg(version)` is experimental and subject to change + --> $DIR/feature-gate-cfg-version.rs:41:7 + | +LL | #[cfg(version("1.20.0-stable"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #64796 for more information + = help: add `#![feature(cfg_version)]` to the crate attributes to enable + +warning: unknown version literal format, assuming it refers to a future version + --> $DIR/feature-gate-cfg-version.rs:41:15 + | +LL | #[cfg(version("1.20.0-stable"))] + | ^^^^^^^^^^^^^^^ + error[E0658]: `cfg(version)` is experimental and subject to change - --> $DIR/feature-gate-cfg-version.rs:40:18 + --> $DIR/feature-gate-cfg-version.rs:48:18 | LL | assert!(cfg!(version("1.42"))); | ^^^^^^^^^^^^^^^ @@ -127,6 +199,6 @@ LL | assert!(cfg!(version("1.42"))); = note: see issue #64796 for more information = help: add `#![feature(cfg_version)]` to the crate attributes to enable -error: aborting due to 16 previous errors +error: aborting due to 19 previous errors; 7 warnings emitted For more information about this error, try `rustc --explain E0658`. -- cgit 1.4.1-3-g733a5 From 351b2acd14dab76292c0e9a684d2714454cc9956 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 23:03:01 -0500 Subject: Make bad shlex parsing a pretty error --- src/tools/jsondocck/src/main.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 29131f686a9..376639ced0a 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -149,7 +149,20 @@ fn get_commands(template: &str) -> Result, ()> { } } - let args = cap.name("args").map_or(vec![], |m| shlex::split(m.as_str()).unwrap()); + let args = cap.name("args") + .map_or(Some(vec![]), |m| shlex::split(m.as_str())); + + let args = match args { + Some(args) => args, + None => { + print_err( + &format!("Invalid arguments to shlex::split: `{}`", cap.name("args").unwrap().as_str()), + lineno + ); + errors = true; + continue; + } + }; if !cmd.validate(&args, commands.len(), lineno) { errors = true; -- cgit 1.4.1-3-g733a5 From c37c4213543a727870ca862d25446b3c66d8e399 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Sat, 23 Jan 2021 23:17:31 -0500 Subject: fmt --- src/tools/jsondocck/src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs index 376639ced0a..6ec292aba64 100644 --- a/src/tools/jsondocck/src/main.rs +++ b/src/tools/jsondocck/src/main.rs @@ -149,15 +149,17 @@ fn get_commands(template: &str) -> Result, ()> { } } - let args = cap.name("args") - .map_or(Some(vec![]), |m| shlex::split(m.as_str())); + let args = cap.name("args").map_or(Some(vec![]), |m| shlex::split(m.as_str())); let args = match args { Some(args) => args, None => { print_err( - &format!("Invalid arguments to shlex::split: `{}`", cap.name("args").unwrap().as_str()), - lineno + &format!( + "Invalid arguments to shlex::split: `{}`", + cap.name("args").unwrap().as_str() + ), + lineno, ); errors = true; continue; -- cgit 1.4.1-3-g733a5