Skip to content
Open
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
45 changes: 39 additions & 6 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use Namespace::*;
use rustc_ast::{self as ast, NodeId};
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{DefKind, MacroKinds, Namespace, NonMacroAttrKind, PartialRes, PerNS};
use rustc_middle::{bug, span_bug};
use rustc_hir::def_id::DefId;
use rustc_middle::{bug, span_bug, ty};
use rustc_session::lint::builtin::PROC_MACRO_DERIVE_RESOLUTION_FALLBACK;
use rustc_session::parse::feature_err;
use rustc_span::hygiene::{ExpnId, ExpnKind, LocalExpnId, MacroKind, SyntaxContext};
Expand Down Expand Up @@ -640,6 +641,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

match result {
Ok((binding, flags)) => {
if !matches!(scope, Scope::MacroUsePrelude) {
let adjusted_module = if let Scope::Module(module, _) = scope
&& !matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..))
{
module
} else {
parent_scope.module
};
if !this.is_accessible_from(binding.vis, adjusted_module) {
this.dcx()
.struct_span_err(binding.span, "binding")
.with_span_label(adjusted_module.span, "module")
.emit();
}
}

if !sub_namespace_match(binding.macro_kinds(), macro_kind) {
return None;
}
Expand All @@ -648,14 +665,30 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
// We do not need to report them if we are either in speculative resolution,
// or in late resolution when everything is already imported and expanded
// and no ambiguities exist.
if matches!(finalize, None | Some(Finalize { stage: Stage::Late, .. })) {
return Some(Ok(binding));
}
let (significant_visibility, import_vis) = match finalize {
None | Some(Finalize { stage: Stage::Late, .. }) => {
return Some(Ok(binding));
}
Some(Finalize { significant_visibility, import_vis, .. }) => {
(significant_visibility, import_vis)
}
};

if let Some((innermost_binding, innermost_flags)) = innermost_result {
// Found another solution, if the first one was "weak", report an error.
let (res, innermost_res) = (binding.res(), innermost_binding.res());
if res != innermost_res {

let vis_min = |v1: ty::Visibility<DefId>, v2: ty::Visibility<DefId>| {
if v1.is_at_least(v2, this.tcx) { v2 } else { v1 }
};
let bad_vis = significant_visibility
&& vis_min(binding.vis, import_vis.unwrap().to_def_id())
!= vis_min(
innermost_binding.vis,
import_vis.unwrap().to_def_id(),
);

if res != innermost_res || bad_vis {
let is_builtin = |res| {
matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..)))
};
Expand Down Expand Up @@ -1065,7 +1098,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&& shadowing == Shadowing::Restricted
&& finalize.stage == Stage::Early
&& binding.expansion != LocalExpnId::ROOT
&& binding.res() != shadowed_glob.res()
&& (binding.res() != shadowed_glob.res() || finalize.significant_visibility)
{
self.ambiguity_errors.push(AmbiguityError {
kind: AmbiguityKind::GlobVsExpanded,
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&& non_glob_binding.expansion != LocalExpnId::ROOT
&& glob_binding.res() != non_glob_binding.res()
{
// FIXME: record vis mismatches as well, but breakage in practice.
resolution.non_glob_binding = Some(this.new_ambiguity_binding(
AmbiguityKind::GlobVsExpanded,
non_glob_binding,
Expand All @@ -413,7 +414,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
glob_binding,
false,
));
} else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) {
} else if !old_glob_binding.vis.is_at_least(glob_binding.vis, this.tcx)
{
resolution.glob_binding = Some(glob_binding);
}
} else {
Expand Down Expand Up @@ -957,7 +959,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
&import.module_path,
None,
&import.parent_scope,
Some(finalize),
Some(Finalize { significant_visibility: false, ..finalize }),
ignore_binding,
Some(import),
);
Expand Down Expand Up @@ -1135,7 +1137,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
ident,
ns,
&import.parent_scope,
Some(Finalize { report_private: false, ..finalize }),
Some(Finalize {
report_private: false,
import_vis: Some(import.vis),
..finalize
}),
bindings[ns].get().binding(),
Some(import),
);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
opt_ns,
&self.parent_scope,
Some(source),
finalize,
finalize.map(|finalize| Finalize { significant_visibility: false, ..finalize }),
Some(&self.ribs),
None,
None,
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2035,6 +2035,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
warn_ambiguity: bool,
) {
if let Some((b2, kind)) = used_binding.ambiguity {
// FIXME: Need to check if the `AmbiguityKind::GlobVsGlob`s caused by visibility
// mismatch ever passed through an import, but it's too breaking.
let ambiguity_error = AmbiguityError {
kind,
ident,
Expand Down Expand Up @@ -2506,6 +2508,11 @@ struct Finalize {
used: Used = Used::Other,
/// Finalizing early or late resolution.
stage: Stage = Stage::Early,
/// Ambiguous bindings with different visibilities need to be reported
/// even if they have the same `Res`olutions.
significant_visibility: bool = true,
/// Tralala
import_vis: Option<Visibility> = None,
}

impl Finalize {
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,11 +867,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
for seg in &mut path {
seg.id = None;
}

let finalize = Finalize::new(ast::CRATE_NODE_ID, path_span);
match self.cm().resolve_path(
&path,
Some(ns),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, path_span)),
Some(Finalize { significant_visibility: false, ..finalize }),
None,
None,
) {
Expand Down Expand Up @@ -940,11 +942,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

let macro_resolutions = self.single_segment_macro_resolutions.take(self);
for (ident, kind, parent_scope, initial_binding, sugg_span) in macro_resolutions {
let finalize = Finalize::new(ast::CRATE_NODE_ID, ident.span);
match self.cm().resolve_ident_in_scope_set(
ident,
ScopeSet::Macro(kind),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
Some(Finalize { significant_visibility: false, ..finalize }),
true,
None,
None,
Expand Down Expand Up @@ -995,11 +998,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {

let builtin_attrs = mem::take(&mut self.builtin_attrs);
for (ident, parent_scope) in builtin_attrs {
let finalize = Finalize::new(ast::CRATE_NODE_ID, ident.span);
let _ = self.cm().resolve_ident_in_scope_set(
ident,
ScopeSet::Macro(MacroKind::Attr),
&parent_scope,
Some(Finalize::new(ast::CRATE_NODE_ID, ident.span)),
Some(Finalize { significant_visibility: false, ..finalize }),
true,
None,
None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ globbing! {} // this imports the same `RustEmbed` macro with `pub` visibility

pub trait RustEmbed {}

pub use RustEmbed as Embed;
pub use self::RustEmbed as Embed;
2 changes: 1 addition & 1 deletion tests/ui/imports/auxiliary/same-res-ambigious-extern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ pub use same_res_ambigious_extern_macro::*;

pub trait RustEmbed {}

pub use RustEmbed as Embed;
pub use self::RustEmbed as Embed;
20 changes: 0 additions & 20 deletions tests/ui/imports/same-res-ambigious.fail.stderr

This file was deleted.

4 changes: 2 additions & 2 deletions tests/ui/imports/same-res-ambigious.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
//@ edition: 2018
//@ revisions: fail pass
//@[pass] check-pass
//@ check-pass
//@[pass] aux-crate: ambigious_extern=same-res-ambigious-extern.rs
//@[fail] aux-crate: ambigious_extern=same-res-ambigious-extern-fail.rs
// see https://github.com/rust-lang/rust/pull/147196

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

fn main(){}
Loading