@@ -4,6 +4,7 @@ use crate::maybe_whole;
4
4
use rustc_ast:: ast:: { self , AngleBracketedArg , AngleBracketedArgs , GenericArg , ParenthesizedArgs } ;
5
5
use rustc_ast:: ast:: { AnonConst , AssocTyConstraint , AssocTyConstraintKind , BlockCheckMode } ;
6
6
use rustc_ast:: ast:: { Ident , Path , PathSegment , QSelf } ;
7
+ use rustc_ast:: ptr:: P ;
7
8
use rustc_ast:: token:: { self , Token } ;
8
9
use rustc_errors:: { pluralize, Applicability , PResult } ;
9
10
use rustc_span:: source_map:: { BytePos , Span } ;
@@ -405,7 +406,8 @@ impl<'a> Parser<'a> {
405
406
let lo = self . token . span ;
406
407
let ident = self . parse_ident ( ) ?;
407
408
let kind = if self . eat ( & token:: Eq ) {
408
- AssocTyConstraintKind :: Equality { ty : self . parse_ty ( ) ? }
409
+ let ty = self . parse_assoc_equality_term ( ident, self . prev_token . span ) ?;
410
+ AssocTyConstraintKind :: Equality { ty }
409
411
} else if self . eat ( & token:: Colon ) {
410
412
let bounds = self . parse_generic_bounds ( Some ( self . prev_token . span ) ) ?;
411
413
AssocTyConstraintKind :: Bound { bounds }
@@ -427,6 +429,46 @@ impl<'a> Parser<'a> {
427
429
}
428
430
}
429
431
432
+ /// Parse the term to the right of an associated item equality constraint.
433
+ /// That is, parse `<term>` in `Item = <term>`.
434
+ /// Right now, this only admits types in `<term>`.
435
+ fn parse_assoc_equality_term ( & mut self , ident : Ident , eq : Span ) -> PResult < ' a , P < ast:: Ty > > {
436
+ let arg = self . parse_generic_arg ( ) ?;
437
+ let span = ident. span . to ( self . prev_token . span ) ;
438
+ match arg {
439
+ Some ( GenericArg :: Type ( ty) ) => return Ok ( ty) ,
440
+ Some ( GenericArg :: Const ( expr) ) => {
441
+ self . struct_span_err ( span, "cannot constrain an associated constant to a value" )
442
+ . span_label ( ident. span , "the value constrains this associated constant" )
443
+ . span_label ( expr. value . span , "the value is given in this expression" )
444
+ . emit ( ) ;
445
+ }
446
+ Some ( GenericArg :: Lifetime ( lt) ) => {
447
+ self . struct_span_err ( span, "associated lifetimes are not supported" )
448
+ . span_label ( lt. ident . span , "the lifetime is given here" )
449
+ . help ( "if you meant to specify a trait object, write `dyn Trait + 'lifetime`" )
450
+ . emit ( ) ;
451
+ }
452
+ None => {
453
+ self . struct_span_err ( span, "missing type to the right of `=`" )
454
+ . span_suggestion (
455
+ span,
456
+ "to constrain the associated type, add a type after `=`" ,
457
+ format ! ( "{} = TheType" , ident) ,
458
+ Applicability :: HasPlaceholders ,
459
+ )
460
+ . span_suggestion (
461
+ eq,
462
+ & format ! ( "remove the `=` if `{}` is a type" , ident) ,
463
+ String :: new ( ) ,
464
+ Applicability :: MaybeIncorrect ,
465
+ )
466
+ . emit ( ) ;
467
+ }
468
+ }
469
+ Ok ( self . mk_ty ( span, ast:: TyKind :: Err ) )
470
+ }
471
+
430
472
/// Parse a generic argument in a path segment.
431
473
/// This does not include constraints, e.g., `Item = u8`, which is handled in `parse_angle_arg`.
432
474
fn parse_generic_arg ( & mut self ) -> PResult < ' a , Option < GenericArg > > {
0 commit comments