Skip to content

Commit ba3ae46

Browse files
committed
trait-object-lifetime-parens: improve recovery.
1 parent d1822b3 commit ba3ae46

File tree

5 files changed

+40
-33
lines changed

5 files changed

+40
-33
lines changed

src/librustc_parse/parser/ty.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,14 @@ impl<'a> Parser<'a> {
148148
self.parse_impl_ty(&mut impl_dyn_multi)?
149149
} else if self.is_explicit_dyn_type() {
150150
self.parse_dyn_ty(&mut impl_dyn_multi)?
151-
} else if self.check(&token::Question)
152-
|| self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus())
153-
{
154-
// Bound list (trait object type)
155-
let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
156-
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
157151
} else if self.eat_lt() {
158152
// Qualified path
159153
let (qself, path) = self.parse_qpath(PathStyle::Type)?;
160154
TyKind::Path(Some(qself), path)
161155
} else if self.check_path() {
162156
self.parse_path_start_ty(lo, allow_plus)?
157+
} else if self.can_begin_bound() {
158+
self.parse_bare_trait_object(lo, allow_plus)?
163159
} else if self.eat(&token::DotDotDot) {
164160
if allow_c_variadic == AllowCVariadic::Yes {
165161
TyKind::CVarArgs
@@ -218,6 +214,15 @@ impl<'a> Parser<'a> {
218214
}
219215
}
220216

217+
fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
218+
let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
219+
let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
220+
if lt_no_plus {
221+
self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`").emit()
222+
}
223+
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
224+
}
225+
221226
fn parse_remaining_bounds_path(
222227
&mut self,
223228
generic_params: Vec<GenericParam>,

src/test/ui/parser/macro/trait-object-macro-matcher.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
// `ty` matcher in particular doesn't accept a single lifetime
33

44
macro_rules! m {
5-
($t: ty) => ( let _: $t; )
5+
($t: ty) => {
6+
let _: $t;
7+
};
68
}
79

810
fn main() {
9-
m!('static); //~ ERROR expected type, found `'static`
11+
m!('static);
12+
//~^ ERROR lifetime in trait object type must be followed by `+`
13+
//~| ERROR at least one trait is required for an object type
14+
//~| WARN trait objects without an explicit `dyn` are deprecated
1015
}
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
error: expected type, found `'static`
2-
--> $DIR/trait-object-macro-matcher.rs:9:8
1+
error: lifetime in trait object type must be followed by `+`
2+
--> $DIR/trait-object-macro-matcher.rs:11:8
33
|
44
LL | m!('static);
5-
| ^^^^^^^ expected type
5+
| ^^^^^^^
66

7-
error: aborting due to previous error
7+
warning: trait objects without an explicit `dyn` are deprecated
8+
--> $DIR/trait-object-macro-matcher.rs:11:8
9+
|
10+
LL | m!('static);
11+
| ^^^^^^^ help: use `dyn`: `dyn 'static`
12+
|
13+
= note: `#[warn(bare_trait_objects)]` on by default
14+
15+
error[E0224]: at least one trait is required for an object type
16+
--> $DIR/trait-object-macro-matcher.rs:11:8
17+
|
18+
LL | m!('static);
19+
| ^^^^^^^
20+
21+
error: aborting due to 2 previous errors
822

src/test/ui/parser/trait-object-lifetime-parens.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@ fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not s
66

77
fn check<'a>() {
88
let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
9-
let _: Box<('a) + Trait>;
10-
//~^ ERROR expected type, found `'a`
11-
//~| ERROR expected `while`, `for`, `loop` or `{` after a label
12-
//~| ERROR expected expression, found `)`
9+
let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+`
1310
}
1411

1512
fn main() {}

src/test/ui/parser/trait-object-lifetime-parens.stderr

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,11 @@ error: parenthesized lifetime bounds are not supported
1010
LL | let _: Box<Trait + ('a)>;
1111
| ^^^^ help: remove the parentheses
1212

13-
error: expected `while`, `for`, `loop` or `{` after a label
14-
--> $DIR/trait-object-lifetime-parens.rs:9:19
15-
|
16-
LL | let _: Box<('a) + Trait>;
17-
| ^ expected `while`, `for`, `loop` or `{` after a label
18-
19-
error: expected expression, found `)`
20-
--> $DIR/trait-object-lifetime-parens.rs:9:19
21-
|
22-
LL | let _: Box<('a) + Trait>;
23-
| ^ expected expression
24-
25-
error: expected type, found `'a`
13+
error: lifetime in trait object type must be followed by `+`
2614
--> $DIR/trait-object-lifetime-parens.rs:9:17
2715
|
2816
LL | let _: Box<('a) + Trait>;
29-
| - ^^ expected type
30-
| |
31-
| while parsing the type for `_`
17+
| ^^
3218

33-
error: aborting due to 5 previous errors
19+
error: aborting due to 3 previous errors
3420

0 commit comments

Comments
 (0)