@@ -585,12 +585,51 @@ impl<'a> Parser<'a> {
585
585
let early_return = vec ! [ token:: Eof ] ;
586
586
self . consume_tts ( 1 , & modifiers[ ..] , & early_return[ ..] ) ;
587
587
588
- if self . token . kind != token:: OpenDelim ( token:: Paren ) {
589
- // We don't have `foo< bar >(`, so we rewind the parser and bail out.
588
+ if !& [
589
+ token:: OpenDelim ( token:: Paren ) ,
590
+ token:: ModSep ,
591
+ ] . contains ( & self . token . kind ) {
592
+ // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the
593
+ // parser and bail out.
590
594
mem:: replace ( self , snapshot. clone ( ) ) ;
591
595
}
592
596
}
593
- if self . token . kind == token:: OpenDelim ( token:: Paren ) {
597
+ if token:: ModSep == self . token . kind {
598
+ // We have some certainty that this was a bad turbofish at this point.
599
+ // `foo< bar >::`
600
+ err. span_suggestion (
601
+ op_span. shrink_to_lo ( ) ,
602
+ msg,
603
+ "::" . to_string ( ) ,
604
+ Applicability :: MaybeIncorrect ,
605
+ ) ;
606
+
607
+ let snapshot = self . clone ( ) ;
608
+
609
+ self . bump ( ) ; // `::`
610
+ // Consume the rest of the likely `foo<bar>::new()` or return at `foo<bar>`.
611
+ match self . parse_expr ( ) {
612
+ Ok ( _) => {
613
+ // 99% certain that the suggestion is correct, continue parsing.
614
+ err. emit ( ) ;
615
+ // FIXME: actually check that the two expressions in the binop are
616
+ // paths and resynthesize new fn call expression instead of using
617
+ // `ExprKind::Err` placeholder.
618
+ return Ok ( Some ( self . mk_expr (
619
+ lhs. span . to ( self . prev_span ) ,
620
+ ExprKind :: Err ,
621
+ ThinVec :: new ( ) ,
622
+ ) ) ) ;
623
+ }
624
+ Err ( mut err) => {
625
+ err. cancel ( ) ;
626
+ // Not entirely sure now, but we bubble the error up with the
627
+ // suggestion.
628
+ mem:: replace ( self , snapshot) ;
629
+ return Err ( err) ;
630
+ }
631
+ }
632
+ } else if token:: OpenDelim ( token:: Paren ) == self . token . kind {
594
633
// We have high certainty that this was a bad turbofish at this point.
595
634
// `foo< bar >(`
596
635
err. span_suggestion (
@@ -601,14 +640,14 @@ impl<'a> Parser<'a> {
601
640
) ;
602
641
603
642
let snapshot = self . clone ( ) ;
643
+ self . bump ( ) ; // `(`
604
644
605
645
// Consume the fn call arguments.
606
646
let modifiers = vec ! [
607
647
( token:: OpenDelim ( token:: Paren ) , 1 ) ,
608
648
( token:: CloseDelim ( token:: Paren ) , -1 ) ,
609
649
] ;
610
650
let early_return = vec ! [ token:: Eof ] ;
611
- self . bump ( ) ; // `(`
612
651
self . consume_tts ( 1 , & modifiers[ ..] , & early_return[ ..] ) ;
613
652
614
653
if self . token . kind == token:: Eof {
0 commit comments