@@ -375,22 +375,47 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
375375 return resolution_result;
376376 }
377377
378- fn resolve_imported_name_in_module ( & mut self ,
379- module : Module < ' b > , // Module containing the name
380- name : Name ,
381- ns : Namespace ,
382- importing_module : Module < ' b > ) // Module importing the name
383- -> ResolveResult < ( Module < ' b > , NameBinding < ' b > ) > {
378+ /// Resolves the name in the namespace of the module because it is being imported by
379+ /// importing_module. Returns the module in which the name was defined (as opposed to imported),
380+ /// the name bindings defining the name, and whether or not the name was imported into `module`.
381+ fn resolve_name_in_module ( & mut self ,
382+ module : Module < ' b > , // Module containing the name
383+ name : Name ,
384+ ns : Namespace ,
385+ importing_module : Module < ' b > ) // Module importing the name
386+ -> ( ResolveResult < ( Module < ' b > , NameBinding < ' b > ) > , bool ) {
387+ build_reduced_graph:: populate_module_if_necessary ( self . resolver , module) ;
388+ if let Some ( name_binding) = module. get_child ( name, ns) {
389+ return ( Success ( ( module, name_binding) ) , false ) ;
390+ }
391+
392+ if let TypeNS = ns {
393+ if let Some ( extern_crate) = module. external_module_children . borrow ( ) . get ( & name) {
394+ // track the extern crate as used.
395+ if let Some ( DefId { krate : kid, .. } ) = extern_crate. def_id ( ) {
396+ self . resolver . used_crates . insert ( kid) ;
397+ }
398+ let name_binding = NameBinding :: create_from_module ( extern_crate, None ) ;
399+ return ( Success ( ( module, name_binding) ) , false ) ;
400+ }
401+ }
402+
403+ // If there is an unresolved glob at this point in the containing module, bail out.
404+ // We don't know enough to be able to resolve the name.
405+ if module. pub_glob_count . get ( ) > 0 {
406+ return ( Indeterminate , false ) ;
407+ }
408+
384409 match module. import_resolutions . borrow ( ) . get ( & ( name, ns) ) {
385410 // The containing module definitely doesn't have an exported import with the
386411 // name in question. We can therefore accurately report that names are unbound.
387- None => Failed ( None ) ,
412+ None => ( Failed ( None ) , false ) ,
388413
389414 // The name is an import which has been fully resolved, so we just follow it.
390415 Some ( resolution) if resolution. outstanding_references == 0 => {
391416 // Import resolutions must be declared with "pub" in order to be exported.
392417 if !resolution. is_public {
393- return Failed ( None ) ;
418+ return ( Failed ( None ) , false ) ;
394419 }
395420
396421 let target = resolution. target . clone ( ) ;
@@ -401,9 +426,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
401426 if let Some ( DefId { krate, .. } ) = target_module. def_id ( ) {
402427 self . resolver . used_crates . insert ( krate) ;
403428 }
404- Success ( ( target_module, binding) )
429+ ( Success ( ( target_module, binding) ) , true )
405430 } else {
406- Failed ( None )
431+ ( Failed ( None ) , false )
407432 }
408433 }
409434
@@ -415,11 +440,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
415440 // use self::submodule;
416441 // pub mod submodule;
417442 //
418- // In this case we continue as if we resolved the import and let the
419- // check_for_conflicts_between_imports_and_items call below handle the conflict
443+ // In this case we continue as if we resolved the import and let
444+ // check_for_conflicts_between_imports_and_items handle the conflict
420445 Some ( _) => match ( importing_module. def_id ( ) , module. def_id ( ) ) {
421- ( Some ( id1) , Some ( id2) ) if id1 == id2 => Failed ( None ) ,
422- _ => Indeterminate ,
446+ ( Some ( id1) , Some ( id2) ) if id1 == id2 => ( Failed ( None ) , false ) ,
447+ _ => ( Indeterminate , false )
423448 } ,
424449 }
425450 }
@@ -451,34 +476,25 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
451476 } ;
452477
453478 // We need to resolve both namespaces for this to succeed.
454- let mut value_result = Indeterminate ;
455- let mut type_result = Indeterminate ;
456- let mut lev_suggestion = "" . to_owned ( ) ;
479+ let ( value_result, value_used_reexport) =
480+ self . resolve_name_in_module ( & target_module, source, ValueNS , module_) ;
481+ let ( type_result, type_used_reexport) =
482+ self . resolve_name_in_module ( & target_module, source, TypeNS , module_) ;
457483
458- // Search for direct children of the containing module.
459- build_reduced_graph:: populate_module_if_necessary ( self . resolver , & target_module) ;
460-
461- // pub_err makes sure we don't give the same error twice.
462- let mut pub_err = false ;
463-
464- if let Some ( name_binding) = target_module. get_child ( source, ValueNS ) {
465- debug ! ( "(resolving single import) found value binding" ) ;
466- value_result = Success ( ( target_module, name_binding. clone ( ) ) ) ;
467- if directive. is_public && !name_binding. is_public ( ) {
484+ match ( & value_result, & type_result) {
485+ ( & Success ( ( _, ref name_binding) ) , _) if !value_used_reexport &&
486+ directive. is_public &&
487+ !name_binding. is_public ( ) => {
468488 let msg = format ! ( "`{}` is private, and cannot be reexported" , source) ;
469489 let note_msg = format ! ( "Consider marking `{}` as `pub` in the imported module" ,
470490 source) ;
471491 struct_span_err ! ( self . resolver. session, directive. span, E0364 , "{}" , & msg)
472492 . span_note ( directive. span , & note_msg)
473493 . emit ( ) ;
474- pub_err = true ;
475494 }
476- }
477495
478- if let Some ( name_binding) = target_module. get_child ( source, TypeNS ) {
479- debug ! ( "(resolving single import) found type binding" ) ;
480- type_result = Success ( ( target_module, name_binding. clone ( ) ) ) ;
481- if !pub_err && directive. is_public {
496+ ( _, & Success ( ( _, ref name_binding) ) ) if !type_used_reexport &&
497+ directive. is_public => {
482498 if !name_binding. is_public ( ) {
483499 let msg = format ! ( "`{}` is private, and cannot be reexported" , source) ;
484500 let note_msg =
@@ -496,50 +512,26 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
496512 msg) ;
497513 }
498514 }
499- }
500-
501- if let ( & Indeterminate , & Indeterminate ) = ( & value_result, & type_result) {
502- let names = target_module. children . borrow ( ) ;
503- let names = names. keys ( ) . map ( |& ( ref name, _) | name) ;
504- if let Some ( name) = find_best_match_for_name ( names, & source. as_str ( ) , None ) {
505- lev_suggestion = format ! ( ". Did you mean to use `{}`?" , name) ;
506- }
507- }
508515
509- match ( & value_result, & type_result) {
510- // If there is an unresolved glob at this point in the containing module, bail out.
511- // We don't know enough to be able to resolve this import.
512- ( & Indeterminate , _) | ( _, & Indeterminate ) if target_module. pub_glob_count . get ( ) > 0 =>
513- return Indeterminate ,
514- _ => ( )
515- }
516-
517- let mut value_used_reexport = false ;
518- if let Indeterminate = value_result {
519- value_result =
520- self . resolve_imported_name_in_module ( & target_module, source, ValueNS , module_) ;
521- value_used_reexport = match value_result { Success ( _) => true , _ => false } ;
522- }
523-
524- let mut type_used_reexport = false ;
525- if let Indeterminate = type_result {
526- type_result =
527- self . resolve_imported_name_in_module ( & target_module, source, TypeNS , module_) ;
528- type_used_reexport = match type_result { Success ( _) => true , _ => false } ;
516+ _ => { }
529517 }
530518
519+ let mut lev_suggestion = "" . to_owned ( ) ;
531520 match ( & value_result, & type_result) {
532521 ( & Indeterminate , _) | ( _, & Indeterminate ) => return Indeterminate ,
533522 ( & Failed ( _) , & Failed ( _) ) => {
534- if lev_suggestion. is_empty ( ) { // skip if we already have a suggestion
535- let names = target_module. import_resolutions . borrow ( ) ;
536- let names = names. keys ( ) . map ( |& ( ref name, _) | name) ;
523+ let children = target_module. children . borrow ( ) ;
524+ let names = children. keys ( ) . map ( |& ( ref name, _) | name) ;
525+ if let Some ( name) = find_best_match_for_name ( names, & source. as_str ( ) , None ) {
526+ lev_suggestion = format ! ( ". Did you mean to use `{}`?" , name) ;
527+ } else {
528+ let resolutions = target_module. import_resolutions . borrow ( ) ;
529+ let names = resolutions. keys ( ) . map ( |& ( ref name, _) | name) ;
537530 if let Some ( name) = find_best_match_for_name ( names,
538531 & source. as_str ( ) ,
539532 None ) {
540533 lev_suggestion =
541- format ! ( ". Did you mean to use the re-exported import `{}`?" ,
542- name) ;
534+ format ! ( ". Did you mean to use the re-exported import `{}`?" , name) ;
543535 }
544536 }
545537 }
@@ -549,30 +541,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
549541 let mut value_used_public = false ;
550542 let mut type_used_public = false ;
551543
552- // If we didn't find a result in the type namespace, search the
553- // external modules.
554- match type_result {
555- Success ( ..) => { }
556- _ => {
557- match target_module. external_module_children . borrow_mut ( ) . get ( & source) . cloned ( ) {
558- None => { } // Continue.
559- Some ( module) => {
560- debug ! ( "(resolving single import) found external module" ) ;
561- // track the module as used.
562- match module. def_id ( ) {
563- Some ( DefId { krate : kid, ..} ) => {
564- self . resolver . used_crates . insert ( kid) ;
565- }
566- _ => { }
567- }
568- let name_binding = NameBinding :: create_from_module ( module, None ) ;
569- type_result = Success ( ( target_module, name_binding) ) ;
570- type_used_public = true ;
571- }
572- }
573- }
574- }
575-
576544 // We've successfully resolved the import. Write the results in.
577545 let mut import_resolutions = module_. import_resolutions . borrow_mut ( ) ;
578546
@@ -621,7 +589,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
621589 import_resolution,
622590 directive. span ,
623591 ( target, namespace) ) ;
624-
625592 } ;
626593 check_and_write_import ( ValueNS , & value_result, & mut value_used_public) ;
627594 check_and_write_import ( TypeNS , & type_result, & mut type_used_public) ;
@@ -631,8 +598,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
631598 let msg = format ! ( "There is no `{}` in `{}`{}" ,
632599 source,
633600 module_to_string( & target_module) , lev_suggestion) ;
634- return ResolveResult :: Failed ( Some ( ( directive. span , msg) ) ) ;
601+ return Failed ( Some ( ( directive. span , msg) ) ) ;
635602 }
603+
636604 let value_used_public = value_used_reexport || value_used_public;
637605 let type_used_public = type_used_reexport || type_used_public;
638606
@@ -646,12 +614,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
646614 // purposes it's good enough to just favor one over the other.
647615 import_resolution_value. target . as_ref ( ) . map ( |target| {
648616 let def = target. binding . def ( ) . unwrap ( ) ;
649- ( def,
650- if value_used_public {
651- lp
652- } else {
653- DependsOn ( def. def_id ( ) )
654- } )
617+ let last_private = if value_used_public { lp } else { DependsOn ( def. def_id ( ) ) } ;
618+ ( def, last_private)
655619 } )
656620 } ;
657621
@@ -662,12 +626,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
662626
663627 import_resolution_type. target . as_ref ( ) . map ( |target| {
664628 let def = target. binding . def ( ) . unwrap ( ) ;
665- ( def,
666- if type_used_public {
667- lp
668- } else {
669- DependsOn ( def. def_id ( ) )
670- } )
629+ let last_private = if type_used_public { lp } else { DependsOn ( def. def_id ( ) ) } ;
630+ ( def, last_private)
671631 } )
672632 } ;
673633
@@ -696,7 +656,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
696656 }
697657
698658 debug ! ( "(resolving single import) successfully resolved import" ) ;
699- return ResolveResult :: Success ( ( ) ) ;
659+ return Success ( ( ) ) ;
700660 }
701661
702662 // Resolves a glob import. Note that this function cannot fail; it either
0 commit comments