@@ -1007,15 +1007,24 @@ impl<'ra> NameBindingData<'ra> {
10071007    } 
10081008} 
10091009
1010+ #[ derive( Default ,  Clone ,  Copy ,  PartialEq ) ]  
1011+ enum  EpeBinding < ' ra >  { 
1012+     #[ default]  
1013+     OptPending , 
1014+     OptReadyOk ( NameBinding < ' ra > ,  bool ) , 
1015+     OptReadyErr ( bool ) , 
1016+     Item ( NameBinding < ' ra > ,  bool ) , 
1017+ } 
1018+ 
10101019#[ derive( Default ,  Clone ) ]  
10111020struct  ExternPreludeEntry < ' ra >  { 
1012-     binding :  Cell < Option < NameBinding < ' ra > > > , 
1021+     binding :  Cell < EpeBinding < ' ra > > , 
10131022    introduced_by_item :  bool , 
10141023} 
10151024
10161025impl  ExternPreludeEntry < ' _ >  { 
10171026    fn  is_import ( & self )  -> bool  { 
1018-         self . binding . get ( ) . is_some_and ( |binding| binding . is_import ( ) ) 
1027+         matches ! ( self . binding. get( ) ,   EpeBinding :: Item ( .. ) ) 
10191028    } 
10201029} 
10211030
@@ -2011,7 +2020,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20112020            // but not introduce it, as used if they are accessed from lexical scope. 
20122021            if  used == Used :: Scope  { 
20132022                if  let  Some ( entry)  = self . extern_prelude . get ( & ident. normalize_to_macros_2_0 ( ) )  { 
2014-                     if  !entry. introduced_by_item  && entry. binding . get ( )  == Some ( used_binding)  { 
2023+                     if  !entry. introduced_by_item 
2024+                         && matches ! ( entry. binding. get( ) ,  EpeBinding :: Item ( b,  _)  if  b == used_binding) 
2025+                     { 
20152026                        return ; 
20162027                    } 
20172028                } 
@@ -2174,37 +2185,50 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21742185        } 
21752186
21762187        let  norm_ident = ident. normalize_to_macros_2_0 ( ) ; 
2177-         let  binding = self . extern_prelude . get ( & norm_ident) . cloned ( ) . and_then ( |entry| { 
2178-             Some ( if  let  Some ( binding)  = entry. binding . get ( )  { 
2179-                 if  finalize { 
2180-                     if  !entry. is_import ( )  { 
2181-                         self . cstore_mut ( ) . process_path_extern ( self . tcx ,  ident. name ,  ident. span ) ; 
2182-                     }  else  if  entry. introduced_by_item  { 
2183-                         self . record_use ( ident,  binding,  Used :: Other ) ; 
2184-                     } 
2188+         let  entry = self . extern_prelude . get ( & norm_ident) . cloned ( ) ; 
2189+         let  binding = entry. map ( |entry| match  entry. binding . get ( )  { 
2190+             EpeBinding :: Item ( binding,  finalized)  => { 
2191+                 if  finalize && !finalized && entry. introduced_by_item  { 
2192+                     self . record_use ( ident,  binding,  Used :: Other ) ; 
21852193                } 
2186-                 binding
2187-             }  else  { 
2194+                 EpeBinding :: Item ( binding,  finalize) 
2195+             } 
2196+             EpeBinding :: OptReadyOk ( binding,  finalized)  => { 
2197+                 if  finalize && !finalized { 
2198+                     self . cstore_mut ( ) . process_path_extern ( self . tcx ,  ident. name ,  ident. span ) ; 
2199+                 } 
2200+                 EpeBinding :: OptReadyOk ( binding,  finalize) 
2201+             } 
2202+             EpeBinding :: OptReadyErr ( finalized)  => { 
2203+                 if  finalize && !finalized { 
2204+                     self . cstore_mut ( ) . process_path_extern ( self . tcx ,  ident. name ,  ident. span ) ; 
2205+                 } 
2206+                 EpeBinding :: OptReadyErr ( finalize) 
2207+             } 
2208+             EpeBinding :: OptPending  => { 
21882209                let  crate_id = if  finalize { 
2189-                     let  Some ( crate_id)  =
2190-                         self . cstore_mut ( ) . process_path_extern ( self . tcx ,  ident. name ,  ident. span ) 
2191-                     else  { 
2192-                         return  Some ( self . dummy_binding ) ; 
2193-                     } ; 
2194-                     crate_id
2210+                     self . cstore_mut ( ) . process_path_extern ( self . tcx ,  ident. name ,  ident. span ) 
21952211                }  else  { 
2196-                     self . cstore_mut ( ) . maybe_process_path_extern ( self . tcx ,  ident. name ) ? 
2212+                     self . cstore_mut ( ) . maybe_process_path_extern ( self . tcx ,  ident. name ) 
21972213                } ; 
2198-                 let  res = Res :: Def ( DefKind :: Mod ,  crate_id. as_def_id ( ) ) ; 
2199-                 self . arenas . new_pub_res_binding ( res,  DUMMY_SP ,  LocalExpnId :: ROOT ) 
2200-             } ) 
2214+                 let  res = match  crate_id { 
2215+                     Some ( crate_id)  => Res :: Def ( DefKind :: Mod ,  crate_id. as_def_id ( ) ) , 
2216+                     None  => return  EpeBinding :: OptReadyErr ( finalize) , 
2217+                 } ; 
2218+                 let  binding = self . arenas . new_pub_res_binding ( res,  DUMMY_SP ,  LocalExpnId :: ROOT ) ; 
2219+                 EpeBinding :: OptReadyOk ( binding,  finalize) 
2220+             } 
22012221        } ) ; 
22022222
2203-         if  let  Some ( entry)  = self . extern_prelude . get ( & norm_ident)  { 
2204-             entry. binding . set ( binding) ; 
2205-         } 
2206- 
2207-         binding
2223+         binding. and_then ( |binding| { 
2224+             self . extern_prelude [ & norm_ident] . binding . set ( binding) ; 
2225+             match  binding { 
2226+                 EpeBinding :: Item ( binding,  _)  | EpeBinding :: OptReadyOk ( binding,  _)  => Some ( binding) , 
2227+                 EpeBinding :: OptReadyErr ( _)  if  finalize => Some ( self . dummy_binding ) , 
2228+                 EpeBinding :: OptReadyErr ( _)  => None , 
2229+                 EpeBinding :: OptPending  => unreachable ! ( ) , 
2230+             } 
2231+         } ) 
22082232    } 
22092233
22102234    /// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>` 
0 commit comments