Auto merge of #33794 - petrochenkov:sanity, r=nrc
Add AST validation pass and move some checks to it The purpose of this pass is to catch constructions that fit into AST data structures, but not permitted by the language. As an example, `impl`s don't have visibilities, but for convenience and uniformity with other items they are represented with a structure `Item` which has `Visibility` field. This pass is intended to run after expansion of macros and syntax extensions (and before lowering to HIR), so it can catch erroneous constructions that were generated by them. This pass allows to remove ad hoc semantic checks from the parser, which can be overruled by syntax extensions and occasionally macros. The checks can be put here if they are simple, local, don't require results of any complex analysis like name resolution or type checking and maybe don't logically fall into other passes. I expect most of errors generated by this pass to be non-fatal and allowing the compilation to proceed. I intend to move some more checks to this pass later and maybe extend it with new checks, like, for example, identifier validity. Given that syntax extensions are going to be stabilized in the measurable future, it's important that they would not be able to subvert usual language rules. In this patch I've added two new checks - a check for labels named `'static` and a check for lifetimes and labels named `'_`. The first one gives a hard error, the second one - a future compatibility warning. Fixes https://github.com/rust-lang/rust/issues/33059 ([breaking-change]) cc https://github.com/rust-lang/rfcs/pull/1177 r? @nrc
This commit is contained in:
commit
c2cab1fd58
21 changed files with 318 additions and 220 deletions
|
|
@ -21,5 +21,5 @@ enum Foo {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 })
|
||||
println!("{}", match Bar { Bar => 1, Baz => 2, Bazar => 3 }) //~ ERROR unresolved name `Bar`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ mod a {
|
|||
struct A;
|
||||
|
||||
impl Default for A {
|
||||
pub fn default() -> A {
|
||||
pub fn default() -> A { //~ ERROR unnecessary visibility qualifier
|
||||
A;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
src/test/compile-fail/label-static.rs
Normal file
15
src/test/compile-fail/label-static.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// 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.
|
||||
|
||||
fn main() {
|
||||
'static: loop { //~ ERROR invalid label name `'static`
|
||||
break 'static //~ ERROR invalid label name `'static`
|
||||
}
|
||||
}
|
||||
27
src/test/compile-fail/lifetime-underscore.rs
Normal file
27
src/test/compile-fail/lifetime-underscore.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// 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.
|
||||
|
||||
#![deny(lifetime_underscore)]
|
||||
|
||||
fn _f<'_>() //~ ERROR invalid lifetime name `'_`
|
||||
//~^ WARN this was previously accepted
|
||||
-> &'_ u8 //~ ERROR invalid lifetime name `'_`
|
||||
//~^ WARN this was previously accepted
|
||||
{
|
||||
panic!();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
'_: loop { //~ ERROR invalid label name `'_`
|
||||
//~^ WARN this was previously accepted
|
||||
break '_ //~ ERROR invalid label name `'_`
|
||||
//~^ WARN this was previously accepted
|
||||
}
|
||||
}
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub extern {
|
||||
//~^ ERROR unnecessary visibility
|
||||
pub extern { //~ ERROR unnecessary visibility qualifier
|
||||
pub fn bar();
|
||||
}
|
||||
|
||||
|
|
@ -19,10 +18,10 @@ trait A {
|
|||
|
||||
struct B;
|
||||
|
||||
pub impl B {} //~ ERROR: unnecessary visibility
|
||||
pub impl B {} //~ ERROR unnecessary visibility qualifier
|
||||
|
||||
pub impl A for B { //~ ERROR: unnecessary visibility
|
||||
pub fn foo(&self) {} //~ ERROR: unnecessary visibility
|
||||
pub impl A for B { //~ ERROR unnecessary visibility qualifier
|
||||
pub fn foo(&self) {} //~ ERROR unnecessary visibility qualifier
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ macro_rules! m {
|
|||
|
||||
struct S<T>(T);
|
||||
m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path
|
||||
//~^ ERROR failed to resolve module path. Not a module `S`
|
||||
|
||||
mod foo {
|
||||
struct S(pub(foo<T>) ()); //~ ERROR type or lifetime parameters in visibility path
|
||||
//~^ ERROR type name `T` is undefined or not in scope
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,17 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(unused_imports, dead_code)]
|
||||
|
||||
struct S;
|
||||
struct Z;
|
||||
|
||||
mod foo {
|
||||
use ::super::{S, Z}; //~ WARN global paths cannot start with `super`
|
||||
//~^ WARN this was previously accepted by the compiler but is being phased out
|
||||
|
||||
pub fn g() {
|
||||
use ::super::main; //~ WARN expected identifier, found keyword `super`
|
||||
use ::super::main; //~ WARN global paths cannot start with `super`
|
||||
//~^ WARN this was previously accepted by the compiler but is being phased out
|
||||
main();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,14 +15,12 @@ pub trait E {
|
|||
}
|
||||
|
||||
impl E for A {
|
||||
pub fn foo(&self) {} //~ ERROR: unnecessary visibility
|
||||
pub fn foo(&self) {} //~ ERROR: unnecessary visibility qualifier
|
||||
}
|
||||
|
||||
enum Foo {
|
||||
V1 { pub f: i32 }, //~ ERROR unnecessary visibility qualifier
|
||||
//| NOTE visibility qualifiers have no effect on variant fields
|
||||
V2(pub i32), //~ ERROR unnecessary visibility qualifier
|
||||
//| NOTE visibility qualifiers have no effect on variant fields
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue