@@ -32,7 +32,7 @@ use std::sync::Arc;
3232use diagnostics:: { ImportSuggestion , LabelSuggestion , Suggestion } ;
3333use effective_visibilities:: EffectiveVisibilitiesVisitor ;
3434use errors:: { ParamKindInEnumDiscriminant , ParamKindInNonTrivialAnonConst } ;
35- use imports:: { Import , ImportData , ImportKind , NameResolution } ;
35+ use imports:: { Import , ImportData , ImportKind , NameResolution , PendingBinding } ;
3636use late:: {
3737 ForwardGenericParamBanReason , HasGenericParams , PathSource , PatternSource ,
3838 UnnecessaryQualification ,
@@ -1025,18 +1025,26 @@ impl<'ra> NameBindingData<'ra> {
10251025 }
10261026}
10271027
1028- #[ derive( Default , Clone ) ]
10291028struct ExternPreludeEntry < ' ra > {
10301029 /// Binding from an `extern crate` item.
1031- item_binding : Option < NameBinding < ' ra > > ,
1030+ /// The boolean flag is true is `item_binding` is non-redundant, happens either when
1031+ /// `flag_binding` is `None`, or when `extern crate` introducing `item_binding` used renaming.
1032+ item_binding : Option < ( NameBinding < ' ra > , /* introduced by item */ bool ) > ,
10321033 /// Binding from an `--extern` flag, lazily populated on first use.
1033- flag_binding : Cell < Option < NameBinding < ' ra > > > ,
1034- /// There was no `--extern` flag introducing this name,
1035- /// `flag_binding` doesn't need to be populated.
1036- only_item : bool ,
1037- /// `item_binding` is non-redundant, happens either when `only_item` is true,
1038- /// or when `extern crate` introducing `item_binding` used renaming.
1039- introduced_by_item : bool ,
1034+ flag_binding : Option < Cell < PendingBinding < ' ra > > > ,
1035+ }
1036+
1037+ impl ExternPreludeEntry < ' _ > {
1038+ fn introduced_by_item ( & self ) -> bool {
1039+ matches ! ( self . item_binding, Some ( ( _, true ) ) )
1040+ }
1041+
1042+ fn flag ( ) -> Self {
1043+ ExternPreludeEntry {
1044+ item_binding : None ,
1045+ flag_binding : Some ( Cell :: new ( PendingBinding :: Pending ) ) ,
1046+ }
1047+ }
10401048}
10411049
10421050struct DeriveData {
@@ -1528,19 +1536,20 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15281536 && let name = Symbol :: intern ( name)
15291537 && name. can_be_raw ( )
15301538 {
1531- Some ( ( Macros20NormalizedIdent :: with_dummy_span ( name) , Default :: default ( ) ) )
1539+ let ident = Macros20NormalizedIdent :: with_dummy_span ( name) ;
1540+ Some ( ( ident, ExternPreludeEntry :: flag ( ) ) )
15321541 } else {
15331542 None
15341543 }
15351544 } )
15361545 . collect ( ) ;
15371546
15381547 if !attr:: contains_name ( attrs, sym:: no_core) {
1539- extern_prelude
1540- . insert ( Macros20NormalizedIdent :: with_dummy_span ( sym :: core ) , Default :: default ( ) ) ;
1548+ let ident = Macros20NormalizedIdent :: with_dummy_span ( sym :: core ) ;
1549+ extern_prelude . insert ( ident , ExternPreludeEntry :: flag ( ) ) ;
15411550 if !attr:: contains_name ( attrs, sym:: no_std) {
1542- extern_prelude
1543- . insert ( Macros20NormalizedIdent :: with_dummy_span ( sym :: std ) , Default :: default ( ) ) ;
1551+ let ident = Macros20NormalizedIdent :: with_dummy_span ( sym :: std ) ;
1552+ extern_prelude . insert ( ident , ExternPreludeEntry :: flag ( ) ) ;
15441553 }
15451554 }
15461555
@@ -2062,12 +2071,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20622071 }
20632072 // Avoid marking `extern crate` items that refer to a name from extern prelude,
20642073 // but not introduce it, as used if they are accessed from lexical scope.
2065- if used == Used :: Scope {
2066- if let Some ( entry) = self . extern_prelude . get ( & Macros20NormalizedIdent :: new ( ident) ) {
2067- if !entry. introduced_by_item && entry. item_binding == Some ( used_binding) {
2068- return ;
2069- }
2070- }
2074+ if used == Used :: Scope
2075+ && let Some ( entry) = self . extern_prelude . get ( & Macros20NormalizedIdent :: new ( ident) )
2076+ && entry. item_binding == Some ( ( used_binding, false ) )
2077+ {
2078+ return ;
20712079 }
20722080 let old_used = self . import_use_map . entry ( import) . or_insert ( used) ;
20732081 if * old_used < used {
@@ -2226,7 +2234,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22262234 finalize : bool ,
22272235 ) -> Option < NameBinding < ' ra > > {
22282236 let entry = self . extern_prelude . get ( & Macros20NormalizedIdent :: new ( ident) ) ;
2229- entry. and_then ( |entry| entry. item_binding ) . map ( |binding| {
2237+ entry. and_then ( |entry| entry. item_binding ) . map ( |( binding, _ ) | {
22302238 if finalize {
22312239 self . get_mut ( ) . record_use ( ident, binding, Used :: Scope ) ;
22322240 }
@@ -2236,31 +2244,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
22362244
22372245 fn extern_prelude_get_flag ( & self , ident : Ident , finalize : bool ) -> Option < NameBinding < ' ra > > {
22382246 let entry = self . extern_prelude . get ( & Macros20NormalizedIdent :: new ( ident) ) ;
2239- entry. and_then ( |entry| match entry. flag_binding . get ( ) {
2240- Some ( binding) => {
2241- if finalize {
2242- self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span ) ;
2247+ entry. and_then ( |entry| entry. flag_binding . as_ref ( ) ) . and_then ( |flag_binding| {
2248+ let binding = match flag_binding. get ( ) {
2249+ PendingBinding :: Ready ( binding) => {
2250+ if finalize {
2251+ self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span ) ;
2252+ }
2253+ binding
22432254 }
2244- Some ( binding)
2245- }
2246- None if entry. only_item => None ,
2247- None => {
2248- let crate_id = if finalize {
2249- self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span )
2250- } else {
2251- self . cstore_mut ( ) . maybe_process_path_extern ( self . tcx , ident. name )
2252- } ;
2253- match crate_id {
2254- Some ( crate_id) => {
2255+ PendingBinding :: Pending => {
2256+ let crate_id = if finalize {
2257+ self . cstore_mut ( ) . process_path_extern ( self . tcx , ident. name , ident. span )
2258+ } else {
2259+ self . cstore_mut ( ) . maybe_process_path_extern ( self . tcx , ident. name )
2260+ } ;
2261+ crate_id. map ( |crate_id| {
22552262 let res = Res :: Def ( DefKind :: Mod , crate_id. as_def_id ( ) ) ;
2256- let binding =
2257- self . arenas . new_pub_res_binding ( res, DUMMY_SP , LocalExpnId :: ROOT ) ;
2258- entry. flag_binding . set ( Some ( binding) ) ;
2259- Some ( binding)
2260- }
2261- None => finalize. then_some ( self . dummy_binding ) ,
2263+ self . arenas . new_pub_res_binding ( res, DUMMY_SP , LocalExpnId :: ROOT )
2264+ } )
22622265 }
2263- }
2266+ } ;
2267+ flag_binding. set ( PendingBinding :: Ready ( binding) ) ;
2268+ binding. or_else ( || finalize. then_some ( self . dummy_binding ) )
22642269 } )
22652270 }
22662271
0 commit comments