@@ -12,7 +12,7 @@ use self::ImportDirectiveSubclass::*;
1212
1313use Module ;
1414use Namespace :: { self , TypeNS , ValueNS } ;
15- use { NameBinding , NameBindingKind , PrivacyError } ;
15+ use { NameBinding , NameBindingKind , PrivacyError , ToNameBinding } ;
1616use ResolveResult ;
1717use ResolveResult :: * ;
1818use Resolver ;
@@ -226,28 +226,6 @@ impl<'a> ::ModuleS<'a> {
226226 Failed ( None )
227227 }
228228
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-
251229 pub fn add_import_directive ( & self ,
252230 module_path : Vec < Name > ,
253231 subclass : ImportDirectiveSubclass ,
@@ -277,19 +255,45 @@ impl<'a> ::ModuleS<'a> {
277255 GlobImport { .. } => self . globs . borrow_mut ( ) . push ( directive) ,
278256 }
279257 }
258+ }
280259
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.
282286 // 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
285289 {
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.
288292 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 ( ) ;
290294 let was_known = resolution. binding ( ) . is_some ( ) ;
291295
292- let t = update ( resolution) ;
296+ let t = f ( self , resolution) ;
293297
294298 if was_known { return t; }
295299 match resolution. binding ( ) {
@@ -298,15 +302,14 @@ impl<'a> ::ModuleS<'a> {
298302 }
299303 } ;
300304
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+ }
309310 }
311+
312+ t
310313 }
311314}
312315
@@ -396,7 +399,9 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
396399
397400 // Define a "dummy" resolution containing a Def::Err as a placeholder for a
398401 // 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 > ) {
400405 if let SingleImport { target, .. } = directive. subclass {
401406 let dummy_binding = self . arenas . alloc_name_binding ( NameBinding {
402407 kind : NameBindingKind :: Def ( Def :: Err ) ,
@@ -405,14 +410,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
405410 } ) ;
406411 let dummy_binding = directive. import ( dummy_binding) ;
407412
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) ;
410415 }
411416 }
412417
413418 /// Resolves an `ImportResolvingError` into the correct enum discriminant
414419 /// 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 > ) {
416421 // If the error is a single failed import then create a "fake" import
417422 // resolution for it so that later resolve stages won't complain.
418423 self . import_dummy_binding ( e. source_module , e. import_directive ) ;
@@ -492,7 +497,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
492497 match * result {
493498 Failed ( ..) if !determined. get ( ) => {
494499 determined. set ( true ) ;
495- module_ . update_resolution ( target, ns, |resolution| {
500+ self . update_resolution ( module_ , target, ns, |_ , resolution| {
496501 resolution. single_imports . directive_failed ( )
497502 } ) ;
498503 }
@@ -508,7 +513,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
508513 Success ( binding) if !determined. get ( ) => {
509514 determined. set ( true ) ;
510515 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) ;
512517 if let Err ( old_binding) = conflict {
513518 let binding = & directive. import ( binding) ;
514519 self . report_conflict ( module_, target, ns, binding, old_binding) ;
@@ -551,7 +556,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
551556 for & ( ns, result) in & [ ( ValueNS , & value_result) , ( TypeNS , & type_result) ] {
552557 let binding = match * result { Success ( binding) => binding, _ => continue } ;
553558 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) ) ;
555560 }
556561 }
557562
@@ -626,14 +631,14 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
626631 // Add to target_module's glob_importers
627632 target_module. glob_importers . borrow_mut ( ) . push ( ( module_, directive) ) ;
628633
629- // Ensure that `resolutions` isn't borrowed during `try_define_child `,
634+ // Ensure that `resolutions` isn't borrowed during `try_define `,
630635 // since it might get updated via a glob cycle.
631636 let bindings = target_module. resolutions . borrow ( ) . iter ( ) . filter_map ( |( name, resolution) | {
632637 resolution. borrow ( ) . binding ( ) . map ( |binding| ( * name, binding) )
633638 } ) . collect :: < Vec < _ > > ( ) ;
634639 for ( ( name, ns) , binding) in bindings {
635640 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) ) ;
637642 }
638643 }
639644
0 commit comments