@@ -145,21 +145,18 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
145145 ( $self: expr, $allow_qpath_recovery: expr) => {
146146 if $allow_qpath_recovery
147147 && $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 )
151150 {
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+ ) ;
154158 return $self. maybe_recover_from_bad_qpath_stage_2( $self. prev_token. span, ty) ;
155159 }
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- }
163160 } ;
164161}
165162
@@ -619,6 +616,24 @@ impl<'a> Parser<'a> {
619616 self . token == * tok
620617 }
621618
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+
622637 /// Consumes a token 'tok' if it exists. Returns whether the given token was present.
623638 ///
624639 /// the main purpose of this function is to reduce the cluttering of the suggestions list
@@ -1664,6 +1679,7 @@ pub enum FlatToken {
16641679#[ derive( Clone , Debug ) ]
16651680pub enum ParseNtResult < NtType > {
16661681 Tt ( TokenTree ) ,
1682+ Ty ( P < ast:: Ty > ) ,
16671683 Vis ( P < ast:: Visibility > ) ,
16681684
16691685 /// This variant will eventually be removed, along with `Token::Interpolate`.
@@ -1677,6 +1693,7 @@ impl<T> ParseNtResult<T> {
16771693 {
16781694 match self {
16791695 ParseNtResult :: Tt ( tt) => ParseNtResult :: Tt ( tt) ,
1696+ ParseNtResult :: Ty ( x) => ParseNtResult :: Ty ( x) ,
16801697 ParseNtResult :: Vis ( x) => ParseNtResult :: Vis ( x) ,
16811698 ParseNtResult :: Nt ( nt) => ParseNtResult :: Nt ( f ( nt) ) ,
16821699 }
0 commit comments