1
Fork 0

trait-object-lifetime-parens: improve recovery.

This commit is contained in:
Mazdak Farrokhzad 2020-03-07 13:52:55 +01:00
parent d1822b3dcf
commit ba3ae46de9
5 changed files with 40 additions and 33 deletions

View file

@ -148,18 +148,14 @@ impl<'a> Parser<'a> {
self.parse_impl_ty(&mut impl_dyn_multi)?
} else if self.is_explicit_dyn_type() {
self.parse_dyn_ty(&mut impl_dyn_multi)?
} else if self.check(&token::Question)
|| self.check_lifetime() && self.look_ahead(1, |t| t.is_like_plus())
{
// Bound list (trait object type)
let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
} else if self.eat_lt() {
// Qualified path
let (qself, path) = self.parse_qpath(PathStyle::Type)?;
TyKind::Path(Some(qself), path)
} else if self.check_path() {
self.parse_path_start_ty(lo, allow_plus)?
} else if self.can_begin_bound() {
self.parse_bare_trait_object(lo, allow_plus)?
} else if self.eat(&token::DotDotDot) {
if allow_c_variadic == AllowCVariadic::Yes {
TyKind::CVarArgs
@ -218,6 +214,15 @@ impl<'a> Parser<'a> {
}
}
fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> {
let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus());
let bounds = self.parse_generic_bounds_common(allow_plus, None)?;
if lt_no_plus {
self.struct_span_err(lo, "lifetime in trait object type must be followed by `+`").emit()
}
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
}
fn parse_remaining_bounds_path(
&mut self,
generic_params: Vec<GenericParam>,

View file

@ -2,9 +2,14 @@
// `ty` matcher in particular doesn't accept a single lifetime
macro_rules! m {
($t: ty) => ( let _: $t; )
($t: ty) => {
let _: $t;
};
}
fn main() {
m!('static); //~ ERROR expected type, found `'static`
m!('static);
//~^ ERROR lifetime in trait object type must be followed by `+`
//~| ERROR at least one trait is required for an object type
//~| WARN trait objects without an explicit `dyn` are deprecated
}

View file

@ -1,8 +1,22 @@
error: expected type, found `'static`
--> $DIR/trait-object-macro-matcher.rs:9:8
error: lifetime in trait object type must be followed by `+`
--> $DIR/trait-object-macro-matcher.rs:11:8
|
LL | m!('static);
| ^^^^^^^ expected type
| ^^^^^^^
error: aborting due to previous error
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-macro-matcher.rs:11:8
|
LL | m!('static);
| ^^^^^^^ help: use `dyn`: `dyn 'static`
|
= note: `#[warn(bare_trait_objects)]` on by default
error[E0224]: at least one trait is required for an object type
--> $DIR/trait-object-macro-matcher.rs:11:8
|
LL | m!('static);
| ^^^^^^^
error: aborting due to 2 previous errors

View file

@ -6,10 +6,7 @@ fn f<'a, T: Trait + ('a)>() {} //~ ERROR parenthesized lifetime bounds are not s
fn check<'a>() {
let _: Box<Trait + ('a)>; //~ ERROR parenthesized lifetime bounds are not supported
let _: Box<('a) + Trait>;
//~^ ERROR expected type, found `'a`
//~| ERROR expected `while`, `for`, `loop` or `{` after a label
//~| ERROR expected expression, found `)`
let _: Box<('a) + Trait>; //~ ERROR lifetime in trait object type must be followed by `+`
}
fn main() {}

View file

@ -10,25 +10,11 @@ error: parenthesized lifetime bounds are not supported
LL | let _: Box<Trait + ('a)>;
| ^^^^ help: remove the parentheses
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/trait-object-lifetime-parens.rs:9:19
|
LL | let _: Box<('a) + Trait>;
| ^ expected `while`, `for`, `loop` or `{` after a label
error: expected expression, found `)`
--> $DIR/trait-object-lifetime-parens.rs:9:19
|
LL | let _: Box<('a) + Trait>;
| ^ expected expression
error: expected type, found `'a`
error: lifetime in trait object type must be followed by `+`
--> $DIR/trait-object-lifetime-parens.rs:9:17
|
LL | let _: Box<('a) + Trait>;
| - ^^ expected type
| |
| while parsing the type for `_`
| ^^
error: aborting due to 5 previous errors
error: aborting due to 3 previous errors