Skip to content

Commit

Permalink
fix: modify the condition that resolve_imports stops
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanjoi committed Mar 19, 2023
1 parent ab9bb3e commit 1775722
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 15 deletions.
38 changes: 23 additions & 15 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Resolves all imports for the crate. This method performs the fixed-
/// point iteration.
pub(crate) fn resolve_imports(&mut self) {
let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
while self.indeterminate_imports.len() < prev_num_indeterminates {
prev_num_indeterminates = self.indeterminate_imports.len();
let mut prev_indeterminate_count = usize::MAX;
let mut indeterminate_count = self.indeterminate_imports.len() * 3;
while indeterminate_count < prev_indeterminate_count {
prev_indeterminate_count = indeterminate_count;
indeterminate_count = 0;
for import in mem::take(&mut self.indeterminate_imports) {
match self.resolve_import(&import) {
true => self.determined_imports.push(import),
false => self.indeterminate_imports.push(import),
let import_indeterminate_count = self.resolve_import(&import);
indeterminate_count += import_indeterminate_count;
match import_indeterminate_count {
0 => self.determined_imports.push(import),
_ => self.indeterminate_imports.push(import),
}
}
}
Expand Down Expand Up @@ -581,9 +585,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
diag.emit();
}

/// Attempts to resolve the given import, returning true if its resolution is determined.
/// If successful, the resolved bindings are written into the module.
fn resolve_import(&mut self, import: &'a Import<'a>) -> bool {
/// Attempts to resolve the given import, returning:
/// - `0` means its resolution is determined.
/// - Other values mean that indeterminate exists under certain namespaces.
///
/// Meanwhile, if resolve successful, the resolved bindings are written
/// into the module.
fn resolve_import(&mut self, import: &'a Import<'a>) -> usize {
debug!(
"(resolving import for module) resolving import `{}::...` in `{}`",
Segment::names_to_string(&import.module_path),
Expand All @@ -601,8 +609,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {

match path_res {
PathResult::Module(module) => module,
PathResult::Indeterminate => return false,
PathResult::NonModule(..) | PathResult::Failed { .. } => return true,
PathResult::Indeterminate => return 3,
PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
}
};

Expand All @@ -618,12 +626,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} => (source, target, source_bindings, target_bindings, type_ns_only),
ImportKind::Glob { .. } => {
self.resolve_glob_import(import);
return true;
return 0;
}
_ => unreachable!(),
};

let mut indeterminate = false;
let mut indeterminate_count = 0;
self.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
if let Err(Undetermined) = source_bindings[ns].get() {
Expand All @@ -646,7 +654,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {

let parent = import.parent_scope.module;
match source_bindings[ns].get() {
Err(Undetermined) => indeterminate = true,
Err(Undetermined) => indeterminate_count += 1,
// Don't update the resolution, because it was never added.
Err(Determined) if target.name == kw::Underscore => {}
Ok(binding) if binding.is_importable() => {
Expand All @@ -670,7 +678,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
});

!indeterminate
indeterminate_count
}

/// Performs final import resolution, consistency checks and error reporting.
Expand Down
83 changes: 83 additions & 0 deletions tests/ui/macros/nested-use-as.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// check-pass
// edition:2018
// issue: https://github.com/rust-lang/rust/issues/97534

macro_rules! m {
() => {
macro_rules! foo {
() => {}
}
use foo as bar;
}
}

m!{}

use bar as baz;

baz!{}

macro_rules! foo2 {
() => {};
}

macro_rules! m2 {
() => {
use foo2 as bar2;
};
}

m2! {}

use bar2 as baz2;

baz2! {}

macro_rules! n1 {
() => {
macro_rules! n2 {
() => {
macro_rules! n3 {
() => {
macro_rules! n4 {
() => {}
}
use n4 as c4;
}
}
use n3 as c3;
}
}
use n2 as c2;
}
}

use n1 as c1;
c1!{}
use c2 as a2;
a2!{}
use c3 as a3;
a3!{}
use c4 as a4;
a4!{}

// https://github.com/rust-lang/rust/pull/108729#issuecomment-1474750675
// reversed
use d5 as d6;
use d4 as d5;
use d3 as d4;
use d2 as d3;
use d1 as d2;
use foo2 as d1;
d6! {}

// mess
use f3 as f4;
f5! {}
use f1 as f2;
use f4 as f5;
use f2 as f3;
use foo2 as f1;

fn main() {
}

0 comments on commit 1775722

Please sign in to comment.