Skip to content

Commit e13a045

Browse files
committed
Clean up resolve_single_import
1 parent 118c93b commit e13a045

File tree

1 file changed

+66
-106
lines changed

1 file changed

+66
-106
lines changed

src/librustc_resolve/resolve_imports.rs

Lines changed: 66 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)