diff options
| author | Caio <c410.f3r@gmail.com> | 2021-01-16 15:54:05 -0300 |
|---|---|---|
| committer | Caio <c410.f3r@gmail.com> | 2021-01-16 19:46:54 -0300 |
| commit | ad35979c50366d6b0fbcda99215f1c4e926e5dab (patch) | |
| tree | 8bc4fd6168831ee45cf114456cc70d4cf49266d8 /src/test/ui/borrowck | |
| parent | 63a83c5f55801b17b77adf690db397d17c706c48 (diff) | |
| download | rust-ad35979c50366d6b0fbcda99215f1c4e926e5dab.tar.gz rust-ad35979c50366d6b0fbcda99215f1c4e926e5dab.zip | |
Move some tests to more reasonable directories - 2
Address comments Update limits
Diffstat (limited to 'src/test/ui/borrowck')
19 files changed, 402 insertions, 0 deletions
diff --git a/src/test/ui/borrowck/issue-17263.rs b/src/test/ui/borrowck/issue-17263.rs new file mode 100644 index 00000000000..7e9ff685482 --- /dev/null +++ b/src/test/ui/borrowck/issue-17263.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(box_syntax)] + +struct Foo { a: isize, b: isize } + +fn main() { + let mut x: Box<_> = box Foo { a: 1, b: 2 }; + let (a, b) = (&mut x.a, &mut x.b); + + let mut foo: Box<_> = box Foo { a: 1, b: 2 }; + let (c, d) = (&mut foo.a, &foo.b); + + // We explicitly use the references created above to illustrate that the + // borrow checker is accepting this code *not* because of artificially + // short lifetimes, but rather because it understands that all the + // references are of disjoint parts of memory. + use_imm(d); + use_mut(c); + use_mut(b); + use_mut(a); +} + +fn use_mut<T>(_: &mut T) { } +fn use_imm<T>(_: &T) { } diff --git a/src/test/ui/borrowck/issue-17545.rs b/src/test/ui/borrowck/issue-17545.rs new file mode 100644 index 00000000000..ced6fff315f --- /dev/null +++ b/src/test/ui/borrowck/issue-17545.rs @@ -0,0 +1,10 @@ +#![feature(fn_traits)] + +fn id<T>(x: T) -> T { x } + +pub fn foo<'a, F: Fn(&'a ())>(bar: F) { + bar.call(( + &id(()), //~ ERROR temporary value dropped while borrowed + )); +} +fn main() {} diff --git a/src/test/ui/borrowck/issue-17545.stderr b/src/test/ui/borrowck/issue-17545.stderr new file mode 100644 index 00000000000..79a1e09bd7c --- /dev/null +++ b/src/test/ui/borrowck/issue-17545.stderr @@ -0,0 +1,16 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/issue-17545.rs:7:10 + | +LL | pub fn foo<'a, F: Fn(&'a ())>(bar: F) { + | -- lifetime `'a` defined here +LL | / bar.call(( +LL | | &id(()), + | | ^^^^^^ creates a temporary which is freed while still in use +LL | | )); + | | -- temporary value is freed at the end of this statement + | |______| + | argument requires that borrow lasts for `'a` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/src/test/ui/borrowck/issue-20801.rs b/src/test/ui/borrowck/issue-20801.rs new file mode 100644 index 00000000000..c3f136f2876 --- /dev/null +++ b/src/test/ui/borrowck/issue-20801.rs @@ -0,0 +1,37 @@ +// We used to ICE when moving out of a `*mut T` or `*const T`. + +struct T(u8); + +static mut GLOBAL_MUT_T: T = T(0); + +static GLOBAL_T: T = T(0); + +fn imm_ref() -> &'static T { + unsafe { &GLOBAL_T } +} + +fn mut_ref() -> &'static mut T { + unsafe { &mut GLOBAL_MUT_T } +} + +fn mut_ptr() -> *mut T { + unsafe { core::ptr::null_mut() } +} + +fn const_ptr() -> *const T { + unsafe { core::ptr::null() } +} + +pub fn main() { + let a = unsafe { *mut_ref() }; + //~^ ERROR cannot move out of a mutable reference + + let b = unsafe { *imm_ref() }; + //~^ ERROR cannot move out of a shared reference + + let c = unsafe { *mut_ptr() }; + //~^ ERROR cannot move out of a raw pointer + + let d = unsafe { *const_ptr() }; + //~^ ERROR cannot move out of a raw pointer +} diff --git a/src/test/ui/borrowck/issue-20801.stderr b/src/test/ui/borrowck/issue-20801.stderr new file mode 100644 index 00000000000..d276231dc0c --- /dev/null +++ b/src/test/ui/borrowck/issue-20801.stderr @@ -0,0 +1,39 @@ +error[E0507]: cannot move out of a mutable reference + --> $DIR/issue-20801.rs:26:22 + | +LL | let a = unsafe { *mut_ref() }; + | ^^^^^^^^^^ + | | + | move occurs because value has type `T`, which does not implement the `Copy` trait + | help: consider borrowing here: `&*mut_ref()` + +error[E0507]: cannot move out of a shared reference + --> $DIR/issue-20801.rs:29:22 + | +LL | let b = unsafe { *imm_ref() }; + | ^^^^^^^^^^ + | | + | move occurs because value has type `T`, which does not implement the `Copy` trait + | help: consider borrowing here: `&*imm_ref()` + +error[E0507]: cannot move out of a raw pointer + --> $DIR/issue-20801.rs:32:22 + | +LL | let c = unsafe { *mut_ptr() }; + | ^^^^^^^^^^ + | | + | move occurs because value has type `T`, which does not implement the `Copy` trait + | help: consider borrowing here: `&*mut_ptr()` + +error[E0507]: cannot move out of a raw pointer + --> $DIR/issue-20801.rs:35:22 + | +LL | let d = unsafe { *const_ptr() }; + | ^^^^^^^^^^^^ + | | + | move occurs because value has type `T`, which does not implement the `Copy` trait + | help: consider borrowing here: `&*const_ptr()` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.rs b/src/test/ui/borrowck/issue-24267-flow-exit.rs new file mode 100644 index 00000000000..d6809ee4143 --- /dev/null +++ b/src/test/ui/borrowck/issue-24267-flow-exit.rs @@ -0,0 +1,19 @@ +// Ensure that we reject code when a nonlocal exit (`break`, +// `continue`) causes us to pop over a needed assignment. + +pub fn main() { + foo1(); + foo2(); +} + +pub fn foo1() { + let x: i32; + loop { x = break; } + println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` +} + +pub fn foo2() { + let x: i32; + for _ in 0..10 { x = continue; } + println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` +} diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.stderr b/src/test/ui/borrowck/issue-24267-flow-exit.stderr new file mode 100644 index 00000000000..4eb41ca24dd --- /dev/null +++ b/src/test/ui/borrowck/issue-24267-flow-exit.stderr @@ -0,0 +1,15 @@ +error[E0381]: borrow of possibly-uninitialized variable: `x` + --> $DIR/issue-24267-flow-exit.rs:12:20 + | +LL | println!("{}", x); + | ^ use of possibly-uninitialized `x` + +error[E0381]: borrow of possibly-uninitialized variable: `x` + --> $DIR/issue-24267-flow-exit.rs:18:20 + | +LL | println!("{}", x); + | ^ use of possibly-uninitialized `x` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/issue-25793.rs b/src/test/ui/borrowck/issue-25793.rs new file mode 100644 index 00000000000..6c8dacc2248 --- /dev/null +++ b/src/test/ui/borrowck/issue-25793.rs @@ -0,0 +1,26 @@ +#![feature(rustc_attrs)] +macro_rules! width( + ($this:expr) => { + $this.width.unwrap() + //~^ ERROR cannot use `self.width` because it was mutably borrowed + } +); + +struct HasInfo { + width: Option<usize> +} + +impl HasInfo { + fn get_size(&mut self, n: usize) -> usize { + n + } + + fn get_other(&mut self) -> usize { + let r = &mut *self; + r.get_size(width!(self)) + } + // Above is like `self.get_size(width!(self))`, but it + // deliberately avoids NLL's two phase borrow feature. +} + +fn main() { } diff --git a/src/test/ui/borrowck/issue-25793.stderr b/src/test/ui/borrowck/issue-25793.stderr new file mode 100644 index 00000000000..9d66ba3aae1 --- /dev/null +++ b/src/test/ui/borrowck/issue-25793.stderr @@ -0,0 +1,18 @@ +error[E0503]: cannot use `self.width` because it was mutably borrowed + --> $DIR/issue-25793.rs:4:9 + | +LL | $this.width.unwrap() + | ^^^^^^^^^^^ use of borrowed `*self` +... +LL | let r = &mut *self; + | ---------- borrow of `*self` occurs here +LL | r.get_size(width!(self)) + | -------- ------------ in this macro invocation + | | + | borrow later used by call + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs b/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs new file mode 100644 index 00000000000..71f1f15654b --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.rs @@ -0,0 +1,20 @@ +// Issue 27282: Example 2: This sidesteps the AST checks disallowing +// mutable borrows in match guards by hiding the mutable borrow in a +// guard behind a move (of the mutably borrowed match input) within a +// closure. +// +// This example is not rejected by AST borrowck (and then reliably +// reaches the panic code when executed, despite the compiler warning +// about that match arm being unreachable. + +fn main() { + let b = &mut true; + match b { + &mut false => {}, + _ if { (|| { let bar = b; *bar = false; })(); + false } => { }, + &mut true => { println!("You might think we should get here"); }, + //~^ ERROR use of moved value: `b` [E0382] + _ => panic!("surely we could never get here, since rustc warns it is unreachable."), + } +} diff --git a/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr new file mode 100644 index 00000000000..51f9b464d76 --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-move-match-input-into-guard.stderr @@ -0,0 +1,17 @@ +error[E0382]: use of moved value: `b` + --> $DIR/issue-27282-move-match-input-into-guard.rs:16:14 + | +LL | let b = &mut true; + | - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait +... +LL | _ if { (|| { let bar = b; *bar = false; })(); + | -- - variable moved due to use in closure + | | + | value moved into closure here +LL | false } => { }, +LL | &mut true => { println!("You might think we should get here"); }, + | ^^^^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs new file mode 100644 index 00000000000..9c3e7e9978e --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.rs @@ -0,0 +1,40 @@ +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because it includes a guard that +// diverges, and therefore a single final fake-read at the very end +// after the final match arm would not suffice. +// +// It is also interesting because the access to the corrupted data +// occurs in the pattern-match itself, and not in the guard +// expression. + +struct ForceFnOnce; + +fn main() { + let mut x = &mut Some(&2); + let force_fn_once = ForceFnOnce; + match x { + &mut None => panic!("unreachable"), + &mut Some(&_) + if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = None; drop(force_fn_once); })(); + //~^ ERROR cannot mutably borrow `x` in match guard [E0510] + false + } => {} + + // this segfaults if we corrupted the discriminant, because + // the compiler gets to *assume* that it cannot be the `None` + // case, even though that was the effect of the guard. + &mut Some(&2) + if { + panic!() + } => {} + _ => panic!("unreachable"), + } +} diff --git a/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr new file mode 100644 index 00000000000..f0a3151f4e1 --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-mutate-before-diverging-arm-2.stderr @@ -0,0 +1,14 @@ +error[E0510]: cannot mutably borrow `x` in match guard + --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:26:18 + | +LL | match x { + | - value is immutable in match guard +... +LL | (|| { *x = None; drop(force_fn_once); })(); + | ^^ - borrow occurs due to use of `x` in closure + | | + | cannot mutably borrow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0510`. diff --git a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs new file mode 100644 index 00000000000..82d8b9e9ed9 --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.rs @@ -0,0 +1,18 @@ +// Issue 27282: This is a variation on issue-27282-move-ref-mut-into-guard.rs +// +// It reborrows instead of moving the `ref mut` pattern borrow. This +// means that our conservative check for mutation in guards will +// reject it. But I want to make sure that we continue to reject it +// (under NLL) even when that conservaive check goes away. + +fn main() { + let mut b = &mut true; + match b { + &mut false => {}, + ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); + //~^ ERROR cannot borrow `r` as mutable, as it is immutable for the pattern guard + false } => { &mut *r; }, + &mut true => { println!("You might think we should get here"); }, + _ => panic!("surely we could never get here, since rustc warns it is unreachable."), + } +} diff --git a/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr new file mode 100644 index 00000000000..f0264b56ea5 --- /dev/null +++ b/src/test/ui/borrowck/issue-27282-reborrow-ref-mut-in-guard.stderr @@ -0,0 +1,13 @@ +error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard + --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25 + | +LL | ref mut r if { (|| { let bar = &mut *r; **bar = false; })(); + | ^^ - mutable borrow occurs due to use of `r` in closure + | | + | cannot borrow as mutable + | + = note: variables bound in patterns are immutable until the end of the pattern guard + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/borrowck/issue-45199.rs b/src/test/ui/borrowck/issue-45199.rs new file mode 100644 index 00000000000..cbd45cbb619 --- /dev/null +++ b/src/test/ui/borrowck/issue-45199.rs @@ -0,0 +1,24 @@ +fn test_drop_replace() { + let b: Box<isize>; + //~^ HELP make this binding mutable + //~| SUGGESTION mut b + b = Box::new(1); //~ NOTE first assignment + b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` + //~| NOTE cannot assign twice to immutable +} + +fn test_call() { + let b = Box::new(1); //~ NOTE first assignment + //~| HELP make this binding mutable + //~| SUGGESTION mut b + b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` + //~| NOTE cannot assign twice to immutable +} + +fn test_args(b: Box<i32>) { //~ HELP make this binding mutable + //~| SUGGESTION mut b + b = Box::new(2); //~ ERROR cannot assign to immutable argument `b` + //~| NOTE cannot assign to immutable argument +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-45199.stderr b/src/test/ui/borrowck/issue-45199.stderr new file mode 100644 index 00000000000..83b634051bb --- /dev/null +++ b/src/test/ui/borrowck/issue-45199.stderr @@ -0,0 +1,35 @@ +error[E0384]: cannot assign twice to immutable variable `b` + --> $DIR/issue-45199.rs:6:5 + | +LL | let b: Box<isize>; + | - help: make this binding mutable: `mut b` +... +LL | b = Box::new(1); + | - first assignment to `b` +LL | b = Box::new(2); + | ^ cannot assign twice to immutable variable + +error[E0384]: cannot assign twice to immutable variable `b` + --> $DIR/issue-45199.rs:14:5 + | +LL | let b = Box::new(1); + | - + | | + | first assignment to `b` + | help: make this binding mutable: `mut b` +... +LL | b = Box::new(2); + | ^ cannot assign twice to immutable variable + +error[E0384]: cannot assign to immutable argument `b` + --> $DIR/issue-45199.rs:20:5 + | +LL | fn test_args(b: Box<i32>) { + | - help: make this binding mutable: `mut b` +LL | +LL | b = Box::new(2); + | ^ cannot assign to immutable argument + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/borrowck/issue-46471.rs b/src/test/ui/borrowck/issue-46471.rs new file mode 100644 index 00000000000..8922005d2f8 --- /dev/null +++ b/src/test/ui/borrowck/issue-46471.rs @@ -0,0 +1,7 @@ +fn foo() -> &'static u32 { + let x = 0; + &x + //~^ ERROR cannot return reference to local variable `x` [E0515] +} + +fn main() { } diff --git a/src/test/ui/borrowck/issue-46471.stderr b/src/test/ui/borrowck/issue-46471.stderr new file mode 100644 index 00000000000..935414c1f3f --- /dev/null +++ b/src/test/ui/borrowck/issue-46471.stderr @@ -0,0 +1,9 @@ +error[E0515]: cannot return reference to local variable `x` + --> $DIR/issue-46471.rs:3:5 + | +LL | &x + | ^^ returns a reference to data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. |
