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:
commit
f93aaf84cb
53 changed files with 657 additions and 829 deletions
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
35
src/test/compile-fail/issue-22933-1.rs
Normal file
35
src/test/compile-fail/issue-22933-1.rs
Normal 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
|
||||
21
src/test/compile-fail/issue-22933-2.rs
Normal file
21
src/test/compile-fail/issue-22933-2.rs
Normal 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() {}
|
||||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 () {}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
37
src/test/compile-fail/struct-pat-associated-path.rs
Normal file
37
src/test/compile-fail/struct-pat-associated-path.rs
Normal 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
|
||||
}
|
||||
}
|
||||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue