Auto merge of #34365 - petrochenkov:deferr, r=eddyb

Some more pattern cleanup and bugfixing

The next part of https://github.com/rust-lang/rust/pull/34095

The most significant fixed mistake is definitions for partially resolved associated types not being updated after full resolution.
```
fn f<T: Fn()>(arg: T::Output) { .... } // <- the definition of T::Output was not updated in def_map
```
For this reason unstable associated types of stable traits, like `FnOnce::Output`, could be used in stable code when written in unqualified form. Now they are properly checked, this is a **[breaking-change]** (pretty minor one, but a crater run would be nice). The fix is not to use unstable library features in stable code, alternatively `FnOnce::Output` can be stabilized.

Besides that, paths in struct patterns and expressions `S::A { .. }` are now fully resolved as associated types. Such types cannot be identified as structs at the moment, i.e. the change doesn't make previously invalid code valid, but it improves error diagnostics.

Other changes: `Def::Err` is supported better (less chances for ICEs for erroneous code), some incorrect error messages are corrected, some duplicated error messages are not reported, ADT definitions are now available through constructor IDs, everything else is cleanup and code audit.

Fixes https://github.com/rust-lang/rust/issues/34209
Closes https://github.com/rust-lang/rust/issues/22933 (adds tests)

r? @eddyb
This commit is contained in:
bors 2016-07-09 15:16:21 -07:00 committed by GitHub
commit f93aaf84cb
53 changed files with 657 additions and 829 deletions

View file

@ -16,6 +16,5 @@ pub use use_from_trait_xc::Trait;
fn main() {
match () {
Trait { x: 42 } => () //~ ERROR expected variant, struct or type alias, found trait `Trait`
//~^ ERROR `Trait` does not name a struct or a struct variant
}
}

View file

@ -10,6 +10,7 @@
#![crate_name="lint_stability"]
#![crate_type = "lib"]
#![feature(staged_api)]
#![feature(associated_type_defaults)]
#![stable(feature = "lint_stability", since = "1.0.0")]
#[stable(feature = "test_feature", since = "1.0.0")]
@ -92,6 +93,15 @@ pub trait Trait {
fn trait_stable_text(&self) {}
}
#[stable(feature = "test_feature", since = "1.0.0")]
pub trait TraitWithAssociatedTypes {
#[unstable(feature = "test_feature", issue = "0")]
type TypeUnstable = u8;
#[stable(feature = "test_feature", since = "1.0.0")]
#[rustc_deprecated(since = "1.0.0", reason = "text")]
type TypeDeprecated = u8;
}
#[stable(feature = "test_feature", since = "1.0.0")]
impl Trait for MethodTester {}

View file

@ -31,12 +31,14 @@ fn main() {
Empty1 => () // Not an error, `Empty1` is interpreted as a new binding
}
match e3 {
E::Empty3 => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
E::Empty3 => ()
//~^ ERROR `E::Empty3` does not name a unit variant, unit struct or a constant
}
match xe1 {
XEmpty1 => () // Not an error, `XEmpty1` is interpreted as a new binding
}
match xe3 {
XE::XEmpty3 => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct
XE::XEmpty3 => ()
//~^ ERROR `XE::XEmpty3` does not name a unit variant, unit struct or a constant
}
}

View file

