@@ -100,13 +100,31 @@ impl<'a> Parser<'a> {
100
100
} else if self . check_ident ( ) {
101
101
// Parse type parameter.
102
102
params. push ( self . parse_ty_param ( attrs) ?) ;
103
+ } else if self . token . can_begin_type ( ) {
104
+ // Trying to write an associated type bound? (#26271)
105
+ let snapshot = self . clone ( ) ;
106
+ match self . parse_ty_where_predicate ( ) {
107
+ Ok ( where_predicate) => {
108
+ self . struct_span_err (
109
+ where_predicate. span ( ) ,
110
+ "bounds on associated types do not belong here" ,
111
+ )
112
+ . span_label ( where_predicate. span ( ) , "belongs in `where` clause" )
113
+ . emit ( ) ;
114
+ }
115
+ Err ( mut err) => {
116
+ err. cancel ( ) ;
117
+ std:: mem:: replace ( self , snapshot) ;
118
+ break
119
+ }
120
+ }
103
121
} else {
104
122
// Check for trailing attributes and stop parsing.
105
123
if !attrs. is_empty ( ) {
106
124
if !params. is_empty ( ) {
107
125
self . struct_span_err (
108
126
attrs[ 0 ] . span ,
109
- & format ! ( "trailing attribute after generic parameter" ) ,
127
+ "trailing attribute after generic parameter" ,
110
128
)
111
129
. span_label ( attrs[ 0 ] . span , "attributes must go before parameters" )
112
130
. emit ( ) ;
@@ -202,43 +220,7 @@ impl<'a> Parser<'a> {
202
220
}
203
221
) ) ;
204
222
} else if self . check_type ( ) {
205
- // Parse optional `for<'a, 'b>`.
206
- // This `for` is parsed greedily and applies to the whole predicate,
207
- // the bounded type can have its own `for` applying only to it.
208
- // Examples:
209
- // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
210
- // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
211
- // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
212
- let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
213
-
214
- // Parse type with mandatory colon and (possibly empty) bounds,
215
- // or with mandatory equality sign and the second type.
216
- let ty = self . parse_ty ( ) ?;
217
- if self . eat ( & token:: Colon ) {
218
- let bounds = self . parse_generic_bounds ( Some ( self . prev_span ) ) ?;
219
- where_clause. predicates . push ( ast:: WherePredicate :: BoundPredicate (
220
- ast:: WhereBoundPredicate {
221
- span : lo. to ( self . prev_span ) ,
222
- bound_generic_params : lifetime_defs,
223
- bounded_ty : ty,
224
- bounds,
225
- }
226
- ) ) ;
227
- // FIXME: Decide what should be used here, `=` or `==`.
228
- // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
229
- } else if self . eat ( & token:: Eq ) || self . eat ( & token:: EqEq ) {
230
- let rhs_ty = self . parse_ty ( ) ?;
231
- where_clause. predicates . push ( ast:: WherePredicate :: EqPredicate (
232
- ast:: WhereEqPredicate {
233
- span : lo. to ( self . prev_span ) ,
234
- lhs_ty : ty,
235
- rhs_ty,
236
- id : ast:: DUMMY_NODE_ID ,
237
- }
238
- ) ) ;
239
- } else {
240
- return self . unexpected ( ) ;
241
- }
223
+ where_clause. predicates . push ( self . parse_ty_where_predicate ( ) ?) ;
242
224
} else {
243
225
break
244
226
}
@@ -252,6 +234,47 @@ impl<'a> Parser<'a> {
252
234
Ok ( where_clause)
253
235
}
254
236
237
+ fn parse_ty_where_predicate ( & mut self ) -> PResult < ' a , ast:: WherePredicate > {
238
+ let lo = self . token . span ;
239
+ // Parse optional `for<'a, 'b>`.
240
+ // This `for` is parsed greedily and applies to the whole predicate,
241
+ // the bounded type can have its own `for` applying only to it.
242
+ // Examples:
243
+ // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
244
+ // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
245
+ // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
246
+ let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
247
+
248
+ // Parse type with mandatory colon and (possibly empty) bounds,
249
+ // or with mandatory equality sign and the second type.
250
+ let ty = self . parse_ty ( ) ?;
251
+ if self . eat ( & token:: Colon ) {
252
+ let bounds = self . parse_generic_bounds ( Some ( self . prev_span ) ) ?;
253
+ Ok ( ast:: WherePredicate :: BoundPredicate (
254
+ ast:: WhereBoundPredicate {
255
+ span : lo. to ( self . prev_span ) ,
256
+ bound_generic_params : lifetime_defs,
257
+ bounded_ty : ty,
258
+ bounds,
259
+ }
260
+ ) )
261
+ // FIXME: Decide what should be used here, `=` or `==`.
262
+ // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
263
+ } else if self . eat ( & token:: Eq ) || self . eat ( & token:: EqEq ) {
264
+ let rhs_ty = self . parse_ty ( ) ?;
265
+ Ok ( ast:: WherePredicate :: EqPredicate (
266
+ ast:: WhereEqPredicate {
267
+ span : lo. to ( self . prev_span ) ,
268
+ lhs_ty : ty,
269
+ rhs_ty,
270
+ id : ast:: DUMMY_NODE_ID ,
271
+ }
272
+ ) )
273
+ } else {
274
+ self . unexpected ( )
275
+ }
276
+ }
277
+
255
278
pub ( super ) fn choose_generics_over_qpath ( & self ) -> bool {
256
279
// There's an ambiguity between generic parameters and qualified paths in impls.
257
280
// If we see `<` it may start both, so we have to inspect some following tokens.
0 commit comments