Skip to content

Commit

Permalink
Issue warnings for unnecessary path disambiguators
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Aug 10, 2017
1 parent 7d21f21 commit 804459b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
4 changes: 1 addition & 3 deletions src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,9 +599,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
panic!(FatalError)
}
},
"path" => {
token::NtPath(panictry!(p.parse_path(PathStyle::Type)))
},
"path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
"vis" => token::NtVis(panictry!(p.parse_visibility(true))),
// this is not supposed to happen, since it has been checked
Expand Down
28 changes: 18 additions & 10 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,7 @@ impl<'a> Parser<'a> {
self.expect(&token::ModSep)?;

let qself = QSelf { ty, position: path.segments.len() };
self.parse_path_segments(&mut path.segments, style)?;
self.parse_path_segments(&mut path.segments, style, true)?;

Ok((qself, ast::Path { segments: path.segments, span: lo.to(self.prev_span) }))
}
Expand All @@ -1770,16 +1770,20 @@ impl<'a> Parser<'a> {
/// `a::b::C::<D>` (with disambiguator)
/// `Fn(Args)` (without disambiguator)
/// `Fn::(Args)` (with disambiguator)
pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path>
{
pub fn parse_path(&mut self, style: PathStyle) -> PResult<'a, ast::Path> {
self.parse_path_common(style, true)
}

pub fn parse_path_common(&mut self, style: PathStyle, enable_warning: bool)
-> PResult<'a, ast::Path> {
maybe_whole!(self, NtPath, |x| x);

let lo = self.meta_var_span.unwrap_or(self.span);
let mut segments = Vec::new();
if self.eat(&token::ModSep) {
segments.push(PathSegment::crate_root(lo));
}
self.parse_path_segments(&mut segments, style)?;
self.parse_path_segments(&mut segments, style, enable_warning)?;

Ok(ast::Path { segments, span: lo.to(self.prev_span) })
}
Expand All @@ -1804,18 +1808,19 @@ impl<'a> Parser<'a> {
self.parse_path(style)
}

fn parse_path_segments(&mut self, segments: &mut Vec<PathSegment>, style: PathStyle)
-> PResult<'a, ()> {
fn parse_path_segments(&mut self, segments: &mut Vec<PathSegment>, style: PathStyle,
enable_warning: bool) -> PResult<'a, ()> {
loop {
segments.push(self.parse_path_segment(style)?);
segments.push(self.parse_path_segment(style, enable_warning)?);

if self.is_import_coupler() || !self.eat(&token::ModSep) {
return Ok(());
}
}
}

fn parse_path_segment(&mut self, style: PathStyle) -> PResult<'a, PathSegment> {
fn parse_path_segment(&mut self, style: PathStyle, enable_warning: bool)
-> PResult<'a, PathSegment> {
let ident_span = self.span;
let ident = self.parse_path_segment_ident()?;

Expand All @@ -1835,7 +1840,10 @@ impl<'a> Parser<'a> {
&& self.look_ahead(1, |t| is_args_start(t)) {
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
let lo = self.span;
self.eat(&token::ModSep);
if self.eat(&token::ModSep) && style == PathStyle::Type && enable_warning {
self.diagnostic().struct_span_warn(self.prev_span, "unnecessary path disambiguator")
.span_label(self.prev_span, "try removing `::`").emit();
}

let parameters = if self.eat_lt() {
// `<'a, T, A = U>`
Expand Down Expand Up @@ -2371,7 +2379,7 @@ impl<'a> Parser<'a> {

// Assuming we have just parsed `.`, continue parsing into an expression.
fn parse_dot_suffix(&mut self, self_arg: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
let segment = self.parse_path_segment(PathStyle::Expr)?;
let segment = self.parse_path_segment(PathStyle::Expr, true)?;
Ok(match self.token {
token::OpenDelim(token::Paren) => {
// Method call `expr.f()`
Expand Down
15 changes: 13 additions & 2 deletions src/test/compile-fail/issue-36116.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,24 @@
#![feature(rustc_attrs)]
#![allow(unused)]

macro_rules! m {
($p: path) => {
let _ = $p(0);
let _: $p;
}
}

struct Foo<T> {
_a: T,
}

struct S<T>(T);

fn f() {
let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
let g: Foo::<i32> = Foo { _a: 42 };
let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>); //~ WARN unnecessary path disambiguator
let g: Foo::<i32> = Foo { _a: 42 }; //~ WARN unnecessary path disambiguator

m!(S::<u8>); // OK, no warning
}

#[rustc_error]
Expand Down

0 comments on commit 804459b

Please sign in to comment.