@@ -117,6 +117,11 @@ impl<'a> Parser<'a> {
117117 }
118118}
119119
120+ enum ReuseKind {
121+ Path ,
122+ Impl ,
123+ }
124+
120125impl < ' a > Parser < ' a > {
121126 pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < Box < Item > > > {
122127 let fn_parse_mode =
@@ -249,9 +254,9 @@ impl<'a> Parser<'a> {
249254 } else if self . check_keyword_case ( exp ! ( Trait ) , case) || self . check_trait_front_matter ( ) {
250255 // TRAIT ITEM
251256 self . parse_item_trait ( attrs, lo) ?
252- } else if self . check_impl_frontmatter ( ) {
257+ } else if self . check_impl_frontmatter ( 0 ) {
253258 // IMPL ITEM
254- self . parse_item_impl ( attrs, def_ ( ) ) ?
259+ self . parse_item_impl ( attrs, def_ ( ) , false ) ?
255260 } else if let Const :: Yes ( const_span) = self . parse_constness ( case) {
256261 // CONST ITEM
257262 self . recover_const_mut ( const_span) ;
@@ -265,8 +270,8 @@ impl<'a> Parser<'a> {
265270 rhs,
266271 define_opaque : None ,
267272 } ) )
268- } else if self . is_reuse_path_item ( ) {
269- self . parse_item_delegation ( ) ?
273+ } else if let Some ( kind ) = self . is_reuse_item ( ) {
274+ self . parse_item_delegation ( attrs , def_ ( ) , kind ) ?
270275 } else if self . check_keyword_case ( exp ! ( Mod ) , case)
271276 || self . check_keyword_case ( exp ! ( Unsafe ) , case) && self . is_keyword_ahead ( 1 , & [ kw:: Mod ] )
272277 {
@@ -367,16 +372,25 @@ impl<'a> Parser<'a> {
367372 /// When parsing a statement, would the start of a path be an item?
368373 pub ( super ) fn is_path_start_item ( & mut self ) -> bool {
369374 self . is_kw_followed_by_ident ( kw:: Union ) // no: `union::b`, yes: `union U { .. }`
370- || self . is_reuse_path_item ( )
375+ || self . is_reuse_item ( ) . is_some ( ) // yes: `reuse impl Trait for Struct { self.0 }`, yes: `reuse some_path::foo;`
371376 || self . check_trait_front_matter ( ) // no: `auto::b`, yes: `auto trait X { .. }`
372377 || self . is_async_fn ( ) // no(2015): `async::b`, yes: `async fn`
373378 || matches ! ( self . is_macro_rules_item( ) , IsMacroRulesItem :: Yes { ..} ) // no: `macro_rules::b`, yes: `macro_rules! mac`
374379 }
375380
376- fn is_reuse_path_item ( & mut self ) -> bool {
381+ fn is_reuse_item ( & mut self ) -> Option < ReuseKind > {
382+ if !self . token . is_keyword ( kw:: Reuse ) {
383+ return None ;
384+ }
385+
377386 // no: `reuse ::path` for compatibility reasons with macro invocations
378- self . token . is_keyword ( kw:: Reuse )
379- && self . look_ahead ( 1 , |t| t. is_path_start ( ) && * t != token:: PathSep )
387+ if self . look_ahead ( 1 , |t| t. is_path_start ( ) && * t != token:: PathSep ) {
388+ Some ( ReuseKind :: Path )
389+ } else if self . check_impl_frontmatter ( 1 ) {
390+ Some ( ReuseKind :: Impl )
391+ } else {
392+ None
393+ }
380394 }
381395
382396 /// Are we sure this could not possibly be a macro invocation?
@@ -560,6 +574,7 @@ impl<'a> Parser<'a> {
560574 & mut self ,
561575 attrs : & mut AttrVec ,
562576 defaultness : Defaultness ,
577+ is_reuse : bool ,
563578 ) -> PResult < ' a , ItemKind > {
564579 let mut constness = self . parse_constness ( Case :: Sensitive ) ;
565580 let safety = self . parse_safety ( Case :: Sensitive ) ;
@@ -628,7 +643,11 @@ impl<'a> Parser<'a> {
628643
629644 generics. where_clause = self . parse_where_clause ( ) ?;
630645
631- let impl_items = self . parse_item_list ( attrs, |p| p. parse_impl_item ( ForceCollect :: No ) ) ?;
646+ let impl_items = if is_reuse {
647+ Default :: default ( )
648+ } else {
649+ self . parse_item_list ( attrs, |p| p. parse_impl_item ( ForceCollect :: No ) ) ?
650+ } ;
632651
633652 let ( of_trait, self_ty) = match ty_second {
634653 Some ( ty_second) => {
@@ -699,10 +718,76 @@ impl<'a> Parser<'a> {
699718 Ok ( ItemKind :: Impl ( Impl { generics, of_trait, self_ty, items : impl_items, constness } ) )
700719 }
701720
702- fn parse_item_delegation ( & mut self ) -> PResult < ' a , ItemKind > {
721+ fn parse_item_delegation (
722+ & mut self ,
723+ attrs : & mut AttrVec ,
724+ defaultness : Defaultness ,
725+ kind : ReuseKind ,
726+ ) -> PResult < ' a , ItemKind > {
703727 let span = self . token . span ;
704728 self . expect_keyword ( exp ! ( Reuse ) ) ?;
705729
730+ let item_kind = match kind {
731+ ReuseKind :: Path => self . parse_path_like_delegation ( ) ,
732+ ReuseKind :: Impl => self . parse_impl_delegation ( span, attrs, defaultness) ,
733+ } ?;
734+
735+ self . psess . gated_spans . gate ( sym:: fn_delegation, span. to ( self . prev_token . span ) ) ;
736+
737+ Ok ( item_kind)
738+ }
739+
740+ fn parse_delegation_body ( & mut self ) -> PResult < ' a , Option < Box < Block > > > {
741+ Ok ( if self . check ( exp ! ( OpenBrace ) ) {
742+ Some ( self . parse_block ( ) ?)
743+ } else {
744+ self . expect ( exp ! ( Semi ) ) ?;
745+ None
746+ } )
747+ }
748+
749+ fn parse_impl_delegation (
750+ & mut self ,
751+ span : Span ,
752+ attrs : & mut AttrVec ,
753+ defaultness : Defaultness ,
754+ ) -> PResult < ' a , ItemKind > {
755+ let mut impl_item = self . parse_item_impl ( attrs, defaultness, true ) ?;
756+ let ItemKind :: Impl ( Impl { items, of_trait, .. } ) = & mut impl_item else { unreachable ! ( ) } ;
757+
758+ let until_expr_span = span. to ( self . prev_token . span ) ;
759+
760+ let Some ( of_trait) = of_trait else {
761+ return Err ( self
762+ . dcx ( )
763+ . create_err ( errors:: ImplReuseInherentImpl { span : until_expr_span } ) ) ;
764+ } ;
765+
766+ let body = self . parse_delegation_body ( ) ?;
767+ let whole_reuse_span = span. to ( self . prev_token . span ) ;
768+
769+ items. push ( Box :: new ( AssocItem {
770+ id : DUMMY_NODE_ID ,
771+ attrs : Default :: default ( ) ,
772+ span : whole_reuse_span,
773+ tokens : None ,
774+ vis : Visibility {
775+ kind : VisibilityKind :: Inherited ,
776+ span : whole_reuse_span,
777+ tokens : None ,
778+ } ,
779+ kind : AssocItemKind :: DelegationMac ( Box :: new ( DelegationMac {
780+ qself : None ,
781+ prefix : of_trait. trait_ref . path . clone ( ) ,
782+ suffixes : None ,
783+ body,
784+ } ) ) ,
785+ } ) ) ;
786+
787+ Ok ( impl_item)
788+ }
789+
790+ fn parse_path_like_delegation ( & mut self ) -> PResult < ' a , ItemKind > {
706791 let ( qself, path) = if self . eat_lt ( ) {
707792 let ( qself, path) = self . parse_qpath ( PathStyle :: Expr ) ?;
708793 ( Some ( qself) , path)
@@ -713,43 +798,35 @@ impl<'a> Parser<'a> {
713798 let rename = |this : & mut Self | {
714799 Ok ( if this. eat_keyword ( exp ! ( As ) ) { Some ( this. parse_ident ( ) ?) } else { None } )
715800 } ;
716- let body = |this : & mut Self | {
717- Ok ( if this. check ( exp ! ( OpenBrace ) ) {
718- Some ( this. parse_block ( ) ?)
719- } else {
720- this. expect ( exp ! ( Semi ) ) ?;
721- None
722- } )
723- } ;
724801
725- let item_kind = if self . eat_path_sep ( ) {
802+ Ok ( if self . eat_path_sep ( ) {
726803 let suffixes = if self . eat ( exp ! ( Star ) ) {
727804 None
728805 } else {
729806 let parse_suffix = |p : & mut Self | Ok ( ( p. parse_path_segment_ident ( ) ?, rename ( p) ?) ) ;
730807 Some ( self . parse_delim_comma_seq ( exp ! ( OpenBrace ) , exp ! ( CloseBrace ) , parse_suffix) ?. 0 )
731808 } ;
732- let deleg = DelegationMac { qself, prefix : path, suffixes, body : body ( self ) ? } ;
733- ItemKind :: DelegationMac ( Box :: new ( deleg) )
809+
810+ ItemKind :: DelegationMac ( Box :: new ( DelegationMac {
811+ qself,
812+ prefix : path,
813+ suffixes,
814+ body : self . parse_delegation_body ( ) ?,
815+ } ) )
734816 } else {
735817 let rename = rename ( self ) ?;
736818 let ident = rename. unwrap_or_else ( || path. segments . last ( ) . unwrap ( ) . ident ) ;
737- let deleg = Delegation {
819+
820+ ItemKind :: Delegation ( Box :: new ( Delegation {
738821 id : DUMMY_NODE_ID ,
739822 qself,
740823 path,
741824 ident,
742825 rename,
743- body : body ( self ) ?,
826+ body : self . parse_delegation_body ( ) ?,
744827 from_glob : false ,
745- } ;
746- ItemKind :: Delegation ( Box :: new ( deleg) )
747- } ;
748-
749- let span = span. to ( self . prev_token . span ) ;
750- self . psess . gated_spans . gate ( sym:: fn_delegation, span) ;
751-
752- Ok ( item_kind)
828+ } ) )
829+ } )
753830 }
754831
755832 fn parse_item_list < T > (
@@ -2594,7 +2671,7 @@ impl<'a> Parser<'a> {
25942671 Ok ( body)
25952672 }
25962673
2597- fn check_impl_frontmatter ( & mut self ) -> bool {
2674+ fn check_impl_frontmatter ( & mut self , look_ahead : usize ) -> bool {
25982675 const ALL_QUALS : & [ Symbol ] = & [ kw:: Const , kw:: Unsafe ] ;
25992676 // In contrast to the loop below, this call inserts `impl` into the
26002677 // list of expected tokens shown in diagnostics.
@@ -2603,7 +2680,7 @@ impl<'a> Parser<'a> {
26032680 }
26042681 let mut i = 0 ;
26052682 while i < ALL_QUALS . len ( ) {
2606- let action = self . look_ahead ( i, |token| {
2683+ let action = self . look_ahead ( i + look_ahead , |token| {
26072684 if token. is_keyword ( kw:: Impl ) {
26082685 return Some ( true ) ;
26092686 }
@@ -2618,6 +2695,7 @@ impl<'a> Parser<'a> {
26182695 }
26192696 i += 1 ;
26202697 }
2698+
26212699 self . is_keyword_ahead ( i, & [ kw:: Impl ] )
26222700 }
26232701
0 commit comments