simplify & improve parse_ty_tuple_or_parens

This commit is contained in:
Mazdak Farrokhzad 2020-03-07 12:54:31 +01:00
parent 25cd01b863
commit c0b073bc62
7 changed files with 107 additions and 62 deletions

View File

@ -142,7 +142,7 @@ impl<'a> Parser<'a> {
} else {
let path = self.parse_path(PathStyle::Type)?;
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
}
} else if self.eat_keyword(kw::Impl) {
self.parse_impl_ty(&mut impl_dyn_multi)?
@ -203,21 +203,12 @@ impl<'a> Parser<'a> {
match ty.kind {
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
TyKind::Path(None, path) if maybe_bounds => {
self.parse_remaining_bounds(Vec::new(), path, lo, true)
self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
}
TyKind::TraitObject(mut bounds, TraitObjectSyntax::None)
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
{
let path = match bounds.remove(0) {
GenericBound::Trait(pt, ..) => pt.trait_ref.path,
GenericBound::Outlives(..) => {
return Err(self.struct_span_err(
ty.span,
"expected trait bound, not lifetime bound",
));
}
};
self.parse_remaining_bounds(Vec::new(), path, lo, true)
self.parse_remaining_bounds(bounds, true)
}
// `(TYPE)`
_ => Ok(TyKind::Paren(P(ty))),
@ -227,18 +218,26 @@ impl<'a> Parser<'a> {
}
}
fn parse_remaining_bounds(
fn parse_remaining_bounds_path(
&mut self,
generic_params: Vec<GenericParam>,
path: ast::Path,
lo: Span,
parse_plus: bool,
) -> PResult<'a, TyKind> {
assert_ne!(self.token, token::Question);
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
if parse_plus {
let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
self.parse_remaining_bounds(bounds, parse_plus)
}
/// Parse the remainder of a bare trait object type given an already parsed list.
fn parse_remaining_bounds(
&mut self,
mut bounds: GenericBounds,
plus: bool,
) -> PResult<'a, TyKind> {
assert_ne!(self.token, token::Question);
if plus {
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?);
}
@ -358,7 +357,7 @@ impl<'a> Parser<'a> {
}))
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
// `Trait1 + Trait2 + 'a`
self.parse_remaining_bounds(Vec::new(), path, lo, true)
self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
} else {
// Just a type path.
Ok(TyKind::Path(None, path))

View File

@ -1,3 +1,6 @@
type X = (?'a) +;
fn main() {}
type X<'a> = (?'a) +;
//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
//~| ERROR expected trait bound, not lifetime bound
//~| ERROR at least one trait is required for an object type
//~| WARN trait objects without an explicit `dyn` are deprecated

View File

@ -1,14 +1,22 @@
error: `?` may only modify trait bounds, not lifetime bounds
--> $DIR/issue-68890-2.rs:1:11
--> $DIR/issue-68890-2.rs:3:15
|
LL | type X = (?'a) +;
| ^
LL | type X<'a> = (?'a) +;
| ^
error: expected trait bound, not lifetime bound
--> $DIR/issue-68890-2.rs:1:11
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-68890-2.rs:3:14
|
LL | type X = (?'a) +;
| ^^^
LL | type X<'a> = (?'a) +;
| ^^^^^^^ help: use `dyn`: `dyn (?'a) +`
|
= note: `#[warn(bare_trait_objects)]` on by default
error[E0224]: at least one trait is required for an object type
--> $DIR/issue-68890-2.rs:3:14
|
LL | type X<'a> = (?'a) +;
| ^^^^^^^
error: aborting due to 2 previous errors

View File

@ -1,4 +1,4 @@
enum e{A((?'a a+?+l))}
//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
//~| ERROR expected one of `)`, `+`, or `,`
//~| ERROR expected trait bound, not lifetime bound
//~| ERROR expected item, found `)`

View File

@ -10,11 +10,11 @@ error: expected one of `)`, `+`, or `,`, found `a`
LL | enum e{A((?'a a+?+l))}
| ^ expected one of `)`, `+`, or `,`
error: expected trait bound, not lifetime bound
--> $DIR/issue-68890.rs:1:11
error: expected item, found `)`
--> $DIR/issue-68890.rs:1:21
|
LL | enum e{A((?'a a+?+l))}
| ^^^
| ^ expected item
error: aborting due to 3 previous errors

View File

@ -1,15 +1,20 @@
trait Trait<'a> {}
trait Obj {}
fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {}
fn main() {
let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
//~^ WARN trait objects without an explicit `dyn` are deprecated
let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
//~^ ERROR use of undeclared lifetime name `'a`
//~| ERROR `?Trait` is not permitted in trait object types
let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
}

View File

@ -1,44 +1,74 @@
error: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:6:25
--> $DIR/trait-object-trait-parens.rs:8:24
|
LL | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^
error: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:11:47
--> $DIR/trait-object-trait-parens.rs:12:17
|
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
| ^^^^^^^^
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
| ^^^^^^
error: `?Trait` is not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:16:46
|
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
| ^^^^^^^^
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-trait-parens.rs:6:16
--> $DIR/trait-object-trait-parens.rs:8:16
|
LL | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Copy) + (?Sized) + (for<'a> Trait<'a>)`
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)`
|
= note: `#[warn(bare_trait_objects)]` on by default
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-trait-parens.rs:9:16
--> $DIR/trait-object-trait-parens.rs:12:16
|
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (?Sized) + (for<'a> Trait<'a>) + (Copy)`
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (?Sized) + (for<'a> Trait<'a>) + (Obj)`
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-trait-parens.rs:11:16
--> $DIR/trait-object-trait-parens.rs:16:16
|
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (for<'a> Trait<'a>) + (Copy) + (?Sized)`
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (for<'a> Trait<'a>) + (Obj) + (?Sized)`
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/trait-object-trait-parens.rs:11:31
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:8:35
|
LL | fn main() {
| - help: consider introducing lifetime `'a` here: `<'a>`
...
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
| ^^ undeclared lifetime
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| ----- ^^^^^^^^^^^^^^^^^^^
| | |
| | additional non-auto trait
| | trait alias used in trait object type (additional use)
| first non-auto trait
| trait alias used in trait object type (first use)
error: aborting due to 3 previous errors
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:12:49
|
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
| ------------------- ^^^^^
| | |
| | additional non-auto trait
| | trait alias used in trait object type (additional use)
| first non-auto trait
| trait alias used in trait object type (first use)
For more information about this error, try `rustc --explain E0261`.
error[E0225]: only auto traits can be used as additional traits in a trait object
--> $DIR/trait-object-trait-parens.rs:16:38
|
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
| ----------------- ^^^^^
| | |
| | additional non-auto trait
| | trait alias used in trait object type (additional use)
| first non-auto trait
| trait alias used in trait object type (first use)
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0225`.