Skip to content

Commit 1775722

Browse files
committed
fix: modify the condition that resolve_imports stops
1 parent ab9bb3e commit 1775722

File tree

2 files changed

+106
-15
lines changed

2 files changed

+106
-15
lines changed

compiler/rustc_resolve/src/imports.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -423,13 +423,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
423423
/// Resolves all imports for the crate. This method performs the fixed-
424424
/// point iteration.
425425
pub(crate) fn resolve_imports(&mut self) {
426-
let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1;
427-
while self.indeterminate_imports.len() < prev_num_indeterminates {
428-
prev_num_indeterminates = self.indeterminate_imports.len();
426+
let mut prev_indeterminate_count = usize::MAX;
427+
let mut indeterminate_count = self.indeterminate_imports.len() * 3;
428+
while indeterminate_count < prev_indeterminate_count {
429+
prev_indeterminate_count = indeterminate_count;
430+
indeterminate_count = 0;
429431
for import in mem::take(&mut self.indeterminate_imports) {
430-
match self.resolve_import(&import) {
431-
true => self.determined_imports.push(import),
432-
false => self.indeterminate_imports.push(import),
432+
let import_indeterminate_count = self.resolve_import(&import);
433+
indeterminate_count += import_indeterminate_count;
434+
match import_indeterminate_count {
435+
0 => self.determined_imports.push(import),
436+
_ => self.indeterminate_imports.push(import),
433437
}
434438
}
435439
}
@@ -581,9 +585,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
581585
diag.emit();
582586
}
583587

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

602610
match path_res {
603611
PathResult::Module(module) => module,
604-
PathResult::Indeterminate => return false,
605-
PathResult::NonModule(..) | PathResult::Failed { .. } => return true,
612+
PathResult::Indeterminate => return 3,
613+
PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
606614
}
607615
};
608616

@@ -618,12 +626,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
618626
} => (source, target, source_bindings, target_bindings, type_ns_only),
619627
ImportKind::Glob { .. } => {
620628
self.resolve_glob_import(import);
621-
return true;
629+
return 0;
622630
}
623631
_ => unreachable!(),
624632
};
625633

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

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

673-
!indeterminate
681+
indeterminate_count
674682
}
675683

676684
/// Performs final import resolution, consistency checks and error reporting.

tests/ui/macros/nested-use-as.rs

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// check-pass
2+
// edition:2018
3+
// issue: https://github.com/rust-lang/rust/issues/97534
4+
5+
macro_rules! m {
6+
() => {
7+
macro_rules! foo {
8+
() => {}
9+
}
10+
use foo as bar;
11+
}
12+
}
13+
14+
m!{}
15+
16+
use bar as baz;
17+
18+
baz!{}
19+
20+
macro_rules! foo2 {
21+
() => {};
22+
}
23+
24+
macro_rules! m2 {
25+
() => {
26+
use foo2 as bar2;
27+
};
28+
}
29+
30+
m2! {}
31+
32+
use bar2 as baz2;
33+
34+
baz2! {}
35+
36+
macro_rules! n1 {
37+
() => {
38+
macro_rules! n2 {
39+
() => {
40+
macro_rules! n3 {
41+
() => {
42+
macro_rules! n4 {
43+
() => {}
44+
}
45+
use n4 as c4;
46+
}
47+
}
48+
use n3 as c3;
49+
}
50+
}
51+
use n2 as c2;
52+
}
53+
}
54+
55+
use n1 as c1;
56+
c1!{}
57+
use c2 as a2;
58+
a2!{}
59+
use c3 as a3;
60+
a3!{}
61+
use c4 as a4;
62+
a4!{}
63+
64+
// https://github.com/rust-lang/rust/pull/108729#issuecomment-1474750675
65+
// reversed
66+
use d5 as d6;
67+
use d4 as d5;
68+
use d3 as d4;
69+
use d2 as d3;
70+
use d1 as d2;
71+
use foo2 as d1;
72+
d6! {}
73+
74+
// mess
75+
use f3 as f4;
76+
f5! {}
77+
use f1 as f2;
78+
use f4 as f5;
79+
use f2 as f3;
80+
use foo2 as f1;
81+
82+
fn main() {
83+
}

0 commit comments

Comments
 (0)