@@ -3538,22 +3538,19 @@ impl<'a> Parser<'a> {
35383538 lhs = self . parse_assoc_op_cast ( lhs, lhs_span, ExprKind :: Cast ) ?;
35393539 continue
35403540 } else if op == AssocOp :: Colon {
3541+ let maybe_path = self . could_ascription_be_path ( & lhs. node ) ;
3542+ let next_sp = self . span ;
3543+
35413544 lhs = match self . parse_assoc_op_cast ( lhs, lhs_span, ExprKind :: Type ) {
35423545 Ok ( lhs) => lhs,
35433546 Err ( mut err) => {
3544- err. span_label ( self . span ,
3545- "expecting a type here because of type ascription" ) ;
3546- let cm = self . sess . source_map ( ) ;
3547- let cur_pos = cm. lookup_char_pos ( self . span . lo ( ) ) ;
3548- let op_pos = cm. lookup_char_pos ( cur_op_span. hi ( ) ) ;
3549- if cur_pos. line != op_pos. line {
3550- err. span_suggestion (
3551- cur_op_span,
3552- "try using a semicolon" ,
3553- ";" . to_string ( ) ,
3554- Applicability :: MaybeIncorrect // speculative
3555- ) ;
3556- }
3547+ self . bad_type_ascription (
3548+ & mut err,
3549+ lhs_span,
3550+ cur_op_span,
3551+ next_sp,
3552+ maybe_path,
3553+ ) ;
35573554 return Err ( err) ;
35583555 }
35593556 } ;
@@ -3658,6 +3655,58 @@ impl<'a> Parser<'a> {
36583655 Ok ( lhs)
36593656 }
36603657
3658+ fn could_ascription_be_path ( & self , node : & ast:: ExprKind ) -> bool {
3659+ self . token . is_ident ( ) &&
3660+ if let ast:: ExprKind :: Path ( ..) = node { true } else { false } &&
3661+ !self . token . is_reserved_ident ( ) && // v `foo:bar(baz)`
3662+ self . look_ahead ( 1 , |t| t == & token:: OpenDelim ( token:: Paren ) ) ||
3663+ self . look_ahead ( 1 , |t| t == & token:: Lt ) && // `foo:bar<baz`
3664+ self . look_ahead ( 2 , |t| t. is_ident ( ) ) ||
3665+ self . look_ahead ( 1 , |t| t == & token:: Colon ) && // `foo:bar:baz`
3666+ self . look_ahead ( 2 , |t| t. is_ident ( ) ) ||
3667+ self . look_ahead ( 1 , |t| t == & token:: ModSep ) && // `foo:bar::baz`
3668+ self . look_ahead ( 2 , |t| t. is_ident ( ) )
3669+ }
3670+
3671+ fn bad_type_ascription (
3672+ & self ,
3673+ err : & mut DiagnosticBuilder < ' a > ,
3674+ lhs_span : Span ,
3675+ cur_op_span : Span ,
3676+ next_sp : Span ,
3677+ maybe_path : bool ,
3678+ ) {
3679+ err. span_label ( self . span , "expecting a type here because of type ascription" ) ;
3680+ let cm = self . sess . source_map ( ) ;
3681+ let next_pos = cm. lookup_char_pos ( next_sp. lo ( ) ) ;
3682+ let op_pos = cm. lookup_char_pos ( cur_op_span. hi ( ) ) ;
3683+ if op_pos. line != next_pos. line {
3684+ err. span_suggestion (
3685+ cur_op_span,
3686+ "try using a semicolon" ,
3687+ ";" . to_string ( ) ,
3688+ Applicability :: MaybeIncorrect ,
3689+ ) ;
3690+ } else {
3691+ if maybe_path {
3692+ err. span_suggestion (
3693+ cur_op_span,
3694+ "maybe you meant to write a path separator here" ,
3695+ "::" . to_string ( ) ,
3696+ Applicability :: MaybeIncorrect ,
3697+ ) ;
3698+ } else {
3699+ err. note ( "type ascription is a nightly-only feature that lets \
3700+ you annotate an expression with a type: `<expr>: <type>`") ;
3701+ err. span_note (
3702+ lhs_span,
3703+ "this expression expects an ascribed type after the colon" ,
3704+ ) ;
3705+ err. help ( "this might be indicative of a syntax error elsewhere" ) ;
3706+ }
3707+ }
3708+ }
3709+
36613710 fn parse_assoc_op_cast ( & mut self , lhs : P < Expr > , lhs_span : Span ,
36623711 expr_kind : fn ( P < Expr > , P < Ty > ) -> ExprKind )
36633712 -> PResult < ' a , P < Expr > > {
0 commit comments