@@ -304,23 +304,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
304304 let res = binding. res ( ) ;
305305 self . check_reserved_macro_name ( key. ident , res) ;
306306 self . set_binding_parent_module ( binding, module) ;
307-
308- let mut resolution = self . resolution ( module, key) . borrow_mut ( ) ;
309- let old_binding = resolution. binding ( ) ;
310- let mut t = Ok ( ( ) ) ;
311- if let Some ( old_binding) = resolution. binding {
312- if res == Res :: Err && old_binding. res ( ) != Res :: Err {
313- // Do not override real bindings with `Res::Err`s from error recovery.
314- } else {
307+ self . update_resolution ( module, key, |this, resolution| {
308+ if let Some ( old_binding) = resolution. binding {
309+ if res == Res :: Err && old_binding. res ( ) != Res :: Err {
310+ // Do not override real bindings with `Res::Err`s from error recovery.
311+ return Ok ( ( ) ) ;
312+ }
315313 match ( old_binding. is_glob_import ( ) , binding. is_glob_import ( ) ) {
316314 ( true , true ) => {
317315 if res != old_binding. res ( ) {
318- resolution. binding = Some ( self . ambiguity (
316+ resolution. binding = Some ( this . ambiguity (
319317 AmbiguityKind :: GlobVsGlob ,
320318 old_binding,
321319 binding,
322320 ) ) ;
323- } else if !old_binding. vis . is_at_least ( binding. vis , self . tcx ) {
321+ } else if !old_binding. vis . is_at_least ( binding. vis , this . tcx ) {
324322 // We are glob-importing the same item but with greater visibility.
325323 resolution. binding = Some ( binding) ;
326324 }
@@ -332,7 +330,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
332330 && key. ns == MacroNS
333331 && nonglob_binding. expansion != LocalExpnId :: ROOT
334332 {
335- resolution. binding = Some ( self . ambiguity (
333+ resolution. binding = Some ( this . ambiguity (
336334 AmbiguityKind :: GlobVsExpanded ,
337335 nonglob_binding,
338336 glob_binding,
@@ -344,40 +342,66 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
344342 if let Some ( old_binding) = resolution. shadowed_glob {
345343 assert ! ( old_binding. is_glob_import( ) ) ;
346344 if glob_binding. res ( ) != old_binding. res ( ) {
347- resolution. shadowed_glob = Some ( self . ambiguity (
345+ resolution. shadowed_glob = Some ( this . ambiguity (
348346 AmbiguityKind :: GlobVsGlob ,
349347 old_binding,
350348 glob_binding,
351349 ) ) ;
352- } else if !old_binding. vis . is_at_least ( binding. vis , self . tcx ) {
350+ } else if !old_binding. vis . is_at_least ( binding. vis , this . tcx ) {
353351 resolution. shadowed_glob = Some ( glob_binding) ;
354352 }
355353 } else {
356354 resolution. shadowed_glob = Some ( glob_binding) ;
357355 }
358356 }
359357 ( false , false ) => {
360- t = Err ( old_binding) ;
358+ return Err ( old_binding) ;
361359 }
362360 }
361+ } else {
362+ resolution. binding = Some ( binding) ;
363363 }
364- } else {
365- resolution. binding = Some ( binding) ;
366- } ;
367364
365+ Ok ( ( ) )
366+ } )
367+ }
368+
369+ fn ambiguity (
370+ & self ,
371+ kind : AmbiguityKind ,
372+ primary_binding : & ' a NameBinding < ' a > ,
373+ secondary_binding : & ' a NameBinding < ' a > ,
374+ ) -> & ' a NameBinding < ' a > {
375+ self . arenas . alloc_name_binding ( NameBinding {
376+ ambiguity : Some ( ( secondary_binding, kind) ) ,
377+ ..primary_binding. clone ( )
378+ } )
379+ }
380+
381+ // Use `f` to mutate the resolution of the name in the module.
382+ // If the resolution becomes a success, define it in the module's glob importers.
383+ fn update_resolution < T , F > ( & mut self , module : Module < ' a > , key : BindingKey , f : F ) -> T
384+ where
385+ F : FnOnce ( & mut Resolver < ' a , ' tcx > , & mut NameResolution < ' a > ) -> T ,
386+ {
368387 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
369388 // during which the resolution might end up getting re-defined via a glob cycle.
370- let ( binding, t) = match resolution. binding ( ) {
371- _ if old_binding. is_some ( ) => return t,
372- None => return t,
373- Some ( binding) => match old_binding {
374- Some ( old_binding) if ptr:: eq ( old_binding, binding) => return t,
375- _ => ( binding, t) ,
376- } ,
389+ let ( binding, t) = {
390+ let resolution = & mut * self . resolution ( module, key) . borrow_mut ( ) ;
391+ let old_binding = resolution. binding ( ) ;
392+
393+ let t = f ( self , resolution) ;
394+
395+ match resolution. binding ( ) {
396+ _ if old_binding. is_some ( ) => return t,
397+ None => return t,
398+ Some ( binding) => match old_binding {
399+ Some ( old_binding) if ptr:: eq ( old_binding, binding) => return t,
400+ _ => ( binding, t) ,
401+ } ,
402+ }
377403 } ;
378404
379- drop ( resolution) ;
380-
381405 // Define `binding` in `module`s glob importers.
382406 for import in module. glob_importers . borrow_mut ( ) . iter ( ) {
383407 let mut ident = key. ident ;
@@ -396,18 +420,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
396420 t
397421 }
398422
399- fn ambiguity (
400- & self ,
401- kind : AmbiguityKind ,
402- primary_binding : & ' a NameBinding < ' a > ,
403- secondary_binding : & ' a NameBinding < ' a > ,
404- ) -> & ' a NameBinding < ' a > {
405- self . arenas . alloc_name_binding ( NameBinding {
406- ambiguity : Some ( ( secondary_binding, kind) ) ,
407- ..primary_binding. clone ( )
408- } )
409- }
410-
411423 // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
412424 // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
413425 fn import_dummy_binding ( & mut self , import : & ' a Import < ' a > , is_indeterminate : bool ) {
@@ -757,8 +769,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
757769 . emit ( ) ;
758770 }
759771 let key = BindingKey :: new ( target, ns) ;
760- let mut resolution = this. resolution ( parent, key) . borrow_mut ( ) ;
761- resolution. single_imports . remove ( & Interned :: new_unchecked ( import) ) ;
772+ this. update_resolution ( parent, key, |_, resolution| {
773+ resolution. single_imports . remove ( & Interned :: new_unchecked ( import) ) ;
774+ } ) ;
762775 }
763776 }
764777 }
0 commit comments