@@ -145,21 +145,18 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
145
145
( $self: expr, $allow_qpath_recovery: expr) => {
146
146
if $allow_qpath_recovery
147
147
&& $self. may_recover( )
148
- && $self. look_ahead( 1 , |t| t == & token:: PathSep )
149
- && let token:: Interpolated ( nt) = & $self. token. kind
150
- && let token:: NtTy ( ty) = & nt. 0
148
+ && let Some ( token:: NonterminalKind :: Ty ) = $self. token. is_metavar_seq( )
149
+ && $self. check_noexpect_past_close_delim( & token:: PathSep )
151
150
{
152
- let ty = ty. clone( ) ;
153
- $self. bump( ) ;
151
+ // Reparse the type, then move to recovery.
152
+ let ty = crate :: reparse_metavar_seq!(
153
+ $self,
154
+ token:: NonterminalKind :: Ty ,
155
+ super :: ParseNtResult :: Ty ( ty) ,
156
+ ty
157
+ ) ;
154
158
return $self. maybe_recover_from_bad_qpath_stage_2( $self. prev_token. span, ty) ;
155
159
}
156
- if $allow_qpath_recovery
157
- && $self. may_recover( )
158
- && $self. look_ahead( 1 , |t| t == & token:: PathSep )
159
- && let token:: OpenDelim ( Delimiter :: Invisible ( _) ) = & $self. token. kind
160
- {
161
- panic!( "njn: invis-delim?" ) ;
162
- }
163
160
} ;
164
161
}
165
162
@@ -619,6 +616,24 @@ impl<'a> Parser<'a> {
619
616
self . token == * tok
620
617
}
621
618
619
+ // Check the first token after the delimiter that closes the current
620
+ // delimited sequence. (Panics if used in the outermost token stream, which
621
+ // has no delimiters.) It uses a clone of the relevant tree cursor to skip
622
+ // past the entire `TokenTree::Delimited` in a single step, avoiding the
623
+ // need for unbounded token lookahead.
624
+ //
625
+ // Primarily used when `self.token` matches
626
+ // `OpenDelim(Delimiter::Invisible(_))`, to look ahead through the current
627
+ // metavar expansion.
628
+ fn check_noexpect_past_close_delim ( & self , tok : & TokenKind ) -> bool {
629
+ let mut tree_cursor = self . token_cursor . stack . last ( ) . unwrap ( ) . 0 . clone ( ) ;
630
+ let tt = tree_cursor. next_ref ( ) ;
631
+ matches ! (
632
+ tt,
633
+ Some ( ast:: tokenstream:: TokenTree :: Token ( token:: Token { kind, .. } , _) ) if kind == tok
634
+ )
635
+ }
636
+
622
637
/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
623
638
///
624
639
/// the main purpose of this function is to reduce the cluttering of the suggestions list
@@ -1664,6 +1679,7 @@ pub enum FlatToken {
1664
1679
#[ derive( Clone , Debug ) ]
1665
1680
pub enum ParseNtResult < NtType > {
1666
1681
Tt ( TokenTree ) ,
1682
+ Ty ( P < ast:: Ty > ) ,
1667
1683
Vis ( P < ast:: Visibility > ) ,
1668
1684
1669
1685
/// This variant will eventually be removed, along with `Token::Interpolate`.
@@ -1677,6 +1693,7 @@ impl<T> ParseNtResult<T> {
1677
1693
{
1678
1694
match self {
1679
1695
ParseNtResult :: Tt ( tt) => ParseNtResult :: Tt ( tt) ,
1696
+ ParseNtResult :: Ty ( x) => ParseNtResult :: Ty ( x) ,
1680
1697
ParseNtResult :: Vis ( x) => ParseNtResult :: Vis ( x) ,
1681
1698
ParseNtResult :: Nt ( nt) => ParseNtResult :: Nt ( f ( nt) ) ,
1682
1699
}
0 commit comments