@@ -304,23 +304,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
304
304
let res = binding. res ( ) ;
305
305
self . check_reserved_macro_name ( key. ident , res) ;
306
306
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
+ }
315
313
match ( old_binding. is_glob_import ( ) , binding. is_glob_import ( ) ) {
316
314
( true , true ) => {
317
315
if res != old_binding. res ( ) {
318
- resolution. binding = Some ( self . ambiguity (
316
+ resolution. binding = Some ( this . ambiguity (
319
317
AmbiguityKind :: GlobVsGlob ,
320
318
old_binding,
321
319
binding,
322
320
) ) ;
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 ) {
324
322
// We are glob-importing the same item but with greater visibility.
325
323
resolution. binding = Some ( binding) ;
326
324
}
@@ -332,7 +330,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
332
330
&& key. ns == MacroNS
333
331
&& nonglob_binding. expansion != LocalExpnId :: ROOT
334
332
{
335
- resolution. binding = Some ( self . ambiguity (
333
+ resolution. binding = Some ( this . ambiguity (
336
334
AmbiguityKind :: GlobVsExpanded ,
337
335
nonglob_binding,
338
336
glob_binding,
@@ -344,40 +342,66 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
344
342
if let Some ( old_binding) = resolution. shadowed_glob {
345
343
assert ! ( old_binding. is_glob_import( ) ) ;
346
344
if glob_binding. res ( ) != old_binding. res ( ) {
347
- resolution. shadowed_glob = Some ( self . ambiguity (
345
+ resolution. shadowed_glob = Some ( this . ambiguity (
348
346
AmbiguityKind :: GlobVsGlob ,
349
347
old_binding,
350
348
glob_binding,
351
349
) ) ;
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 ) {
353
351
resolution. shadowed_glob = Some ( glob_binding) ;
354
352
}
355
353
} else {
356
354
resolution. shadowed_glob = Some ( glob_binding) ;
357
355
}
358
356
}
359
357
( false , false ) => {
360
- t = Err ( old_binding) ;
358
+ return Err ( old_binding) ;
361
359
}
362
360
}
361
+ } else {
362
+ resolution. binding = Some ( binding) ;
363
363
}
364
- } else {
365
- resolution. binding = Some ( binding) ;
366
- } ;
367
364
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
+ {
368
387
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
369
388
// 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
+ }
377
403
} ;
378
404
379
- drop ( resolution) ;
380
-
381
405
// Define `binding` in `module`s glob importers.
382
406
for import in module. glob_importers . borrow_mut ( ) . iter ( ) {
383
407
let mut ident = key. ident ;
@@ -396,18 +420,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
396
420
t
397
421
}
398
422
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
-
411
423
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
412
424
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
413
425
fn import_dummy_binding ( & mut self , import : & ' a Import < ' a > , is_indeterminate : bool ) {
@@ -757,8 +769,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
757
769
. emit ( ) ;
758
770
}
759
771
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
+ } ) ;
762
775
}
763
776
}
764
777
}
0 commit comments