Skip to content

Commit c0b073b

Browse files
committed
simplify & improve parse_ty_tuple_or_parens
1 parent 25cd01b commit c0b073b

File tree

7 files changed

+107
-62
lines changed

7 files changed

+107
-62
lines changed

src/librustc_parse/parser/ty.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ impl<'a> Parser<'a> {
142142
} else {
143143
let path = self.parse_path(PathStyle::Type)?;
144144
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
145-
self.parse_remaining_bounds(lifetime_defs, path, lo, parse_plus)?
145+
self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
146146
}
147147
} else if self.eat_keyword(kw::Impl) {
148148
self.parse_impl_ty(&mut impl_dyn_multi)?
@@ -203,21 +203,12 @@ impl<'a> Parser<'a> {
203203
match ty.kind {
204204
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
205205
TyKind::Path(None, path) if maybe_bounds => {
206-
self.parse_remaining_bounds(Vec::new(), path, lo, true)
206+
self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
207207
}
208-
TyKind::TraitObject(mut bounds, TraitObjectSyntax::None)
208+
TyKind::TraitObject(bounds, TraitObjectSyntax::None)
209209
if maybe_bounds && bounds.len() == 1 && !trailing_plus =>
210210
{
211-
let path = match bounds.remove(0) {
212-
GenericBound::Trait(pt, ..) => pt.trait_ref.path,
213-
GenericBound::Outlives(..) => {
214-
return Err(self.struct_span_err(
215-
ty.span,
216-
"expected trait bound, not lifetime bound",
217-
));
218-
}
219-
};
220-
self.parse_remaining_bounds(Vec::new(), path, lo, true)
211+
self.parse_remaining_bounds(bounds, true)
221212
}
222213
// `(TYPE)`
223214
_ => Ok(TyKind::Paren(P(ty))),
@@ -227,18 +218,26 @@ impl<'a> Parser<'a> {
227218
}
228219
}
229220

230-
fn parse_remaining_bounds(
221+
fn parse_remaining_bounds_path(
231222
&mut self,
232223
generic_params: Vec<GenericParam>,
233224
path: ast::Path,
234225
lo: Span,
235226
parse_plus: bool,
236227
) -> PResult<'a, TyKind> {
237-
assert_ne!(self.token, token::Question);
238-
239228
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
240-
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
241-
if parse_plus {
229+
let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
230+
self.parse_remaining_bounds(bounds, parse_plus)
231+
}
232+
233+
/// Parse the remainder of a bare trait object type given an already parsed list.
234+
fn parse_remaining_bounds(
235+
&mut self,
236+
mut bounds: GenericBounds,
237+
plus: bool,
238+
) -> PResult<'a, TyKind> {
239+
assert_ne!(self.token, token::Question);
240+
if plus {
242241
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
243242
bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?);
244243
}
@@ -358,7 +357,7 @@ impl<'a> Parser<'a> {
358357
}))
359358
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
360359
// `Trait1 + Trait2 + 'a`
361-
self.parse_remaining_bounds(Vec::new(), path, lo, true)
360+
self.parse_remaining_bounds_path(Vec::new(), path, lo, true)
362361
} else {
363362
// Just a type path.
364363
Ok(TyKind::Path(None, path))

src/test/ui/parser/issue-68890-2.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
type X = (?'a) +;
1+
fn main() {}
2+
3+
type X<'a> = (?'a) +;
24
//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
3-
//~| ERROR expected trait bound, not lifetime bound
5+
//~| ERROR at least one trait is required for an object type
6+
//~| WARN trait objects without an explicit `dyn` are deprecated
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
error: `?` may only modify trait bounds, not lifetime bounds
2-
--> $DIR/issue-68890-2.rs:1:11
2+
--> $DIR/issue-68890-2.rs:3:15
33
|
4-
LL | type X = (?'a) +;
5-
| ^
4+
LL | type X<'a> = (?'a) +;
5+
| ^
66

7-
error: expected trait bound, not lifetime bound
8-
--> $DIR/issue-68890-2.rs:1:11
7+
warning: trait objects without an explicit `dyn` are deprecated
8+
--> $DIR/issue-68890-2.rs:3:14
99
|
10-
LL | type X = (?'a) +;
11-
| ^^^
10+
LL | type X<'a> = (?'a) +;
11+
| ^^^^^^^ help: use `dyn`: `dyn (?'a) +`
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/issue-68890-2.rs:3:14
17+
|
18+
LL | type X<'a> = (?'a) +;
19+
| ^^^^^^^
1220

1321
error: aborting due to 2 previous errors
1422

