Rollup merge of #119369 - bvanjoi:fix-119301, r=petrochenkov

exclude unexported macro bindings from extern crate

Fixes #119301

Macros that aren't exported from an external crate should not be defined.

r? ``@petrochenkov``
This commit is contained in:
Matthias Krüger 2024-01-22 16:13:25 +01:00 committed by GitHub
commit c5984caa44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 149 additions and 17 deletions

View file

@ -1029,9 +1029,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
}
}
let macro_use_import = |this: &Self, span| {
let macro_use_import = |this: &Self, span, warn_private| {
this.r.arenas.alloc_import(ImportData {
kind: ImportKind::MacroUse,
kind: ImportKind::MacroUse { warn_private },
root_id: item.id,
parent_scope: this.parent_scope,
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
@ -1048,11 +1048,25 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
let allow_shadowing = self.parent_scope.expansion == LocalExpnId::ROOT;
if let Some(span) = import_all {
let import = macro_use_import(self, span);
let import = macro_use_import(self, span, false);
self.r.potentially_unused_imports.push(import);
module.for_each_child(self, |this, ident, ns, binding| {
if ns == MacroNS {
let imported_binding = this.r.import(binding, import);
let imported_binding =
if this.r.is_accessible_from(binding.vis, this.parent_scope.module) {
this.r.import(binding, import)
} else if !this.r.is_builtin_macro(binding.res())
&& !this.r.macro_use_prelude.contains_key(&ident.name)
{
// - `!r.is_builtin_macro(res)` excluding the built-in macros such as `Debug` or `Hash`.
// - `!r.macro_use_prelude.contains_key(name)` excluding macros defined in other extern
// crates such as `std`.
// FIXME: This branch should eventually be removed.
let import = macro_use_import(this, span, true);
this.r.import(binding, import)
} else {
return;
};
this.add_macro_use_binding(ident.name, imported_binding, span, allow_shadowing);
}
});
@ -1065,7 +1079,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
&self.parent_scope,
);
if let Ok(binding) = result {
let import = macro_use_import(self, ident.span);
let import = macro_use_import(self, ident.span, false);
self.r.potentially_unused_imports.push(import);
let imported_binding = self.r.import(binding, import);
self.add_macro_use_binding(

View file

@ -290,7 +290,7 @@ impl Resolver<'_, '_> {
|| import.expect_vis().is_public()
|| import.span.is_dummy() =>
{
if let ImportKind::MacroUse = import.kind {
if let ImportKind::MacroUse { .. } = import.kind {
if !import.span.is_dummy() {
self.lint_buffer.buffer_lint(
MACRO_USE_EXTERN_CRATE,
@ -315,7 +315,7 @@ impl Resolver<'_, '_> {
maybe_unused_extern_crates.insert(id, import.span);
}
}
ImportKind::MacroUse => {
ImportKind::MacroUse { .. } => {
let msg = "unused `#[macro_use]` import";
self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.root_id, import.span, msg);
}

View file

@ -285,7 +285,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
use NameBindingKind::Import;
let can_suggest = |binding: NameBinding<'_>, import: self::Import<'_>| {
!binding.span.is_dummy()
&& !matches!(import.kind, ImportKind::MacroUse | ImportKind::MacroExport)
&& !matches!(import.kind, ImportKind::MacroUse { .. } | ImportKind::MacroExport)
};
let import = match (&new_binding.kind, &old_binding.kind) {
// If there are two imports where one or both have attributes then prefer removing the
@ -1819,9 +1819,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
next_ident = source;
Some(binding)
}
ImportKind::Glob { .. } | ImportKind::MacroUse | ImportKind::MacroExport => {
Some(binding)
}
ImportKind::Glob { .. }
| ImportKind::MacroUse { .. }
| ImportKind::MacroExport => Some(binding),
ImportKind::ExternCrate { .. } => None,
},
_ => None,

View file

@ -80,7 +80,11 @@ pub(crate) enum ImportKind<'a> {
target: Ident,
id: NodeId,
},
MacroUse,
MacroUse {
/// A field has been added indicating whether it should be reported as a lint,
/// addressing issue#119301.
warn_private: bool,
},
MacroExport,
}
@ -127,7 +131,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
.field("target", target)
.field("id", id)
.finish(),
MacroUse => f.debug_struct("MacroUse").finish(),
MacroUse { .. } => f.debug_struct("MacroUse").finish(),
MacroExport => f.debug_struct("MacroExport").finish(),
}
}
@ -197,7 +201,7 @@ impl<'a> ImportData<'a> {
ImportKind::Single { id, .. }
| ImportKind::Glob { id, .. }
| ImportKind::ExternCrate { id, .. } => Some(id),
ImportKind::MacroUse | ImportKind::MacroExport => None,
ImportKind::MacroUse { .. } | ImportKind::MacroExport => None,
}
}
@ -207,7 +211,7 @@ impl<'a> ImportData<'a> {
ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
ImportKind::MacroUse => Reexport::MacroUse,
ImportKind::MacroUse { .. } => Reexport::MacroUse,
ImportKind::MacroExport => Reexport::MacroExport,
}
}
@ -1482,7 +1486,7 @@ fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
ImportKind::Single { source, .. } => source.to_string(),
ImportKind::Glob { .. } => "*".to_string(),
ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
ImportKind::MacroUse => "#[macro_use]".to_string(),
ImportKind::MacroUse { .. } => "#[macro_use]".to_string(),
ImportKind::MacroExport => "#[macro_export]".to_string(),
}
}

View file

@ -55,6 +55,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
use rustc_session::lint::LintBuffer;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
@ -1799,6 +1800,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
if let NameBindingKind::Import { import, binding, ref used } = used_binding.kind {
if let ImportKind::MacroUse { warn_private: true } = import.kind {
let msg = format!("macro `{ident}` is private");
self.lint_buffer().buffer_lint(PRIVATE_MACRO_USE, import.root_id, ident.span, msg);
}
// Avoid marking `extern crate` items that refer to a name from extern prelude,
// but not introduce it, as used if they are accessed from lexical scope.
if is_lexical_scope {