rust/src/test/compile-fail/borrowck/borrowck-vec-pattern-nesting.rs

91 lines
2.6 KiB
Rust
Raw Normal View History

2014-02-05 22:33:10 +00:00
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(advanced_slice_patterns)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(slice_patterns)]
fn a() {
2015-01-31 16:23:42 +00:00
let mut vec = [box 1, box 2, box 3];
match vec {
[box ref _a, _, _] => {
//~^ borrow of `vec[..]` occurs here
vec[0] = box 4; //~ ERROR cannot assign
2016-05-12 23:39:09 +00:00
//~^ assignment to `vec[..]` occurs here
}
}
}
fn b() {
2015-01-31 16:23:42 +00:00
let mut vec = vec!(box 1, box 2, box 3);
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_b..] => {
//~^ borrow of `vec[..]` occurs here
vec[0] = box 4; //~ ERROR cannot assign
2016-05-12 23:39:09 +00:00
//~^ assignment to `vec[..]` occurs here
}
}
}
fn c() {
2015-01-31 16:23:42 +00:00
let mut vec = vec!(box 1, box 2, box 3);
let vec: &mut [Box<isize>] = &mut vec;
match vec {
Collect move errors before reporting This commit changes the way move errors are reported when some value is captured by a PatIdent. First, we collect all of the "cannot move out of" errors before reporting them, and those errors with the same "move source" are reported together. If the move is caused by a PatIdent (that binds by value), we add a note indicating where it is and suggest the user to put `ref` if they don't want the value to move. This makes the "cannot move out of" error in match expression nicer (though the extra note may not feel that helpful in other places :P). For example, with the following code snippet, ```rust enum Foo { Foo1(~u32, ~u32), Foo2(~u32), Foo3, } fn main() { let f = &Foo1(~1u32, ~2u32); match *f { Foo1(num1, num2) => (), Foo2(num) => (), Foo3 => () } } ``` Errors before the change: ```rust test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:11:9: 11:18 error: cannot move out of dereference of `&`-pointer test.rs:11 Foo2(num) => (), ^~~~~~~~~ ``` After: ```rust test.rs:9:11: 9:13 error: cannot move out of dereference of `&`-pointer test.rs:9 match *f { ^~ test.rs:10:14: 10:18 note: attempting to move value to here (to prevent the move, you can use `ref num1` to capture value by reference) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:10:20: 10:24 note: and here (use `ref num2`) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:11:14: 11:17 note: and here (use `ref num`) test.rs:11 Foo2(num) => (), ^~~ ``` Close #8064
2014-04-09 01:14:14 +00:00
[_a, //~ ERROR cannot move out
2016-05-12 23:39:09 +00:00
//~| move occurs here
//~| attempting to move value to here
_b..] => {
// Note: `_a` is *moved* here, but `b` is borrowing,
// hence illegal.
//
// See comment in middle/borrowck/gather_loans/mod.rs
// in the case covering these sorts of vectors.
}
_ => {}
}
let a = vec[0]; //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
2016-05-12 23:39:09 +00:00
//~| can not move out of here
}
fn d() {
2015-01-31 16:23:42 +00:00
let mut vec = vec!(box 1, box 2, box 3);
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_a.., //~ ERROR cannot move out
2016-05-12 23:39:09 +00:00
//~^ move occurs here
Collect move errors before reporting This commit changes the way move errors are reported when some value is captured by a PatIdent. First, we collect all of the "cannot move out of" errors before reporting them, and those errors with the same "move source" are reported together. If the move is caused by a PatIdent (that binds by value), we add a note indicating where it is and suggest the user to put `ref` if they don't want the value to move. This makes the "cannot move out of" error in match expression nicer (though the extra note may not feel that helpful in other places :P). For example, with the following code snippet, ```rust enum Foo { Foo1(~u32, ~u32), Foo2(~u32), Foo3, } fn main() { let f = &Foo1(~1u32, ~2u32); match *f { Foo1(num1, num2) => (), Foo2(num) => (), Foo3 => () } } ``` Errors before the change: ```rust test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:11:9: 11:18 error: cannot move out of dereference of `&`-pointer test.rs:11 Foo2(num) => (), ^~~~~~~~~ ``` After: ```rust test.rs:9:11: 9:13 error: cannot move out of dereference of `&`-pointer test.rs:9 match *f { ^~ test.rs:10:14: 10:18 note: attempting to move value to here (to prevent the move, you can use `ref num1` to capture value by reference) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:10:20: 10:24 note: and here (use `ref num2`) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:11:14: 11:17 note: and here (use `ref num`) test.rs:11 Foo2(num) => (), ^~~ ``` Close #8064
2014-04-09 01:14:14 +00:00
_b] => {} //~ NOTE attempting to move value to here
_ => {}
}
let a = vec[0]; //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
2016-05-12 23:39:09 +00:00
//~| can not move out of here
}
fn e() {
2015-01-31 16:23:42 +00:00
let mut vec = vec!(box 1, box 2, box 3);
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_a, _b, _c] => {} //~ ERROR cannot move out
2016-05-12 23:39:09 +00:00
//~| move occurs here
//~| NOTE attempting to move value to here
//~| NOTE and here
//~| NOTE and here
_ => {}
}
let a = vec[0]; //~ ERROR cannot move out
Collect move errors before reporting This commit changes the way move errors are reported when some value is captured by a PatIdent. First, we collect all of the "cannot move out of" errors before reporting them, and those errors with the same "move source" are reported together. If the move is caused by a PatIdent (that binds by value), we add a note indicating where it is and suggest the user to put `ref` if they don't want the value to move. This makes the "cannot move out of" error in match expression nicer (though the extra note may not feel that helpful in other places :P). For example, with the following code snippet, ```rust enum Foo { Foo1(~u32, ~u32), Foo2(~u32), Foo3, } fn main() { let f = &Foo1(~1u32, ~2u32); match *f { Foo1(num1, num2) => (), Foo2(num) => (), Foo3 => () } } ``` Errors before the change: ```rust test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:10:9: 10:25 error: cannot move out of dereference of `&`-pointer test.rs:10 Foo1(num1, num2) => (), ^~~~~~~~~~~~~~~~ test.rs:11:9: 11:18 error: cannot move out of dereference of `&`-pointer test.rs:11 Foo2(num) => (), ^~~~~~~~~ ``` After: ```rust test.rs:9:11: 9:13 error: cannot move out of dereference of `&`-pointer test.rs:9 match *f { ^~ test.rs:10:14: 10:18 note: attempting to move value to here (to prevent the move, you can use `ref num1` to capture value by reference) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:10:20: 10:24 note: and here (use `ref num2`) test.rs:10 Foo1(num1, num2) => (), ^~~~ test.rs:11:14: 11:17 note: and here (use `ref num`) test.rs:11 Foo2(num) => (), ^~~ ``` Close #8064
2014-04-09 01:14:14 +00:00
//~^ NOTE attempting to move value to here
2016-05-12 23:39:09 +00:00
//~| can not move out of here
}
fn main() {}