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:
bors 2018-04-13 01:43:09 +00:00
commit defcfe7142
87 changed files with 759 additions and 676 deletions

View file

@ -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

View file

@ -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`.

View file

@ -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`.

View file

@ -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
}

View 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`.

View file

@ -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`
}

View 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`.

View file

@ -0,0 +1,52 @@
// Copyright 2017 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.
// ignore-pretty pretty-printing is unhygienic
#![feature(decl_macro)]
#![allow(unused)]
mod ok {
macro mac_trait_item($method: ident) {
fn $method();
}
trait Tr {
mac_trait_item!(method);
}
macro mac_trait_impl() {
impl Tr for u8 { // OK
fn method() {} // OK
}
}
mac_trait_impl!();
}
mod error {
macro mac_trait_item() {
fn method();
}
trait Tr {
mac_trait_item!();
}
macro mac_trait_impl() {
impl Tr for u8 { //~ ERROR not all trait items implemented, missing: `method`
fn method() {} //~ ERROR method `method` is not a member of trait `Tr`
}
}
mac_trait_impl!();
}
fn main() {}

View 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`.

View file

@ -0,0 +1,49 @@
// Copyright 2017 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.
// ignore-pretty pretty-printing is unhygienic
#![feature(decl_macro, associated_type_defaults)]
#![feature(rustc_attrs)]
trait Base {
type AssocTy;
fn f();
}
trait Derived: Base {
fn g();
}
macro mac() {
type A = Base<AssocTy = u8>;
type B = Derived<AssocTy = u8>;
impl Base for u8 {
type AssocTy = u8;
fn f() {
let _: Self::AssocTy;
}
}
impl Derived for u8 {
fn g() {
let _: Self::AssocTy;
}
}
fn h<T: Base, U: Derived>() {
let _: T::AssocTy;
let _: U::AssocTy;
}
}
mac!();
#[rustc_error]
fn main() {} //~ ERROR compilation successful

View 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

View file

@ -0,0 +1,21 @@
// Copyright 2017 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)]
pub mod foo {
pub use self::bar::m;
mod bar {
fn f() -> u32 { 1 }
pub macro m() {
f();
}
}
}

View 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() {}

View 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`.

View 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`
}

View 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`.

View 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
}

View 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`.

View file

@ -0,0 +1,40 @@
// Copyright 2017 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.
// ignore-pretty pretty-printing is unhygienic
#![feature(decl_macro)]
mod foo {
struct S { x: u32 }
struct T(u32);
pub macro m($S:ident, $x:ident) {{
struct $S {
$x: u32,
x: i32,
}
let s = S { x: 0 }; //~ ERROR type `foo::S` is private
let _ = s.x; //~ ERROR type `foo::S` is private
let t = T(0); //~ ERROR type `foo::T` is private
let _ = t.0; //~ ERROR type `foo::T` is private
let s = $S { $x: 0, x: 1 };
assert_eq!((s.$x, s.x), (0, 1));
s
}}
}
fn main() {
let s = foo::m!(S, x);
assert_eq!(s.x, 0);
}

View 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

View file

@ -0,0 +1,18 @@
// 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.
// for-loops are expanded in the front end, and use an `iter` ident in their expansion. Check that
// `iter` is not accessible inside the for loop.
fn main() {
for _ in 0..10 {
iter.next(); //~ ERROR cannot find value `iter` in this scope
}
}

View 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`.

View file

@ -0,0 +1,68 @@
// Copyright 2017 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)]
mod foo {
pub fn f() {}
}
mod bar {
pub fn g() {}
}
macro m($($t:tt)*) {
$($t)*
use foo::*;
f();
g(); //~ ERROR cannot find function `g` in this scope
}
fn main() {
m! {
use bar::*;
g();
f(); //~ ERROR cannot find function `f` in this scope
}
}
n!(f);
macro n($i:ident) {
mod foo {
pub fn $i() -> u32 { 0 }
pub fn f() {}
mod test {
use super::*;
fn g() {
let _: u32 = $i();
let _: () = f();
}
}
macro n($j:ident) {
mod test {
use super::*;
fn g() {
let _: u32 = $i();
let _: () = f();
$j();
}
}
}
n!(f);
mod test2 {
super::n! {
f //~ ERROR cannot find function `f` in this scope
}
}
}
}

View 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`.

View file

@ -0,0 +1,44 @@
// Copyright 2017 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.
// ignore-pretty pretty-printing is unhygienic
#![feature(decl_macro)]
mod foo {
struct S;
impl S {
fn f(&self) {}
}
pub macro m() {
let _: () = S.f(); //~ ERROR type `for<'r> fn(&'r foo::S) {foo::S::f}` is private
}
}
struct S;
macro m($f:ident) {
impl S {
fn f(&self) -> u32 { 0 }
fn $f(&self) -> i32 { 0 }
}
fn f() {
let _: u32 = S.f();
let _: i32 = S.$f();
}
}
m!(f);
fn main() {
let _: i32 = S.f();
foo::m!();
}

View 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

View file

@ -0,0 +1,23 @@
// Copyright 2017 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.
// ignore-pretty pretty-printing is unhygienic
// aux-build:intercrate.rs
// error-pattern:type `fn() -> u32 {intercrate::foo::bar::f}` is private
#![feature(decl_macro)]
extern crate intercrate;
fn main() {
assert_eq!(intercrate::foo::m!(), 1);
}

View 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

View file

@ -0,0 +1,27 @@
// Copyright 2017 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 n($foo:ident, $S:ident, $i:ident, $m:ident) {
mod $foo {
#[derive(Default)]
pub struct $S { $i: u32 }
pub macro $m($e:expr) { $e.$i }
}
}
n!(foo, S, i, m);
fn main() {
use foo::{S, m};
S::default().i; //~ ERROR field `i` of struct `foo::S` is private
m!(S::default()); // ok
}

View 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`.

View file

@ -0,0 +1,25 @@
// Copyright 2017 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)]
mod foo {
pub macro m() { Vec::new(); ().clone() }
fn f() { ::bar::m!(); }
}
#[no_implicit_prelude]
mod bar {
pub macro m() {
Vec::new(); //~ ERROR failed to resolve
().clone() //~ ERROR no method named `clone` found
}
fn f() { ::foo::m!(); }
}

View 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`.

View file

@ -0,0 +1,16 @@
// 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.
macro_rules! foo { () => ( x ) }
fn main() {
let foo!() = 2;
x + 1; //~ ERROR cannot find value `x` in this scope
}

View 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`.

View file

@ -0,0 +1,28 @@
// Copyright 2017 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)]
mod foo {
fn f() {}
pub macro m($e:expr) {
f();
self::f();
::foo::f();
$e
}
}
fn main() {
foo::m!(
foo::f() //~ ERROR `f` is private
);
}

View 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`.

View file

@ -0,0 +1,31 @@
// Copyright 2017 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)]
mod foo {
pub trait T {
fn f(&self) {}
}
impl T for () {}
}
mod bar {
use foo::*;
pub macro m() { ().f() }
fn f() { ::baz::m!(); }
}
mod baz {
pub macro m() { ().f() } //~ ERROR no method named `f` found for type `()` in the current scope
fn f() { ::bar::m!(); }
}
fn main() {}

View 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`.

View file

@ -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`
}

View file

@ -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`.

View file

@ -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
}
}

View file

@ -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`.