Rollup merge of #36206 - mcarton:35755, r=pnkfelix

Fix bad error message with `::<` in types

Fix #36116.

Before:
```rust
error: expected identifier, found `<`
  --> src/test/compile-fail/issue-36116.rs:16:52
   |
16 |     let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
   |                                                    ^

error: chained comparison operators require parentheses
  --> src/test/compile-fail/issue-36116.rs:16:52
   |
16 |     let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
   |                                                    ^^^^^^
   |
   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments

error: expected expression, found `)`
  --> src/test/compile-fail/issue-36116.rs:16:57
   |
16 |     let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
   |                                                         ^

error: expected identifier, found `<`
  --> src/test/compile-fail/issue-36116.rs:20:17
   |
20 |     let g: Foo::<i32> = Foo { _a: 42 };
   |                 ^

error: aborting due to 5 previous errors
```

After:
```rust
error: unexpected token: `::`
  --> src/test/compile-fail/issue-36116.rs:16:50
   |
16 |     let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
   |                                                  ^^
   |
   = help: use `<...>` instead of `::<...>` if you meant to specify type arguments

error: unexpected token: `::`
  --> src/test/compile-fail/issue-36116.rs:20:15
   |
20 |     let g: Foo::<i32> = Foo { _a: 42 };
   |               ^^
   |
   = help: use `<...>` instead of `::<...>` if you meant to specify type arguments

error: aborting due to 2 previous errors
```
This commit is contained in:
Guillaume Gomez 2016-10-28 17:05:47 +02:00 committed by GitHub
commit f02577d491
2 changed files with 34 additions and 0 deletions

View file

@ -1757,6 +1757,17 @@ pub fn parse_path_segments_without_colons(&mut self) -> PResult<'a, Vec<ast::Pat
// First, parse an identifier.
let identifier = self.parse_path_segment_ident()?;
if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
self.bump();
let prev_span = self.prev_span;
let mut err = self.diagnostic().struct_span_err(prev_span,
"unexpected token: `::`");
err.help(
"use `<...>` instead of `::<...>` if you meant to specify type arguments");
err.emit();
}
// Parse types, optionally.
let parameters = if self.eat_lt() {
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;

View file

@ -0,0 +1,23 @@
// 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 Foo<T> {
_a: T,
}
fn main() {
let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
//~^ ERROR unexpected token: `::`
//~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments
let g: Foo::<i32> = Foo { _a: 42 };
//~^ ERROR unexpected token: `::`
//~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments
}