Auto merge of #49718 - petrochenkov:fieldcmp, r=eddyb
Hygiene 2.0: Avoid comparing fields by name
There are two separate commits here (not counting tests):
- The first one unifies named (`obj.name`) and numeric (`obj.0`) field access expressions in AST and HIR. Before field references in these expressions are resolved it doesn't matter whether the field is named or numeric (it's just a symbol) and 99% of code is common. After field references are resolved we work with
them by index for all fields (see the second commit), so it's again not important whether the field was named or numeric (this includes MIR where all fields were already by index).
(This refactoring actually fixed some bugs in HIR-based borrow checker where borrows through names (`S {
0: ref x }`) and indices (`&s.0`) weren't considered overlapping.)
- The second commit removes all by-name field comparison and instead resolves field references to their indices once, and then uses those resolutions. (There are still a few name comparisons in save-analysis, because save-analysis is weird, but they are made correctly hygienic).
Thus we are fixing a bunch of "secondary" field hygiene bugs (in borrow checker, lints).
Fixes https://github.com/rust-lang/rust/issues/46314
This commit is contained in:
commit
defcfe7142
87 changed files with 759 additions and 676 deletions
|
|
@ -36,7 +36,7 @@ fn main() {
|
|||
|
||||
let mut line1 = Line::default();
|
||||
let _moved = line1.origin;
|
||||
let _ = line1.origin.x + 1; //[ast]~ ERROR use of collaterally moved value: `line1.origin.x`
|
||||
let _ = line1.origin.x + 1; //[ast]~ ERROR use of moved value: `line1.origin.x`
|
||||
//[mir]~^ [E0382]
|
||||
|
||||
let mut line2 = Line::default();
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ const TUP: (usize,) = (42,);
|
|||
|
||||
fn main() {
|
||||
let a: [isize; TUP.1];
|
||||
//~^ ERROR attempted out-of-bounds tuple index
|
||||
//~^ ERROR no field `1` on type `(usize,)`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B, z: inner::Z) {
|
|||
e.b; //~ ERROR: field `b` of struct `xc::B` is private
|
||||
|
||||
z.0;
|
||||
z.1; //~ ERROR: field `1` of tuple-struct `inner::Z` is private
|
||||
z.1; //~ ERROR: field `1` of struct `inner::Z` is private
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ fn main() {
|
|||
origin.0;
|
||||
origin.1;
|
||||
origin.2;
|
||||
//~^ ERROR attempted out-of-bounds tuple index `2` on type `Point`
|
||||
//~^ ERROR no field `2` on type `Point`
|
||||
let tuple = (0, 0);
|
||||
tuple.0;
|
||||
tuple.1;
|
||||
tuple.2;
|
||||
//~^ ERROR attempted out-of-bounds tuple index `2` on type `({integer}, {integer})`
|
||||
//~^ ERROR no field `2` on type `({integer}, {integer})`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,29 +40,29 @@ fn query() -> bool { true }
|
|||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.SimplifyCfg-qualify-consts.after.mir
|
||||
// fn main() -> () {
|
||||
// fn main() -> (){
|
||||
// let mut _0: ();
|
||||
// scope 1 {
|
||||
// let _2: S<'35_0rs>;
|
||||
// let _2: S<'36_0rs>;
|
||||
// }
|
||||
// scope 2 {
|
||||
// }
|
||||
// ...
|
||||
// let mut _1: ();
|
||||
// let mut _3: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
|
||||
// let mut _4: std::option::Option<&'35_0rs S<'35_0rs>>;
|
||||
// let mut _3: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
|
||||
// let mut _4: std::option::Option<&'36_0rs S<'36_0rs>>;
|
||||
// let mut _5: ();
|
||||
// let mut _6: &'16s std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
|
||||
// let mut _7: std::option::Option<&'35_0rs S<'35_0rs>>;
|
||||
// let mut _8: &'35_0rs S<'35_0rs>;
|
||||
// let mut _9: &'35_0rs S<'35_0rs>;
|
||||
// let mut _6: &'17s std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
|
||||
// let mut _7: std::option::Option<&'36_0rs S<'36_0rs>>;
|
||||
// let mut _8: &'36_0rs S<'36_0rs>;
|
||||
// let mut _9: &'36_0rs S<'36_0rs>;
|
||||
// let mut _10: ();
|
||||
// let mut _11: bool;
|
||||
// let mut _12: !;
|
||||
// let mut _13: ();
|
||||
// let mut _14: &'33s std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>;
|
||||
// let mut _15: std::option::Option<&'35_0rs S<'35_0rs>>;
|
||||
// let mut _16: &'35_0rs S<'35_0rs>;
|
||||
// let mut _17: &'35_0rs S<'35_0rs>;
|
||||
//
|
||||
// let mut _14: &'34s std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>;
|
||||
// let mut _15: std::option::Option<&'36_0rs S<'36_0rs>>;
|
||||
// let mut _16: &'36_0rs S<'36_0rs>;
|
||||
// let mut _17: &'36_0rs S<'36_0rs>;
|
||||
// bb0: {
|
||||
// goto -> bb1;
|
||||
// }
|
||||
|
|
@ -73,7 +73,7 @@ fn query() -> bool { true }
|
|||
// StorageLive(_2);
|
||||
// StorageLive(_3);
|
||||
// StorageLive(_4);
|
||||
// _4 = std::option::Option<&'35_0rs S<'35_0rs>>::None;
|
||||
// _4 = std::option::Option<&'36_0rs S<'36_0rs>>::None;
|
||||
// _3 = const <std::cell::Cell<T>>::new(move _4) -> [return: bb4, unwind: bb3];
|
||||
// }
|
||||
// bb3: {
|
||||
|
|
@ -81,21 +81,21 @@ fn query() -> bool { true }
|
|||
// }
|
||||
// bb4: {
|
||||
// StorageDead(_4);
|
||||
// _2 = S<'35_0rs> { r: move _3 };
|
||||
// _2 = S<'36_0rs> { r: move _3 };
|
||||
// StorageDead(_3);
|
||||
// StorageLive(_6);
|
||||
// _6 = &'16s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
|
||||
// _6 = &'17s (_2.0: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>);
|
||||
// StorageLive(_7);
|
||||
// StorageLive(_8);
|
||||
// StorageLive(_9);
|
||||
// _9 = &'35_0rs _2;
|
||||
// _8 = &'35_0rs (*_9);
|
||||
// _7 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _8,);
|
||||
// _9 = &'36_0rs _2;
|
||||
// _8 = &'36_0rs (*_9);
|
||||
// _7 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _8,);
|
||||
// StorageDead(_8);
|
||||
// _5 = const <std::cell::Cell<T>>::set(move _6, move _7) -> [return: bb5, unwind: bb3];
|
||||
// }
|
||||
// bb5: {
|
||||
// EndRegion('16s);
|
||||
// EndRegion('17s);
|
||||
// StorageDead(_7);
|
||||
// StorageDead(_6);
|
||||
// StorageDead(_9);
|
||||
|
|
@ -108,7 +108,7 @@ fn query() -> bool { true }
|
|||
// bb7: {
|
||||
// _0 = ();
|
||||
// StorageDead(_11);
|
||||
// EndRegion('35_0rs);
|
||||
// EndRegion('36_0rs);
|
||||
// StorageDead(_2);
|
||||
// return;
|
||||
// }
|
||||
|
|
@ -116,23 +116,23 @@ fn query() -> bool { true }
|
|||
// _10 = ();
|
||||
// StorageDead(_11);
|
||||
// StorageLive(_14);
|
||||
// _14 = &'33s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>);
|
||||
// _14 = &'34s (_2.0: std::cell::Cell<std::option::Option<&'36_0rs S<'36_0rs>>>);
|
||||
// StorageLive(_15);
|
||||
// StorageLive(_16);
|
||||
// StorageLive(_17);
|
||||
// _17 = &'35_0rs _2;
|
||||
// _16 = &'35_0rs (*_17);
|
||||
// _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _16,);
|
||||
// _17 = &'36_0rs _2;
|
||||
// _16 = &'36_0rs (*_17);
|
||||
// _15 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _16,);
|
||||
// StorageDead(_16);
|
||||
// _13 = const <std::cell::Cell<T>>::set(move _14, move _15) -> [return: bb9, unwind: bb3];
|
||||
// }
|
||||
// bb9: {
|
||||
// EndRegion('33s);
|
||||
// EndRegion('34s);
|
||||
// StorageDead(_15);
|
||||
// StorageDead(_14);
|
||||
// StorageDead(_17);
|
||||
// _1 = ();
|
||||
// EndRegion('35_0rs);
|
||||
// EndRegion('36_0rs);
|
||||
// StorageDead(_2);
|
||||
// goto -> bb1;
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -29,34 +29,46 @@ fn main() {
|
|||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.EraseRegions.after.mir
|
||||
// fn main() -> () {
|
||||
// ...
|
||||
// fn main() -> (){
|
||||
// let mut _0: ();
|
||||
// scope 1 {
|
||||
// let _1: Test;
|
||||
// scope 3 {
|
||||
// let _2: &ReErased Test;
|
||||
// }
|
||||
// scope 4 {
|
||||
// }
|
||||
// }
|
||||
// scope 2 {
|
||||
// }
|
||||
// let mut _3: ();
|
||||
// let mut _4: &ReErased i32;
|
||||
// let mut _5: &ReErased i32;
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = Test { x: const 0i32 };
|
||||
// StorageLive(_2);
|
||||
// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 }))), [_1: Test]);
|
||||
// Validate(Suspend(ReScope(Remainder(BlockRemainder { block: ItemLocalId(20), first_statement_index: 3 }))), [_1: Test]);
|
||||
// _2 = &ReErased _1;
|
||||
// Validate(Acquire, [(*_2): Test/ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })) (imm)]);
|
||||
// Validate(Acquire, [(*_2): Test/ReScope(Remainder(BlockRemainder { block: ItemLocalId(20), first_statement_index: 3 })) (imm)]);
|
||||
// StorageLive(_4);
|
||||
// StorageLive(_5);
|
||||
// Validate(Suspend(ReScope(Node(ItemLocalId(17)))), [((*_2).0: i32): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })) (imm)]);
|
||||
// Validate(Suspend(ReScope(Node(ItemLocalId(18)))), [((*_2).0: i32): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(20), first_statement_index: 3 })) (imm)]);
|
||||
// _5 = &ReErased ((*_2).0: i32);
|
||||
// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
|
||||
// Validate(Suspend(ReScope(Node(ItemLocalId(17)))), [(*_5): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
|
||||
// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(18))) (imm)]);
|
||||
// Validate(Suspend(ReScope(Node(ItemLocalId(18)))), [(*_5): i32/ReScope(Node(ItemLocalId(18))) (imm)]);
|
||||
// _4 = &ReErased (*_5);
|
||||
// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(17))) (imm)]);
|
||||
// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(17))) i32]);
|
||||
// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(18))) (imm)]);
|
||||
// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(18))) i32]);
|
||||
// _3 = const foo(move _4) -> bb1;
|
||||
// }
|
||||
// bb1: {
|
||||
// Validate(Acquire, [_3: ()]);
|
||||
// EndRegion(ReScope(Node(ItemLocalId(17))));
|
||||
// EndRegion(ReScope(Node(ItemLocalId(18))));
|
||||
// StorageDead(_4);
|
||||
// StorageDead(_5);
|
||||
// _0 = ();
|
||||
// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(19), first_statement_index: 3 })));
|
||||
// EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(20), first_statement_index: 3 })));
|
||||
// StorageDead(_2);
|
||||
// StorageDead(_1);
|
||||
// return;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ LL | let _ = x.foo; //~ ERROR E0609
|
|||
= note: available fields are: `x`
|
||||
|
||||
error[E0609]: no field `1` on type `Bar`
|
||||
--> $DIR/E0609.rs:21:5
|
||||
--> $DIR/E0609.rs:21:7
|
||||
|
|
||||
LL | y.1; //~ ERROR E0609
|
||||
| ^^^
|
||||
| ^ unknown field
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
error[E0611]: field `0` of tuple-struct `a::Foo` is private
|
||||
--> $DIR/E0611.rs:21:4
|
||||
|
|
||||
LL | y.0; //~ ERROR E0611
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0611`.
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
error[E0612]: attempted out-of-bounds tuple index `1` on type `Foo`
|
||||
--> $DIR/E0612.rs:15:4
|
||||
|
|
||||
LL | y.1; //~ ERROR E0612
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0612`.
|
||||
|
|
@ -18,5 +18,5 @@ mod a {
|
|||
|
||||
fn main() {
|
||||
let y = a::Foo::new();
|
||||
y.0; //~ ERROR E0611
|
||||
y.0; //~ ERROR field `0` of struct `a::Foo` is private
|
||||
}
|
||||
9
src/test/ui/error-codes/ex-E0611.stderr
Normal file
9
src/test/ui/error-codes/ex-E0611.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0616]: field `0` of struct `a::Foo` is private
|
||||
--> $DIR/ex-E0611.rs:21:4
|
||||
|
|
||||
LL | y.0; //~ ERROR field `0` of struct `a::Foo` is private
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0616`.
|
||||
|
|
@ -12,5 +12,5 @@ struct Foo(u32);
|
|||
|
||||
fn main() {
|
||||
let y = Foo(0);
|
||||
y.1; //~ ERROR E0612
|
||||
y.1; //~ ERROR no field `1` on type `Foo`
|
||||
}
|
||||
9
src/test/ui/error-codes/ex-E0612.stderr
Normal file
9
src/test/ui/error-codes/ex-E0612.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0609]: no field `1` on type `Foo`
|
||||
--> $DIR/ex-E0612.rs:15:6
|
||||
|
|
||||
LL | y.1; //~ ERROR no field `1` on type `Foo`
|
||||
| ^ did you mean `0`?
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
||||
25
src/test/ui/hygiene/assoc_item_ctxt.stderr
Normal file
25
src/test/ui/hygiene/assoc_item_ctxt.stderr
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
error[E0407]: method `method` is not a member of trait `Tr`
|
||||
--> $DIR/assoc_item_ctxt.rs:45:13
|
||||
|
|
||||
LL | fn method() {} //~ ERROR method `method` is not a member of trait `Tr`
|
||||
| ^^^^^^^^^^^^^^ not a member of trait `Tr`
|
||||
...
|
||||
LL | mac_trait_impl!();
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `method`
|
||||
--> $DIR/assoc_item_ctxt.rs:44:9
|
||||
|
|
||||
LL | fn method();
|
||||
| ------------ `method` from trait
|
||||
...
|
||||
LL | impl Tr for u8 { //~ ERROR not all trait items implemented, missing: `method`
|
||||
| ^^^^^^^^^^^^^^ missing `method` in implementation
|
||||
...
|
||||
LL | mac_trait_impl!();
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors occurred: E0046, E0407.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
8
src/test/ui/hygiene/assoc_ty_bindings.stderr
Normal file
8
src/test/ui/hygiene/assoc_ty_bindings.stderr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
error: compilation successful
|
||||
--> $DIR/assoc_ty_bindings.rs:49:1
|
||||
|
|
||||
LL | fn main() {} //~ ERROR compilation successful
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
32
src/test/ui/hygiene/fields-definition.rs
Normal file
32
src/test/ui/hygiene/fields-definition.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <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(decl_macro)]
|
||||
|
||||
macro modern($a: ident) {
|
||||
struct Modern {
|
||||
a: u8,
|
||||
$a: u8, // OK
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! legacy {
|
||||
($a: ident) => {
|
||||
struct Legacy {
|
||||
a: u8,
|
||||
$a: u8, //~ ERROR field `a` is already declared
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modern!(a);
|
||||
legacy!(a);
|
||||
|
||||
fn main() {}
|
||||
14
src/test/ui/hygiene/fields-definition.stderr
Normal file
14
src/test/ui/hygiene/fields-definition.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error[E0124]: field `a` is already declared
|
||||
--> $DIR/fields-definition.rs:24:17
|
||||
|
|
||||
LL | a: u8,
|
||||
| ----- `a` first declared here
|
||||
LL | $a: u8, //~ ERROR field `a` is already declared
|
||||
| ^^ field already declared
|
||||
...
|
||||
LL | legacy!(a);
|
||||
| ----------- in this macro invocation
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0124`.
|
||||
40
src/test/ui/hygiene/fields-move.rs
Normal file
40
src/test/ui/hygiene/fields-move.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <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.
|
||||
|
||||
// issue #46314
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NonCopy(String);
|
||||
|
||||
struct Foo {
|
||||
x: NonCopy,
|
||||
}
|
||||
|
||||
macro copy_modern($foo: ident) {
|
||||
$foo.x
|
||||
}
|
||||
|
||||
macro_rules! copy_legacy {
|
||||
($foo: ident) => {
|
||||
$foo.x //~ ERROR use of moved value: `foo.x`
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_two_copies(a: NonCopy, b: NonCopy) {
|
||||
println!("Got two copies: {:?}, {:?}", a, b);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo { x: NonCopy("foo".into()) };
|
||||
assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
|
||||
assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
|
||||
}
|
||||
39
src/test/ui/hygiene/fields-move.stderr
Normal file
39
src/test/ui/hygiene/fields-move.stderr
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
error[E0382]: use of moved value: `foo.x`
|
||||
--> $DIR/fields-move.rs:38:42
|
||||
|
|
||||
LL | $foo.x
|
||||
| ------ value moved here
|
||||
...
|
||||
LL | assert_two_copies(copy_modern!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
|
||||
| ^^^^^ value used here after move
|
||||
|
|
||||
= note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0382]: use of moved value: `foo.x`
|
||||
--> $DIR/fields-move.rs:28:9
|
||||
|
|
||||
LL | $foo.x
|
||||
| ------ value moved here
|
||||
...
|
||||
LL | $foo.x //~ ERROR use of moved value: `foo.x`
|
||||
| ^^^^^^ value used here after move
|
||||
...
|
||||
LL | assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
|
||||
| ----------------- in this macro invocation
|
||||
|
|
||||
= note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait
|
||||
|
||||
error[E0382]: use of moved value: `foo.x`
|
||||
--> $DIR/fields-move.rs:39:42
|
||||
|
|
||||
LL | $foo.x
|
||||
| ------ value moved here
|
||||
...
|
||||
LL | assert_two_copies(copy_legacy!(foo), foo.x); //~ ERROR use of moved value: `foo.x`
|
||||
| ^^^^^ value used here after move
|
||||
|
|
||||
= note: move occurs because `foo.x` has type `NonCopy`, which does not implement the `Copy` trait
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
18
src/test/ui/hygiene/fields-numeric-borrowck.rs
Normal file
18
src/test/ui/hygiene/fields-numeric-borrowck.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <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.
|
||||
|
||||
struct S(u8);
|
||||
|
||||
fn main() {
|
||||
let mut s = S(0);
|
||||
let borrow1 = &mut s.0;
|
||||
let S { 0: ref mut borrow2 } = s;
|
||||
//~^ ERROR cannot borrow `s.0` as mutable more than once at a time
|
||||
}
|
||||
14
src/test/ui/hygiene/fields-numeric-borrowck.stderr
Normal file
14
src/test/ui/hygiene/fields-numeric-borrowck.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
error[E0499]: cannot borrow `s.0` as mutable more than once at a time
|
||||
--> $DIR/fields-numeric-borrowck.rs:16:16
|
||||
|
|
||||
LL | let borrow1 = &mut s.0;
|
||||
| --- first mutable borrow occurs here
|
||||
LL | let S { 0: ref mut borrow2 } = s;
|
||||
| ^^^^^^^^^^^^^^^ second mutable borrow occurs here
|
||||
LL | //~^ ERROR cannot borrow `s.0` as mutable more than once at a time
|
||||
LL | }
|
||||
| - first borrow ends here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0499`.
|
||||
38
src/test/ui/hygiene/fields.stderr
Normal file
38
src/test/ui/hygiene/fields.stderr
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
error: type `foo::S` is private
|
||||
--> $DIR/fields.rs:25:17
|
||||
|
|
||||
LL | let s = S { x: 0 }; //~ ERROR type `foo::S` is private
|
||||
| ^^^^^^^^^^
|
||||
...
|
||||
LL | let s = foo::m!(S, x);
|
||||
| ------------- in this macro invocation
|
||||
|
||||
error: type `foo::S` is private
|
||||
--> $DIR/fields.rs:26:17
|
||||
|
|
||||
LL | let _ = s.x; //~ ERROR type `foo::S` is private
|
||||
| ^
|
||||
...
|
||||
LL | let s = foo::m!(S, x);
|
||||
| ------------- in this macro invocation
|
||||
|
||||
error: type `foo::T` is private
|
||||
--> $DIR/fields.rs:28:17
|
||||
|
|
||||
LL | let t = T(0); //~ ERROR type `foo::T` is private
|
||||
| ^^^^
|
||||
...
|
||||
LL | let s = foo::m!(S, x);
|
||||
| ------------- in this macro invocation
|
||||
|
||||
error: type `foo::T` is private
|
||||
--> $DIR/fields.rs:29:17
|
||||
|
|
||||
LL | let _ = t.0; //~ ERROR type `foo::T` is private
|
||||
| ^
|
||||
...
|
||||
LL | let s = foo::m!(S, x);
|
||||
| ------------- in this macro invocation
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
9
src/test/ui/hygiene/for-loop.stderr
Normal file
9
src/test/ui/hygiene/for-loop.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0425]: cannot find value `iter` in this scope
|
||||
--> $DIR/for-loop.rs:16:9
|
||||
|
|
||||
LL | iter.next(); //~ ERROR cannot find value `iter` in this scope
|
||||
| ^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
49
src/test/ui/hygiene/globs.stderr
Normal file
49
src/test/ui/hygiene/globs.stderr
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/globs.rs:32:9
|
||||
|
|
||||
LL | f(); //~ ERROR cannot find function `f` in this scope
|
||||
| ^ not found in this scope
|
||||
help: possible candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use foo::f;
|
||||
|
|
||||
LL | use foo::f;
|
||||
|
|
||||
LL | use foo::f;
|
||||
|
|
||||
|
||||
error[E0425]: cannot find function `g` in this scope
|
||||
--> $DIR/globs.rs:25:5
|
||||
|
|
||||
LL | g(); //~ ERROR cannot find function `g` in this scope
|
||||
| ^ not found in this scope
|
||||
...
|
||||
LL | / m! {
|
||||
LL | | use bar::*;
|
||||
LL | | g();
|
||||
LL | | f(); //~ ERROR cannot find function `f` in this scope
|
||||
LL | | }
|
||||
| |_____- in this macro invocation
|
||||
help: possible candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use bar::g;
|
||||
|
|
||||
LL | use foo::test2::test::g;
|
||||
|
|
||||
LL | use foo::test::g;
|
||||
|
|
||||
LL | use foo::test::g;
|
||||
|
|
||||
|
||||
error[E0425]: cannot find function `f` in this scope
|
||||
--> $DIR/globs.rs:64:17
|
||||
|
|
||||
LL | n!(f);
|
||||
| ------ in this macro invocation
|
||||
...
|
||||
LL | f //~ ERROR cannot find function `f` in this scope
|
||||
| ^ not found in this scope
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
11
src/test/ui/hygiene/impl_items.stderr
Normal file
11
src/test/ui/hygiene/impl_items.stderr
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
error: type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
|
||||
--> $DIR/impl_items.rs:22:23
|
||||
|
|
||||
LL | let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
|
||||
| ^
|
||||
...
|
||||
LL | foo::m!();
|
||||
| ---------- in this macro invocation
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
10
src/test/ui/hygiene/intercrate.stderr
Normal file
10
src/test/ui/hygiene/intercrate.stderr
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
error: type `fn() -> u32 {intercrate::foo::bar::f}` is private
|
||||
--> $DIR/intercrate.rs:22:16
|
||||
|
|
||||
LL | assert_eq!(intercrate::foo::m!(), 1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
9
src/test/ui/hygiene/nested_macro_privacy.stderr
Normal file
9
src/test/ui/hygiene/nested_macro_privacy.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0616]: field `i` of struct `foo::S` is private
|
||||
--> $DIR/nested_macro_privacy.rs:25:5
|
||||
|
|
||||
LL | S::default().i; //~ ERROR field `i` of struct `foo::S` is private
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0616`.
|
||||
30
src/test/ui/hygiene/no_implicit_prelude.stderr
Normal file
30
src/test/ui/hygiene/no_implicit_prelude.stderr
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
error[E0433]: failed to resolve. Use of undeclared type or module `Vec`
|
||||
--> $DIR/no_implicit_prelude.rs:21:9
|
||||
|
|
||||
LL | fn f() { ::bar::m!(); }
|
||||
| ------------ in this macro invocation
|
||||
...
|
||||
LL | Vec::new(); //~ ERROR failed to resolve
|
||||
| ^^^ Use of undeclared type or module `Vec`
|
||||
|
||||
error[E0601]: `main` function not found in crate `no_implicit_prelude`
|
||||
|
|
||||
= note: consider adding a `main` function to `$DIR/no_implicit_prelude.rs`
|
||||
|
||||
error[E0599]: no method named `clone` found for type `()` in the current scope
|
||||
--> $DIR/no_implicit_prelude.rs:22:12
|
||||
|
|
||||
LL | fn f() { ::bar::m!(); }
|
||||
| ------------ in this macro invocation
|
||||
...
|
||||
LL | ().clone() //~ ERROR no method named `clone` found
|
||||
| ^^^^^
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
||||
candidate #1: `use std::clone::Clone;`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors occurred: E0433, E0599, E0601.
|
||||
For more information about an error, try `rustc --explain E0433`.
|
||||
9
src/test/ui/hygiene/pattern-macro.stderr
Normal file
9
src/test/ui/hygiene/pattern-macro.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/pattern-macro.rs:15:5
|
||||
|
|
||||
LL | x + 1; //~ ERROR cannot find value `x` in this scope
|
||||
| ^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
9
src/test/ui/hygiene/privacy.stderr
Normal file
9
src/test/ui/hygiene/privacy.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0603]: function `f` is private
|
||||
--> $DIR/privacy.rs:26:9
|
||||
|
|
||||
LL | foo::f() //~ ERROR `f` is private
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0603`.
|
||||
16
src/test/ui/hygiene/trait_items.stderr
Normal file
16
src/test/ui/hygiene/trait_items.stderr
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
error[E0599]: no method named `f` found for type `()` in the current scope
|
||||
--> $DIR/trait_items.rs:27:24
|
||||
|
|
||||
LL | fn f() { ::baz::m!(); }
|
||||
| ------------ in this macro invocation
|
||||
...
|
||||
LL | pub macro m() { ().f() } //~ ERROR no method named `f` found for type `()` in the current scope
|
||||
| ^
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
||||
candidate #1: `use foo::T;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
|
|
@ -16,7 +16,7 @@ struct Verdict(Guilty, Option<FineDollars>);
|
|||
fn main() {
|
||||
let justice = Verdict(true, Some(2718));
|
||||
let _condemned = justice.00;
|
||||
//~^ ERROR invalid tuple or struct index
|
||||
//~^ ERROR no field `00` on type `Verdict`
|
||||
let _punishment = justice.001;
|
||||
//~^ ERROR invalid tuple or struct index
|
||||
//~^ ERROR no field `001` on type `Verdict`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
error: invalid tuple or struct index
|
||||
error[E0609]: no field `00` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:18:30
|
||||
|
|
||||
LL | let _condemned = justice.00;
|
||||
| ^^ help: try simplifying the index: `0`
|
||||
| ^^ did you mean `0`?
|
||||
|
||||
error: invalid tuple or struct index
|
||||
error[E0609]: no field `001` on type `Verdict`
|
||||
--> $DIR/issue-47073-zero-padded-tuple-struct-indices.rs:20:31
|
||||
|
|
||||
LL | let _punishment = justice.001;
|
||||
| ^^^ help: try simplifying the index: `1`
|
||||
| ^^^ unknown field
|
||||
|
|
||||
= note: available fields are: `0`, `1`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0609`.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ macro_rules! fake_field_stmt {
|
|||
|
||||
macro_rules! fake_anon_field_stmt {
|
||||
() => {
|
||||
(1).0 //~ ERROR no field
|
||||
(1).0 //~ ERROR doesn't have fields
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ macro_rules! fake_field_expr {
|
|||
|
||||
macro_rules! fake_anon_field_expr {
|
||||
() => {
|
||||
(1).0 //~ ERROR no field
|
||||
(1).0 //~ ERROR doesn't have fields
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ LL | 1.fake //~ ERROR doesn't have fields
|
|||
LL | fake_field_stmt!();
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
error[E0609]: no field `0` on type `{integer}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:27:11
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:27:15
|
||||
|
|
||||
LL | (1).0 //~ ERROR no field
|
||||
| ^^^^^
|
||||
LL | (1).0 //~ ERROR doesn't have fields
|
||||
| ^
|
||||
...
|
||||
LL | fake_anon_field_stmt!();
|
||||
| ------------------------ in this macro invocation
|
||||
|
|
@ -56,11 +56,11 @@ LL | 1.fake //~ ERROR doesn't have fields
|
|||
LL | let _ = fake_field_expr!();
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
error[E0609]: no field `0` on type `{integer}`
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:45:11
|
||||
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
|
||||
--> $DIR/macro-backtrace-invalid-internals.rs:45:15
|
||||
|
|
||||
LL | (1).0 //~ ERROR no field
|
||||
| ^^^^^
|
||||
LL | (1).0 //~ ERROR doesn't have fields
|
||||
| ^
|
||||
...
|
||||
LL | let _ = fake_anon_field_expr!();
|
||||
| ----------------------- in this macro invocation
|
||||
|
|
@ -80,5 +80,5 @@ LL | 2.0_f32.powi(2) //~ ERROR can't call method `powi` on ambiguous n
|
|||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
Some errors occurred: E0599, E0609, E0610, E0689.
|
||||
Some errors occurred: E0599, E0610, E0689.
|
||||
For more information about an error, try `rustc --explain E0599`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue