Rollup merge of #108729 - bvanjoi:fix-issue-97534, r=petrochenkov

fix: modify the condition that `resolve_imports` stops

close #97534
This commit is contained in:
Matthias Krüger 2023-03-21 19:00:12 +01:00 committed by GitHub
commit ee330a3ff5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 106 additions and 15 deletions

View File

@ -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),
}
}
}
@ -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),
@ -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,
}
};
@ -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() {
@ -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() => {
@ -670,7 +678,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
});
!indeterminate
indeterminate_count
}
/// Performs final import resolution, consistency checks and error reporting.

View File

@ -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() {
}