Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: modify the condition that resolve_imports stops #108729

Merged
merged 1 commit into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {
}