@@ -12,7 +12,7 @@ use self::ImportDirectiveSubclass::*;
12
12
13
13
use Module ;
14
14
use Namespace :: { self , TypeNS , ValueNS } ;
15
- use { NameBinding , NameBindingKind , PrivacyError } ;
15
+ use { NameBinding , NameBindingKind , PrivacyError , ToNameBinding } ;
16
16
use ResolveResult ;
17
17
use ResolveResult :: * ;
18
18
use Resolver ;
@@ -226,28 +226,6 @@ impl<'a> ::ModuleS<'a> {
226
226
Failed ( None )
227
227
}
228
228
229
- // Define the name or return the existing binding if there is a collision.
230
- pub fn try_define_child ( & self , name : Name , ns : Namespace , binding : NameBinding < ' a > )
231
- -> Result < ( ) , & ' a NameBinding < ' a > > {
232
- let binding = self . arenas . alloc_name_binding ( binding) ;
233
- self . update_resolution ( name, ns, |resolution| {
234
- if let Some ( old_binding) = resolution. binding {
235
- if binding. is_glob_import ( ) {
236
- resolution. duplicate_globs . push ( binding) ;
237
- } else if old_binding. is_glob_import ( ) {
238
- resolution. duplicate_globs . push ( old_binding) ;
239
- resolution. binding = Some ( binding) ;
240
- } else {
241
- return Err ( old_binding) ;
242
- }
243
- } else {
244
- resolution. binding = Some ( binding) ;
245
- }
246
-
247
- Ok ( ( ) )
248
- } )
249
- }
250
-
251
229
pub fn add_import_directive ( & self ,
252
230
module_path : Vec < Name > ,
253
231
subclass : ImportDirectiveSubclass ,
@@ -277,19 +255,45 @@ impl<'a> ::ModuleS<'a> {
277
255
GlobImport { .. } => self . globs . borrow_mut ( ) . push ( directive) ,
278
256
}
279
257
}
258
+ }
280
259
281
- // Use `update` to mutate the resolution for the name.
260
+ impl < ' a > Resolver < ' a > {
261
+ // Define the name or return the existing binding if there is a collision.
262
+ pub fn try_define < T > ( & mut self , module : Module < ' a > , name : Name , ns : Namespace , binding : T )
263
+ -> Result < ( ) , & ' a NameBinding < ' a > >
264
+ where T : ToNameBinding < ' a >
265
+ {
266
+ let binding = self . arenas . alloc_name_binding ( binding. to_name_binding ( ) ) ;
267
+ self . update_resolution ( module, name, ns, |_, resolution| {
268
+ if let Some ( old_binding) = resolution. binding {
269
+ if binding. is_glob_import ( ) {
270
+ resolution. duplicate_globs . push ( binding) ;
271
+ } else if old_binding. is_glob_import ( ) {
272
+ resolution. duplicate_globs . push ( old_binding) ;
273
+ resolution. binding = Some ( binding) ;
274
+ } else {
275
+ return Err ( old_binding) ;
276
+ }
277
+ } else {
278
+ resolution. binding = Some ( binding) ;
279
+ }
280
+
281
+ Ok ( ( ) )
282
+ } )
283
+ }
284
+
285
+ // Use `f` to mutate the resolution of the name in the module.
282
286
// If the resolution becomes a success, define it in the module's glob importers.
283
- fn update_resolution < T , F > ( & self , name : Name , ns : Namespace , update : F ) -> T
284
- where F : FnOnce ( & mut NameResolution < ' a > ) -> T
287
+ fn update_resolution < T , F > ( & mut self , module : Module < ' a > , name : Name , ns : Namespace , f : F ) -> T
288
+ where F : FnOnce ( & mut Resolver < ' a > , & mut NameResolution < ' a > ) -> T
285
289
{
286
- // Ensure that `resolution` isn't borrowed during `define_in_glob_importers` ,
287
- // where it might end up getting re-defined via a glob cycle.
290
+ // Ensure that `resolution` isn't borrowed when defining in the module's glob importers ,
291
+ // during which the resolution might end up getting re-defined via a glob cycle.
288
292
let ( new_binding, t) = {
289
- let mut resolution = & mut * self . resolution ( name, ns) . borrow_mut ( ) ;
293
+ let mut resolution = & mut * module . resolution ( name, ns) . borrow_mut ( ) ;
290
294
let was_known = resolution. binding ( ) . is_some ( ) ;
291
295
292
- let t = update ( resolution) ;
296
+ let t = f ( self , resolution) ;
293
297
294
298
if was_known { return t; }
295
299
match resolution. binding ( ) {
@@ -298,15 +302,14 @@ impl<'a> ::ModuleS<'a> {
298
302
}
299
303
} ;
300
304
301
- self . define_in_glob_importers ( name, ns, new_binding) ;
302
- t
303
- }
304
-
305
- fn define_in_glob_importers ( & self , name : Name , ns : Namespace , binding : & ' a NameBinding < ' a > ) {
306
- if !binding. is_importable ( ) || !binding. is_pseudo_public ( ) { return }
307
- for & ( importer, directive) in self . glob_importers . borrow_mut ( ) . iter ( ) {
308
- let _ = importer. try_define_child ( name, ns, directive. import ( binding) ) ;
305
+ // Define `new_binding` in `module`s glob importers.
306
+ if new_binding. is_importable ( ) && new_binding. is_pseudo_public ( ) {
307
+ for & ( importer, directive) in module. glob_importers . borrow_mut ( ) . iter ( ) {
308
+ let _ = self . try_define ( importer, name, ns, directive. import ( new_binding) ) ;
309
+ }
309
310
}
311
+
312
+ t
310
313
}
311
314
}
312
315
@@ -396,7 +399,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
396
399
397
400
// Define a "dummy" resolution containing a Def::Err as a placeholder for a
398
401
// failed resolution
399
- fn import_dummy_binding ( & self , source_module : Module < ' b > , directive : & ' b ImportDirective < ' b > ) {
402
+ fn import_dummy_binding ( & mut self ,
403
+ source_module : Module < ' b > ,
404
+ directive : & ' b ImportDirective < ' b > ) {
400
405
if let SingleImport { target, .. } = directive. subclass {
401
406
let dummy_binding = self . arenas . alloc_name_binding ( NameBinding {
402
407
kind : NameBindingKind :: Def ( Def :: Err ) ,
@@ -405,14 +410,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
405
410
} ) ;
406
411
let dummy_binding = directive. import ( dummy_binding) ;
407
412
408
- let _ = source_module . try_define_child ( target, ValueNS , dummy_binding. clone ( ) ) ;
409
- let _ = source_module . try_define_child ( target, TypeNS , dummy_binding) ;
413
+ let _ = self . try_define ( source_module , target, ValueNS , dummy_binding. clone ( ) ) ;
414
+ let _ = self . try_define ( source_module , target, TypeNS , dummy_binding) ;
410
415
}
411
416
}
412
417
413
418
/// Resolves an `ImportResolvingError` into the correct enum discriminant
414
419
/// and passes that on to `resolve_error`.
415
- fn import_resolving_error ( & self , e : ImportResolvingError < ' b > ) {
420
+ fn import_resolving_error ( & mut self , e : ImportResolvingError < ' b > ) {
416
421
// If the error is a single failed import then create a "fake" import
417
422
// resolution for it so that later resolve stages won't complain.
418
423
self . import_dummy_binding ( e. source_module , e. import_directive ) ;
@@ -492,7 +497,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
492
497
match * result {
493
498
Failed ( ..) if !determined. get ( ) => {
494
499
determined. set ( true ) ;
495
- module_ . update_resolution ( target, ns, |resolution| {
500
+ self . update_resolution ( module_ , target, ns, |_ , resolution| {
496
501
resolution. single_imports . directive_failed ( )
497
502
} ) ;
498
503
}
@@ -508,7 +513,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
508
513
Success ( binding) if !determined. get ( ) => {
509
514
determined. set ( true ) ;
510
515
let imported_binding = directive. import ( binding) ;
511
- let conflict = module_ . try_define_child ( target, ns, imported_binding) ;
516
+ let conflict = self . try_define ( module_ , target, ns, imported_binding) ;
512
517
if let Err ( old_binding) = conflict {
513
518
let binding = & directive. import ( binding) ;
514
519
self . report_conflict ( module_, target, ns, binding, old_binding) ;
@@ -551,7 +556,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
551
556
for & ( ns, result) in & [ ( ValueNS , & value_result) , ( TypeNS , & type_result) ] {
552
557
let binding = match * result { Success ( binding) => binding, _ => continue } ;
553
558
self . privacy_errors . push ( PrivacyError ( directive. span , source, binding) ) ;
554
- let _ = module_ . try_define_child ( target, ns, directive. import ( binding) ) ;
559
+ let _ = self . try_define ( module_ , target, ns, directive. import ( binding) ) ;
555
560
}
556
561
}
557
562
@@ -626,14 +631,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
626
631
// Add to target_module's glob_importers
627
632
target_module. glob_importers . borrow_mut ( ) . push ( ( module_, directive) ) ;
628
633
629
- // Ensure that `resolutions` isn't borrowed during `try_define_child `,
634
+ // Ensure that `resolutions` isn't borrowed during `try_define `,
630
635
// since it might get updated via a glob cycle.
631
636
let bindings = target_module. resolutions . borrow ( ) . iter ( ) . filter_map ( |( name, resolution) | {
632
637
resolution. borrow ( ) . binding ( ) . map ( |binding| ( * name, binding) )
633
638
} ) . collect :: < Vec < _ > > ( ) ;
634
639
for ( ( name, ns) , binding) in bindings {
635
640
if binding. is_importable ( ) && binding. is_pseudo_public ( ) {
636
- let _ = module_ . try_define_child ( name, ns, directive. import ( binding) ) ;
641
+ let _ = self . try_define ( module_ , name, ns, directive. import ( binding) ) ;
637
642
}
638
643
}
639
644
0 commit comments