@ -16,7 +16,7 @@ pub struct GslResult {
impl GslResult {
pub fn new() -> GslResult {
Result { //~ ERROR: `Result` does not name a structure
Result { //~ ERROR: `Result` does not name a struct or a struct variant
val: 0f64,
err: 0f64
}

View file

@ -11,5 +11,5 @@
mod foo {}
fn main() {
let p = foo { x: () }; //~ ERROR `foo` does not name a structure
let p = foo { x: () }; //~ ERROR `foo` does not name a struct or a struct variant
}

View file

@ -15,6 +15,5 @@ enum Foo {
fn main() {
match Foo::Bar(1) {
Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo`
//~^ ERROR `Foo` does not name a struct or a struct variant
}
}

View file

@ -11,5 +11,5 @@
mod MyMod {}
fn main() {
let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a structure
let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a struct or a struct variant
}

View file

@ -0,0 +1,35 @@
// Copyright 2016 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(rustc_attrs)]
#![allow(warnings)]
struct CNFParser {
token: char,
}
impl CNFParser {
fn is_whitespace(c: char) -> bool {
c == ' ' || c == '\n'
}
fn consume_whitespace(&mut self) {
self.consume_while(&(CNFParser::is_whitespace))
}
fn consume_while(&mut self, p: &Fn(char) -> bool) {
while p(self.token) {
return
}
}
}
#[rustc_error]
fn main() {} //~ ERROR compilation successful

View file

@ -0,0 +1,21 @@
// Copyright 2016 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.
enum Delicious {
Pie = 0x1,
Apple = 0x2,
ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
//~^ ERROR constant evaluation error: unresolved path in constant expression
}
const FOO: [u32; u8::MIN as usize] = [];
//~^ ERROR array length constant evaluation error: unresolved path in constant expression
fn main() {}

View file

@ -12,6 +12,5 @@ fn main() {
match 'a' {
char{ch} => true
//~^ ERROR expected variant, struct or type alias, found builtin type `char`
//~| ERROR `char` does not name a struct or a struct variant
};
}

View file

@ -11,12 +11,10 @@
mod A {}
fn main() {
let u = A { x: 1 }; //~ ERROR `A` does not name a structure
let v = u32 { x: 1 }; //~ ERROR `u32` does not name a structure
let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant
let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant
match () {
A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A`
//~^ ERROR `A` does not name a struct or a struct variant
u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32
//~^ ERROR `u32` does not name a struct or a struct variant
}
}

View file

@ -18,7 +18,7 @@ enum Enum {
fn main() {
let x = Foo(1);
Foo { ..x }; //~ ERROR `Foo` does not name a structure
Foo { ..x }; //~ ERROR `Foo` does not name a struct or a struct variant
let Foo { .. } = x; //~ ERROR `Foo` does not name a struct
let x = Bar;

View file

@ -18,7 +18,7 @@ struct S;
fn main() {
match Foo::Baz {
Foo::Bar => {}
//~^ ERROR `Foo::Bar` does not name a tuple variant or a tuple struct
//~^ ERROR `Foo::Bar` does not name a unit variant, unit struct or a constant
_ => {}
}

View file

@ -8,13 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum Foo { B(u32) }
enum S {
A,
}
fn bar(foo: Foo) -> u32 {
match foo {
Foo::B { i } => i, //~ ERROR E0163
fn bug(l: S) {
match l {
S::B{ } => { },
//~^ ERROR ambiguous associated type; specify the type using the syntax `<S as Trait>::B`
}
}
fn main() {
}
fn main () {}

View file

@ -11,5 +11,5 @@
struct NonCopyable(());
fn main() {
let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a structure
let z = NonCopyable{ p: () }; //~ ERROR `NonCopyable` does not name a struct or a struct variant
}

View file

@ -10,7 +10,7 @@
struct T { i: i32 }
fn f<T>() {
let t = T { i: 0 }; //~ ERROR `T` does not name a structure
let t = T { i: 0 }; //~ ERROR `T` does not name a struct or a struct variant
}
mod Foo {

View file

@ -128,6 +128,11 @@ mod cross_crate {
<Foo>::trait_stable_text(&foo);
<Foo as Trait>::trait_stable_text(&foo);
struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
//~^ ERROR use of unstable library feature
struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
//~^ ERROR use of deprecated item
let _ = DeprecatedStruct { //~ ERROR use of deprecated item
i: 0 //~ ERROR use of deprecated item
};

View file

@ -22,12 +22,13 @@ impl MyTrait for Foo {}
fn main() {
match 0u32 {
Foo::bar => {} //~ ERROR E0327
Foo::bar => {} //~ ERROR `Foo::bar` does not name a unit variant, unit struct or a constant
}
match 0u32 {
<Foo>::bar => {} //~ ERROR E0327
<Foo>::bar => {} //~ ERROR `bar` does not name a unit variant, unit struct or a constant
}
match 0u32 {
<Foo>::trait_bar => {} //~ ERROR E0327
<Foo>::trait_bar => {}
//~^ ERROR `trait_bar` does not name a unit variant, unit struct or a constant
}
}

View file

@ -27,7 +27,8 @@ impl S {
fn main() {
match 10 {
<S as Tr>::A::f::<u8> => {} //~ ERROR associated items in match patterns must be constants
<S as Tr>::A::f::<u8> => {}
//~^ ERROR `Tr::A::f<u8>` does not name a unit variant, unit struct or a constant
0 ... <S as Tr>::A::f::<u8> => {} //~ ERROR only char and numeric types are allowed in range
}
}

View file

@ -0,0 +1,37 @@
// Copyright 2016 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;
trait Tr {
type A;
}
impl Tr for S {
type A = S;
}
fn f<T: Tr>() {
match S {
T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant
}
}
fn g<T: Tr<A = S>>() {
match S {
T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant
}
}
fn main() {
match S {
S::A {} => {} //~ ERROR ambiguous associated type
}
}

View file

@ -12,5 +12,5 @@ trait TraitNotAStruct {}
fn main() {
TraitNotAStruct{ value: 0 };
//~^ ERROR: `TraitNotAStruct` does not name a structure [E0071]
//~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071]
}