@@ -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