src/test/ui/parser/issue-68890.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
enum e{A((?'a a+?+l))}
22
//~^ ERROR `?` may only modify trait bounds, not lifetime bounds
33
//~| ERROR expected one of `)`, `+`, or `,`
4-
//~| ERROR expected trait bound, not lifetime bound
4+
//~| ERROR expected item, found `)`

src/test/ui/parser/issue-68890.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ error: expected one of `)`, `+`, or `,`, found `a`
1010
LL | enum e{A((?'a a+?+l))}
1111
| ^ expected one of `)`, `+`, or `,`
1212

13-
error: expected trait bound, not lifetime bound
14-
--> $DIR/issue-68890.rs:1:11
13+
error: expected item, found `)`
14+
--> $DIR/issue-68890.rs:1:21
1515
|
1616
LL | enum e{A((?'a a+?+l))}
17-
| ^^^
17+
| ^ expected item
1818

1919
error: aborting due to 3 previous errors
2020

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
trait Trait<'a> {}
22

3+
trait Obj {}
4+
35
fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {}
46

57
fn main() {
6-
let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
8+
let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
9+
//~^ ERROR `?Trait` is not permitted in trait object types
10+
//~| ERROR only auto traits can be used as additional traits
11+
//~| WARN trait objects without an explicit `dyn` are deprecated
12+
let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
713
//~^ ERROR `?Trait` is not permitted in trait object types
14+
//~| ERROR only auto traits can be used as additional traits
815
//~| WARN trait objects without an explicit `dyn` are deprecated
9-
let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
10-
//~^ WARN trait objects without an explicit `dyn` are deprecated
11-
let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
12-
//~^ ERROR use of undeclared lifetime name `'a`
13-
//~| ERROR `?Trait` is not permitted in trait object types
16+
let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
17+
//~^ ERROR `?Trait` is not permitted in trait object types
18+
//~| ERROR only auto traits can be used as additional traits
1419
//~| WARN trait objects without an explicit `dyn` are deprecated
1520
}
Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,74 @@
11
error: `?Trait` is not permitted in trait object types
2-
--> $DIR/trait-object-trait-parens.rs:6:25
2+
--> $DIR/trait-object-trait-parens.rs:8:24
33
|
4-
LL | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
5-
| ^^^^^^^^
4+
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
5+
| ^^^^^^^^
66

77
error: `?Trait` is not permitted in trait object types
8-
--> $DIR/trait-object-trait-parens.rs:11:47
8+
--> $DIR/trait-object-trait-parens.rs:12:17
99
|
10-
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
11-
| ^^^^^^^^
10+
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
11+
| ^^^^^^
12+
13+
error: `?Trait` is not permitted in trait object types
14+
--> $DIR/trait-object-trait-parens.rs:16:46
15+
|
16+
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
17+
| ^^^^^^^^
1218

1319
warning: trait objects without an explicit `dyn` are deprecated
14-
--> $DIR/trait-object-trait-parens.rs:6:16
20+
--> $DIR/trait-object-trait-parens.rs:8:16
1521
|
16-
LL | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>;
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Copy) + (?Sized) + (for<'a> Trait<'a>)`
22+
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)`
1824
|
1925
= note: `#[warn(bare_trait_objects)]` on by default
2026

2127
warning: trait objects without an explicit `dyn` are deprecated
22-
--> $DIR/trait-object-trait-parens.rs:9:16
28+
--> $DIR/trait-object-trait-parens.rs:12:16
2329
|
24-
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>;
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (?Sized) + (for<'a> Trait<'a>) + (Copy)`
30+
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (?Sized) + (for<'a> Trait<'a>) + (Obj)`
2632

2733
warning: trait objects without an explicit `dyn` are deprecated
28-
--> $DIR/trait-object-trait-parens.rs:11:16
34+
--> $DIR/trait-object-trait-parens.rs:16:16
35+
|
36+
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (for<'a> Trait<'a>) + (Obj) + (?Sized)`
38+
39+
error[E0225]: only auto traits can be used as additional traits in a trait object
40+
--> $DIR/trait-object-trait-parens.rs:8:35
41+
|
42+
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
43+
| ----- ^^^^^^^^^^^^^^^^^^^
44+
| | |
45+
| | additional non-auto trait
46+
| | trait alias used in trait object type (additional use)
47+
| first non-auto trait
48+
| trait alias used in trait object type (first use)
49+
50+
error[E0225]: only auto traits can be used as additional traits in a trait object
51+
--> $DIR/trait-object-trait-parens.rs:12:49
2952
|
30-
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn (for<'a> Trait<'a>) + (Copy) + (?Sized)`
53+
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
54+
| ------------------- ^^^^^
55+
| | |
56+
| | additional non-auto trait
57+
| | trait alias used in trait object type (additional use)
58+
| first non-auto trait
59+
| trait alias used in trait object type (first use)
3260

33-
error[E0261]: use of undeclared lifetime name `'a`
34-
--> $DIR/trait-object-trait-parens.rs:11:31
61+
error[E0225]: only auto traits can be used as additional traits in a trait object
62+
--> $DIR/trait-object-trait-parens.rs:16:38
3563
|
36-
LL | fn main() {
37-
| - help: consider introducing lifetime `'a` here: `<'a>`
38-
...
39-
LL | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>;
40-
| ^^ undeclared lifetime
64+
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
65+
| ----------------- ^^^^^
66+
| | |
67+
| | additional non-auto trait
68+
| | trait alias used in trait object type (additional use)
69+
| first non-auto trait
70+
| trait alias used in trait object type (first use)
4171

42-
error: aborting due to 3 previous errors
72+
error: aborting due to 6 previous errors
4373

44-
For more information about this error, try `rustc --explain E0261`.
74+
For more information about this error, try `rustc --explain E0225`.

0 commit comments

Comments
 (0)