@@ -375,22 +375,47 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
375
375
return resolution_result;
376
376
}
377
377
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
+
384
409
match module. import_resolutions . borrow ( ) . get ( & ( name, ns) ) {
385
410
// The containing module definitely doesn't have an exported import with the
386
411
// name in question. We can therefore accurately report that names are unbound.
387
- None => Failed ( None ) ,
412
+ None => ( Failed ( None ) , false ) ,
388
413
389
414
// The name is an import which has been fully resolved, so we just follow it.
390
415
Some ( resolution) if resolution. outstanding_references == 0 => {
391
416
// Import resolutions must be declared with "pub" in order to be exported.
392
417
if !resolution. is_public {
393
- return Failed ( None ) ;
418
+ return ( Failed ( None ) , false ) ;
394
419
}
395
420
396
421
let target = resolution. target . clone ( ) ;
@@ -401,9 +426,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
401
426
if let Some ( DefId { krate, .. } ) = target_module. def_id ( ) {
402
427
self . resolver . used_crates . insert ( krate) ;
403
428
}
404
- Success ( ( target_module, binding) )
429
+ ( Success ( ( target_module, binding) ) , true )
405
430
} else {
406
- Failed ( None )
431
+ ( Failed ( None ) , false )
407
432
}
408
433
}
409
434
@@ -415,11 +440,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
415
440
// use self::submodule;
416
441
// pub mod submodule;
417
442
//
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
420
445
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 )
423
448
} ,
424
449
}
425
450
}
@@ -451,34 +476,25 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
451
476
} ;
452
477
453
478
// 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_) ;
457
483
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 ( ) => {
468
488
let msg = format ! ( "`{}` is private, and cannot be reexported" , source) ;
469
489
let note_msg = format ! ( "Consider marking `{}` as `pub` in the imported module" ,
470
490
source) ;
471
491
struct_span_err ! ( self . resolver. session, directive. span, E0364 , "{}" , & msg)
472
492
. span_note ( directive. span , & note_msg)
473
493
. emit ( ) ;
474
- pub_err = true ;
475
494
}
476
- }
477
495
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 => {
482
498
if !name_binding. is_public ( ) {
483
499
let msg = format ! ( "`{}` is private, and cannot be reexported" , source) ;
484
500
let note_msg =
@@ -496,50 +512,26 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
496
512
msg) ;
497
513
}
498
514
}
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
- }
508
515
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
+ _ => { }
529
517
}
530
518
519
+ let mut lev_suggestion = "" . to_owned ( ) ;
531
520
match ( & value_result, & type_result) {
532
521
( & Indeterminate , _) | ( _, & Indeterminate ) => return Indeterminate ,
533
522
( & 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) ;
537
530
if let Some ( name) = find_best_match_for_name ( names,
538
531
& source. as_str ( ) ,
539
532
None ) {
540
533
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) ;
543
535
}
544
536
}
545
537
}
@@ -549,30 +541,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
549
541
let mut value_used_public = false ;
550
542
let mut type_used_public = false ;
551
543
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
-
576
544
// We've successfully resolved the import. Write the results in.
577
545
let mut import_resolutions = module_. import_resolutions . borrow_mut ( ) ;
578
546
@@ -621,7 +589,6 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
621
589
import_resolution,
622
590
directive. span ,
623
591
( target, namespace) ) ;
624
-
625
592
} ;
626
593
check_and_write_import ( ValueNS , & value_result, & mut value_used_public) ;
627
594
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> {
631
598
let msg = format ! ( "There is no `{}` in `{}`{}" ,
632
599
source,
633
600
module_to_string( & target_module) , lev_suggestion) ;
634
- return ResolveResult :: Failed ( Some ( ( directive. span , msg) ) ) ;
601
+ return Failed ( Some ( ( directive. span , msg) ) ) ;
635
602
}
603
+
636
604
let value_used_public = value_used_reexport || value_used_public;
637
605
let type_used_public = type_used_reexport || type_used_public;
638
606
@@ -646,12 +614,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
646
614
// purposes it's good enough to just favor one over the other.
647
615
import_resolution_value. target . as_ref ( ) . map ( |target| {
648
616
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)
655
619
} )
656
620
} ;
657
621
@@ -662,12 +626,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
662
626
663
627
import_resolution_type. target . as_ref ( ) . map ( |target| {
664
628
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)
671
631
} )
672
632
} ;
673
633
@@ -696,7 +656,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
696
656
}
697
657
698
658
debug ! ( "(resolving single import) successfully resolved import" ) ;
699
- return ResolveResult :: Success ( ( ) ) ;
659
+ return Success ( ( ) ) ;
700
660
}
701
661
702
662
// Resolves a glob import. Note that this function cannot fail; it either
0 commit comments