Skip to content

Commit 0e7f93c

Browse files
Auto merge of #149145 - petrochenkov:visambig, r=<try>
[WIP] resolve: Make ambiguity checking stricter
2 parents 683dd08 + bf5f878 commit 0e7f93c

File tree

8 files changed

+44
-34
lines changed

8 files changed

+44
-34
lines changed

compiler/rustc_resolve/src/ident.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
640640

641641
match result {
642642
Ok((binding, flags)) => {
643+
if !matches!(scope, Scope::MacroUsePrelude) {
644+
let adjusted_module = if let Scope::Module(module, _) = scope
645+
&& !matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..))
646+
{
647+
module
648+
} else {
649+
parent_scope.module
650+
};
651+
if !this.is_accessible_from(binding.vis, adjusted_module) {
652+
this.dcx()
653+
.struct_span_err(binding.span, "binding")
654+
.with_span_label(adjusted_module.span, "module")
655+
.emit();
656+
}
657+
}
658+
643659
if !sub_namespace_match(binding.macro_kinds(), macro_kind) {
644660
return None;
645661
}
@@ -648,14 +664,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
648664
// We do not need to report them if we are either in speculative resolution,
649665
// or in late resolution when everything is already imported and expanded
650666
// and no ambiguities exist.
651-
if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
652-
return Some(Ok(binding));
653-
}
667+
let significant_visibility = match finalize {
668+
None | Some(Finalize { stage: Stage::Late, .. }) => {
669+
return Some(Ok(binding));
670+
}
671+
Some(Finalize { significant_visibility, .. }) => significant_visibility,
672+
};
654673

655674
if let Some((innermost_binding, innermost_flags)) = innermost_result {
656675
// Found another solution, if the first one was "weak", report an error.
657676
let (res, innermost_res) = (binding.res(), innermost_binding.res());
658-
if res != innermost_res {
677+
if res != innermost_res || significant_visibility {
659678
let is_builtin = |res| {
660679
matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
661680
};
@@ -1065,7 +1084,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
10651084
&& shadowing == Shadowing::Restricted
10661085
&& finalize.stage == Stage::Early
10671086
&& binding.expansion != LocalExpnId::ROOT
1068-
&& binding.res() != shadowed_glob.res()
1087+
&& (binding.res() != shadowed_glob.res() || finalize.significant_visibility)
10691088
{
10701089
self.ambiguity_errors.push(AmbiguityError {
10711090
kind: AmbiguityKind::GlobVsExpanded,

compiler/rustc_resolve/src/imports.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
394394
&& non_glob_binding.expansion != LocalExpnId::ROOT
395395
&& glob_binding.res() != non_glob_binding.res()
396396
{
397+
// FIXME: record vis mismatches as well, but breakage in practice.
397398
resolution.non_glob_binding = Some(this.new_ambiguity_binding(
398399
AmbiguityKind::GlobVsExpanded,
399400
non_glob_binding,
@@ -413,7 +414,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
413414
glob_binding,
414415
false,
415416
));
416-
} else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) {
417+
} else if !old_glob_binding.vis.is_at_least(glob_binding.vis, this.tcx)
418+
{
417419
resolution.glob_binding = Some(glob_binding);
418420
}
419421
} else {
@@ -957,7 +959,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
957959
&import.module_path,
958960
None,
959961
&import.parent_scope,
960-
Some(finalize),
962+
Some(Finalize { significant_visibility: false, ..finalize }),
961963
ignore_binding,
962964
Some(import),
963965
);

compiler/rustc_resolve/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20352035
warn_ambiguity: bool,
20362036
) {
20372037
if let Some((b2, kind)) = used_binding.ambiguity {
2038+
// FIXME: Need to check if the `AmbiguityKind::GlobVsGlob`s caused by visibility
2039+
// mismatch ever passed through an import, but it's too breaking.
20382040
let ambiguity_error = AmbiguityError {
20392041
kind,
20402042
ident,
@@ -2506,6 +2508,9 @@ struct Finalize {
25062508
used: Used = Used::Other,
25072509
/// Finalizing early or late resolution.
25082510
stage: Stage = Stage::Early,
2511+
/// Ambiguous bindings with different visibilities need to be reported
2512+
/// even if they have the same `Res`olutions.
2513+
significant_visibility: bool = true,
25092514
}
25102515

25112516
impl Finalize {

compiler/rustc_resolve/src/macros.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
867867
for seg in &mut path {
868868
seg.id = None;
869869
}
870+
871+
let finalize = Finalize::new(ast::CRATE_NODE_ID, path_span);
870872
match self.cm().resolve_path(
871873
&path,
872874
Some(ns),
873875
&parent_scope,
874-
Some(Finalize::new(ast::CRATE_NODE_ID, path_span)),
876+
Some(Finalize { significant_visibility: false, ..finalize }),
875877
None,
876878
None,
877879
) {
@@ -940,11 +942,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
940942

941943
let macro_resolutions = self.single_segment_macro_resolutions.take(self);
942944
for (ident, kind, parent_scope, initial_binding, sugg_span) in macro_resolutions {
945+
let finalize = Finalize::new(ast::CRATE_NODE_ID, ident.span);
943946
match self.cm().resolve_ident_in_scope_set(
944947
ident,
945948
ScopeSet::Macro(kind),
946949
&parent_scope,
947-
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
950+
Some(Finalize { significant_visibility: false, ..finalize }),
948951
true,
949952
None,
950953
None,
@@ -995,11 +998,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
995998

996999
let builtin_attrs = mem::take(&mut self.builtin_attrs);
9971000
for (ident, parent_scope) in builtin_attrs {
1001+
let finalize = Finalize::new(ast::CRATE_NODE_ID, ident.span);
9981002
let _ = self.cm().resolve_ident_in_scope_set(
9991003
ident,
10001004
ScopeSet::Macro(MacroKind::Attr),
10011005
&parent_scope,
1002-
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
1006+
Some(Finalize { significant_visibility: false, ..finalize }),
10031007
true,
10041008
None,
10051009
None,

tests/ui/imports/auxiliary/same-res-ambigious-extern-fail.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ globbing! {} // this imports the same `RustEmbed` macro with `pub` visibility
1313

1414
pub trait RustEmbed {}
1515

16-
pub use RustEmbed as Embed;
16+
pub use self::RustEmbed as Embed;

tests/ui/imports/auxiliary/same-res-ambigious-extern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ pub use same_res_ambigious_extern_macro::*;
88

99
pub trait RustEmbed {}
1010

11-
pub use RustEmbed as Embed;
11+
pub use self::RustEmbed as Embed;

tests/ui/imports/same-res-ambigious.fail.stderr

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//@ edition: 2018
22
//@ revisions: fail pass
3-
//@[pass] check-pass
3+
//@ check-pass
44
//@[pass] aux-crate: ambigious_extern=same-res-ambigious-extern.rs
55
//@[fail] aux-crate: ambigious_extern=same-res-ambigious-extern-fail.rs
66
// see https://github.com/rust-lang/rust/pull/147196
77

8-
#[derive(ambigious_extern::Embed)] //[fail]~ ERROR: derive macro `Embed` is private
8+
#[derive(ambigious_extern::Embed)]
99
struct Foo{}
1010

1111
fn main(){}

0 commit comments

Comments
 (0)