@@ -100,13 +100,31 @@ impl<'a> Parser<'a> {
100100 } else if self . check_ident ( ) {
101101 // Parse type parameter.
102102 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+ }
103121 } else {
104122 // Check for trailing attributes and stop parsing.
105123 if !attrs. is_empty ( ) {
106124 if !params. is_empty ( ) {
107125 self . struct_span_err (
108126 attrs[ 0 ] . span ,
109- & format ! ( "trailing attribute after generic parameter" ) ,
127+ "trailing attribute after generic parameter" ,
110128 )
111129 . span_label ( attrs[ 0 ] . span , "attributes must go before parameters" )
112130 . emit ( ) ;
@@ -202,43 +220,7 @@ impl<'a> Parser<'a> {
202220 }
203221 ) ) ;
204222 } 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 ( ) ?) ;
242224 } else {
243225 break
244226 }
@@ -252,6 +234,47 @@ impl<'a> Parser<'a> {
252234 Ok ( where_clause)
253235 }
254236
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+
255278 pub ( super ) fn choose_generics_over_qpath ( & self ) -> bool {
256279 // There's an ambiguity between generic parameters and qualified paths in impls.
257280 // If we see `<` it may start both, so we have to inspect some following tokens.
0 commit comments