@@ -1007,15 +1007,24 @@ impl<'ra> NameBindingData<'ra> {
1007
1007
}
1008
1008
}
1009
1009
1010
+ #[ derive( Default , Clone , Copy , PartialEq ) ]
1011
+ enum EpeBinding < ' ra > {
1012
+ #[ default]
1013
+ OptPending ,
1014
+ OptReadyOk ( NameBinding < ' ra > ) ,
1015
+ OptReadyErr ,
1016
+ Item ( NameBinding < ' ra > ) ,
1017
+ }
1018
+
1010
1019
#[ derive( Default , Clone ) ]
1011
1020
struct ExternPreludeEntry < ' ra > {
1012
- binding : Cell < Option < NameBinding < ' ra > > > ,
1021
+ binding : Cell < EpeBinding < ' ra > > ,
1013
1022
introduced_by_item : bool ,
1014
1023
}
1015
1024
1016
1025
impl ExternPreludeEntry < ' _ > {
1017
1026
fn is_import ( & self ) -> bool {
1018
- self . binding . get ( ) . is_some_and ( |binding| binding . is_import ( ) )
1027
+ matches ! ( self . binding. get( ) , EpeBinding :: Item ( .. ) )
1019
1028
}
1020
1029
}
1021
1030
@@ -2011,7 +2020,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
2011
2020
// but not introduce it, as used if they are accessed from lexical scope.
2012
2021
if used == Used :: Scope {
2013
2022
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
+ && entry. binding . get ( ) == EpeBinding :: Item ( used_binding)
2025
+ {
2015
2026
return ;
2016
2027
}
2017
2028
}
@@ -2174,37 +2185,50 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
2174
2185
}
2175
2186
2176
2187
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 ( ) {
2188
+ let entry = self . extern_prelude . get ( & norm_ident) . cloned ( ) ;
2189
+ let binding = entry. map ( |entry| match entry. binding . get ( ) {
2190
+ EpeBinding :: Item ( binding) => {
2191
+ if finalize && entry. introduced_by_item {
2192
+ self . record_use ( ident, binding, Used :: Other ) ;
2193
+ }
2194
+ EpeBinding :: Item ( binding)
2195
+ }
2196
+ EpeBinding :: OptReadyOk ( binding) => {
2179
2197
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
- }
2198
+ self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span ) ;
2185
2199
}
2186
- binding
2187
- } else {
2200
+ EpeBinding :: OptReadyOk ( binding)
2201
+ }
2202
+ EpeBinding :: OptReadyErr => {
2203
+ if finalize {
2204
+ self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span ) ;
2205
+ }
2206
+ EpeBinding :: OptReadyErr
2207
+ }
2208
+ EpeBinding :: OptPending => {
2188
2209
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 )
2195
2211
} 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 )
2197
2213
} ;
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 ,
2217
+ } ;
2218
+ let binding = self . arenas . new_pub_res_binding ( res, DUMMY_SP , LocalExpnId :: ROOT ) ;
2219
+ EpeBinding :: OptReadyOk ( binding)
2220
+ }
2201
2221
} ) ;
2202
2222
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
+ } )
2208
2232
}
2209
2233
2210
2234
/// Rustdoc uses this to resolve doc link paths in a recoverable way. `PathResult<'a>`
0 commit comments