syntax: Relax path grammar

This commit is contained in:
Vadim Petrochenkov 2017-07-29 04:47:12 +03:00
parent 13d94d5fa8
commit 7d21f21f71
5 changed files with 20 additions and 32 deletions

View file

@ -84,7 +84,7 @@ pub enum PathStyle {
Expr, Expr,
/// In other contexts, notably in types, no ambiguity exists and paths can be written /// In other contexts, notably in types, no ambiguity exists and paths can be written
/// without the disambiguator, e.g. `x<y>` - unambiguously a path. /// without the disambiguator, e.g. `x<y>` - unambiguously a path.
/// Paths with disambiguators are rejected for now, but may be allowed in the future. /// Paths with disambiguators are still accepted, `x::<Y>` - unambiguously a path too.
Type, Type,
/// A path with generic arguments disallowed, e.g. `foo::bar::Baz`, used in imports, /// A path with generic arguments disallowed, e.g. `foo::bar::Baz`, used in imports,
/// visibilities or attributes. /// visibilities or attributes.
@ -1835,18 +1835,7 @@ impl<'a> Parser<'a> {
&& self.look_ahead(1, |t| is_args_start(t)) { && self.look_ahead(1, |t| is_args_start(t)) {
// Generic arguments are found - `<`, `(`, `::<` or `::(`. // Generic arguments are found - `<`, `(`, `::<` or `::(`.
let lo = self.span; let lo = self.span;
if self.eat(&token::ModSep) { self.eat(&token::ModSep);
// These errors are not strictly necessary and may be removed in the future.
if style == PathStyle::Type {
let mut err = self.diagnostic().struct_span_err(self.prev_span,
"unnecessary path disambiguator");
err.span_label(self.prev_span, "try removing `::`");
err.emit();
} else if self.token == token::OpenDelim(token::Paren) {
self.diagnostic().span_err(self.prev_span,
"`::` is not supported before parenthesized generic arguments")
}
}
let parameters = if self.eat_lt() { let parameters = if self.eat_lt() {
// `<'a, T, A = U>` // `<'a, T, A = U>`

View file

@ -19,15 +19,11 @@ fn main() {
//~^ ERROR parenthesized parameters may only be used with a trait //~^ ERROR parenthesized parameters may only be used with a trait
//~| WARN previously accepted //~| WARN previously accepted
macro_rules! pathexpr { let p = ::std::str::()::from_utf8(b"foo").unwrap();
($p:path) => { $p }
}
let p = pathexpr!(::std::str()::from_utf8)(b"foo").unwrap();
//~^ ERROR parenthesized parameters may only be used with a trait //~^ ERROR parenthesized parameters may only be used with a trait
//~| WARN previously accepted //~| WARN previously accepted
let p = pathexpr!(::std::str::from_utf8())(b"foo").unwrap(); let p = ::std::str::from_utf8::()(b"foo").unwrap();
//~^ ERROR parenthesized parameters may only be used with a trait //~^ ERROR parenthesized parameters may only be used with a trait
//~| WARN previously accepted //~| WARN previously accepted

View file

@ -8,16 +8,19 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// Unnecessary path disambiguator is ok
#![feature(rustc_attrs)]
#![allow(unused)]
struct Foo<T> { struct Foo<T> {
_a: T, _a: T,
} }
fn main() { fn f() {
let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>); let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
//~^ ERROR unnecessary path disambiguator
//~| NOTE try removing `::`
let g: Foo::<i32> = Foo { _a: 42 }; let g: Foo::<i32> = Foo { _a: 42 };
//~^ ERROR unnecessary path disambiguator
//~| NOTE try removing `::`
} }
#[rustc_error]
fn main() {} //~ ERROR compilation successful

View file

@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
// compile-flags: -Z parse-only // Test that parentheses form parses in expression paths.
// Test that parentheses form doesn't work in expression paths.
struct Bar<A,R> { struct Bar<A,R> {
f: A, r: R f: A, r: R
@ -21,10 +19,10 @@ impl<A,B> Bar<A,B> {
} }
fn bar() { fn bar() {
let b = Box::Bar::<isize,usize>::new(); // OK let b = Bar::<isize, usize>::new(); // OK
let b = Box::Bar::()::new(); let b = Bar::(isize, usize)::new(); // OK too (for the parser)
//~^ ERROR `::` is not supported before parenthesized generic arguments //~^ ERROR parenthesized parameters may only be used with a trait
} }
fn main() { } fn main() {}

View file

@ -24,4 +24,6 @@ fn main() {
//~^ ERROR field expressions may not have generic arguments //~^ ERROR field expressions may not have generic arguments
f.x::<>; f.x::<>;
//~^ ERROR field expressions may not have generic arguments //~^ ERROR field expressions may not have generic arguments
f.x::();
//~^ ERROR field expressions may not have generic arguments
} }