Skip to content

Commit f153650

Browse files
committed
resolve: determined binding after parent module macro expand
1 parent 1fe747c commit f153650

14 files changed

+154
-80
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
12391239
use_span_with_attributes: span,
12401240
use_span: span,
12411241
root_span: span,
1242-
span: span,
1242+
span,
12431243
module_path: Vec::new(),
12441244
vis: Cell::new(Some(vis)),
12451245
used: Cell::new(true),

compiler/rustc_resolve/src/ident.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -972,9 +972,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
972972
// progress, we have to ignore those potential unresolved invocations from other modules
973973
// and prohibit access to macro-expanded `macro_export` macros instead (unless restricted
974974
// shadowing is enabled, see `macro_expanded_macro_export_errors`).
975-
let unexpanded_macros = !module.unexpanded_invocations.borrow().is_empty();
976975
if let Some(binding) = binding {
977-
if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
976+
if binding.determined() || ns == MacroNS || restricted_shadowing {
978977
return check_usable(self, binding);
979978
} else {
980979
return Err((Undetermined, Weak::No));
@@ -991,7 +990,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
991990

992991
// Check if one of unexpanded macros can still define the name,
993992
// if it can then our "no resolution" result is not determined and can be invalidated.
994-
if unexpanded_macros {
993+
if !module.unexpanded_invocations.borrow().is_empty() {
995994
return Err((Undetermined, Weak::Yes));
996995
}
997996

compiler/rustc_resolve/src/imports.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
319319
// We should replace the `old_binding` with `binding` regardless
320320
// of whether they has same resolution or not when they are
321321
// imported from the same glob-import statement.
322-
// However we currently using `Some(old_binding)` for back compact
323-
// purposes.
324-
// This case can be removed after once `Undetermined` is prepared
325-
// for glob-imports.
322+
resolution.binding = Some(binding);
326323
} else if res != old_binding.res() {
327324
let binding = if warn_ambiguity {
328325
this.warn_ambiguity(
@@ -805,13 +802,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
805802
// For better failure detection, pretend that the import will
806803
// not define any names while resolving its module path.
807804
let orig_vis = import.vis.take();
808-
let binding = this.resolve_ident_in_module(
805+
let binding = this.maybe_resolve_ident_in_module(
809806
module,
810807
source,
811808
ns,
812809
&import.parent_scope,
813-
None,
814-
None,
815810
);
816811
import.vis.set(orig_vis);
817812
source_bindings[ns].set(binding);

compiler/rustc_resolve/src/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,19 @@ impl<'a> NameBindingData<'a> {
881881
invoc_parent_expansion.is_descendant_of(self_parent_expansion);
882882
!(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
883883
}
884+
885+
// Its purpose is to postpone the determination of a single binding because
886+
// we can't predict whether it will be overwritten by recently expanded macros.
887+
// FIXME: How can we integrate it with the `update_resolution`?
888+
fn determined(&self) -> bool {
889+
match &self.kind {
890+
NameBindingKind::Import { binding, import, .. } if import.is_glob() => {
891+
import.parent_scope.module.unexpanded_invocations.borrow().is_empty()
892+
&& binding.determined()
893+
}
894+
_ => true,
895+
}
896+
}
884897
}
885898

886899
#[derive(Default, Clone)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
3+
mod b {
4+
pub mod http {
5+
pub struct HeaderMap;
6+
}
7+
8+
pub use self::http::*;
9+
#[derive(Debug)]
10+
pub struct HeaderMap;
11+
}
12+
13+
use crate::b::*;
14+
15+
fn main() {
16+
let h: crate::b::HeaderMap = HeaderMap;
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// check-pass
2+
3+
#[derive(Debug)]
4+
struct H;
5+
6+
mod p {
7+
use super::*;
8+
9+
#[derive(Clone)]
10+
struct H;
11+
12+
mod t {
13+
use super::*;
14+
15+
fn f() {
16+
let h: crate::p::H = H;
17+
}
18+
}
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// check-pass
2+
// https://github.com/rust-lang/rust/issues/115377
3+
4+
use module::*;
5+
6+
mod module {
7+
pub enum B {}
8+
impl B {
9+
pub const ASSOC: u8 = 0;
10+
}
11+
}
12+
13+
#[derive()]
14+
pub enum B {}
15+
impl B {
16+
pub const ASSOC: u16 = 0;
17+
}
18+
19+
macro_rules! m {
20+
($right:expr) => {
21+
$right
22+
};
23+
}
24+
25+
fn main() {
26+
let a: u16 = {
27+
use self::*;
28+
B::ASSOC
29+
};
30+
let b: u16 = m!({
31+
use self::*;
32+
B::ASSOC
33+
});
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-pass
2+
// similar as `import-after-macro-expand-6.rs`
3+
4+
use crate::a::HeaderMap;
5+
6+
mod b {
7+
pub mod http {
8+
pub struct HeaderMap;
9+
}
10+
11+
pub use self::http::*;
12+
#[derive(Debug)]
13+
pub struct HeaderMap;
14+
}
15+
16+
mod a {
17+
pub use crate::b::*;
18+
}
19+
20+
fn main() {
21+
let h: crate::b::HeaderMap = HeaderMap;
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-pass
2+
3+
use crate::a::HeaderMap;
4+
5+
mod b {
6+
pub mod http {
7+
#[derive(Clone)]
8+
pub struct HeaderMap;
9+
}
10+
11+
pub use self::http::*;
12+
#[derive(Debug)]
13+
pub struct HeaderMap;
14+
}
15+
16+
mod a {
17+
pub use crate::b::*;
18+
}
19+
20+
fn main() {
21+
let h: crate::b::HeaderMap = HeaderMap;
22+
}

tests/ui/imports/import-after-macro-expand-2.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ mod tests {
1212
use super::*;
1313

1414
fn test_thing() {
15-
let thing: crate::thing::Thing = Thing::Bar;
16-
// FIXME: `thing` should refer to `crate::Thing`,
17-
// FIXME: but doesn't currently refer to it due to backward compatibility
15+
let thing: crate::Thing = Thing::Foo;
1816
}
1917
}
2018

tests/ui/imports/import-after-macro-expand-4.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// check-pass
12
// https://github.com/rust-lang/rust/pull/113242#issuecomment-1616034904
23
// similar with `import-after-macro-expand-2.rs`
34

@@ -10,16 +11,6 @@ pub use a::*;
1011
mod c {
1112
use crate::*;
1213
pub struct S(Vec<P>);
13-
//~^ ERROR the size for values of type
14-
//~| WARNING trait objects without an explicit
15-
//~| WARNING this is accepted in the current edition
16-
//~| WARNING trait objects without an explicit
17-
//~| WARNING this is accepted in the current edition
18-
//~| WARNING trait objects without an explicit
19-
//~| WARNING this is accepted in the current edition
20-
21-
// FIXME: should works, but doesn't currently refer
22-
// to it due to backward compatibility
2314
}
2415

2516
#[derive(Clone)]

tests/ui/imports/import-after-macro-expand-4.stderr

-53
This file was deleted.

tests/ui/imports/import-after-macro-expand-6.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,5 @@ mod b {
1818
use crate::a::HeaderMap;
1919

2020
fn main() {
21-
let h: crate::b::http::HeaderMap = HeaderMap;
22-
// FIXME: should refer to `crate::b::HeaderMap`,
23-
// FIXME: but doesn't currently refer to it due to backward compatibility
21+
let h: crate::b::HeaderMap = HeaderMap;
2422
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// check-pass
2+
3+
use crate::b::*;
4+
5+
mod b {
6+
pub mod http {
7+
pub struct HeaderMap;
8+
}
9+
10+
pub use self::http::*;
11+
#[derive(Debug)]
12+
pub struct HeaderMap;
13+
}
14+
15+
fn main() {
16+
let h: crate::b::HeaderMap = HeaderMap;
17+
}

0 commit comments

Comments
 (0)