mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Rollup merge of #98087 - TaKO8Ki:suggest-adding-macro-export, r=oli-obk
Suggest adding a `#[macro_export]` to a private macro fixes #97628
This commit is contained in:
commit
b2d0e7838e
@ -10,7 +10,9 @@ use crate::imports::{Import, ImportKind};
|
|||||||
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||||
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
|
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
|
||||||
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
|
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
|
||||||
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError};
|
use crate::{
|
||||||
|
MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError,
|
||||||
|
};
|
||||||
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
|
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError};
|
||||||
|
|
||||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
||||||
@ -20,7 +22,6 @@ use rustc_ast_lowering::ResolverAstLowering;
|
|||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_errors::{struct_span_err, Applicability};
|
use rustc_errors::{struct_span_err, Applicability};
|
||||||
use rustc_expand::base::SyntaxExtension;
|
|
||||||
use rustc_expand::expand::AstFragment;
|
use rustc_expand::expand::AstFragment;
|
||||||
use rustc_hir::def::{self, *};
|
use rustc_hir::def::{self, *};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
||||||
@ -180,26 +181,32 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
|
pub(crate) fn get_macro(&mut self, res: Res) -> Option<MacroData> {
|
||||||
match res {
|
match res {
|
||||||
Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
|
Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
|
||||||
Res::NonMacroAttr(_) => Some(self.non_macro_attr.clone()),
|
Res::NonMacroAttr(_) => {
|
||||||
|
Some(MacroData { ext: self.non_macro_attr.clone(), macro_rules: false })
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> Lrc<SyntaxExtension> {
|
pub(crate) fn get_macro_by_def_id(&mut self, def_id: DefId) -> MacroData {
|
||||||
if let Some(ext) = self.macro_map.get(&def_id) {
|
if let Some(macro_data) = self.macro_map.get(&def_id) {
|
||||||
return ext.clone();
|
return macro_data.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) {
|
let (ext, macro_rules) = match self.cstore().load_macro_untracked(def_id, &self.session) {
|
||||||
LoadedMacro::MacroDef(item, edition) => self.compile_macro(&item, edition).0,
|
LoadedMacro::MacroDef(item, edition) => (
|
||||||
LoadedMacro::ProcMacro(ext) => ext,
|
Lrc::new(self.compile_macro(&item, edition).0),
|
||||||
});
|
matches!(item.kind, ItemKind::MacroDef(def) if def.macro_rules),
|
||||||
|
),
|
||||||
|
LoadedMacro::ProcMacro(extz) => (Lrc::new(extz), false),
|
||||||
|
};
|
||||||
|
|
||||||
self.macro_map.insert(def_id, ext.clone());
|
let macro_data = MacroData { ext, macro_rules };
|
||||||
ext
|
self.macro_map.insert(def_id, macro_data.clone());
|
||||||
|
macro_data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_reduced_graph(
|
pub(crate) fn build_reduced_graph(
|
||||||
@ -1251,7 +1258,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
|
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
|
||||||
self.r.macro_map.insert(def_id.to_def_id(), ext);
|
self.r.macro_map.insert(def_id.to_def_id(), MacroData { ext, macro_rules });
|
||||||
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
|
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
|
||||||
|
|
||||||
if macro_rules {
|
if macro_rules {
|
||||||
|
@ -241,7 +241,7 @@ impl<'a> Resolver<'a> {
|
|||||||
{
|
{
|
||||||
// The macro is a proc macro derive
|
// The macro is a proc macro derive
|
||||||
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
|
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
|
||||||
let ext = self.get_macro_by_def_id(def_id);
|
let ext = self.get_macro_by_def_id(def_id).ext;
|
||||||
if ext.builtin_name.is_none()
|
if ext.builtin_name.is_none()
|
||||||
&& ext.macro_kind() == MacroKind::Derive
|
&& ext.macro_kind() == MacroKind::Derive
|
||||||
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
|
&& parent.expansion.outer_expn_is_descendant_of(*ctxt)
|
||||||
|
@ -12,7 +12,7 @@ use rustc_ast::NodeId;
|
|||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::intern::Interned;
|
use rustc_data_structures::intern::Interned;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
|
||||||
use rustc_hir::def::{self, PartialRes};
|
use rustc_hir::def::{self, DefKind, PartialRes};
|
||||||
use rustc_middle::metadata::ModChild;
|
use rustc_middle::metadata::ModChild;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
@ -922,11 +922,28 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
|||||||
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
|
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
let note_msg =
|
let mut err =
|
||||||
format!("consider marking `{}` as `pub` in the imported module", ident);
|
struct_span_err!(self.r.session, import.span, E0364, "{error_msg}");
|
||||||
struct_span_err!(self.r.session, import.span, E0364, "{}", error_msg)
|
match binding.kind {
|
||||||
.span_note(import.span, ¬e_msg)
|
NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id), _)
|
||||||
.emit();
|
// exclude decl_macro
|
||||||
|
if self.r.get_macro_by_def_id(def_id).macro_rules =>
|
||||||
|
{
|
||||||
|
err.span_help(
|
||||||
|
binding.span,
|
||||||
|
"consider adding a `#[macro_export]` to the macro in the imported module",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
err.span_note(
|
||||||
|
import.span,
|
||||||
|
&format!(
|
||||||
|
"consider marking `{ident}` as `pub` in the imported module"
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -866,6 +866,12 @@ struct DeriveData {
|
|||||||
has_derive_copy: bool,
|
has_derive_copy: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct MacroData {
|
||||||
|
ext: Lrc<SyntaxExtension>,
|
||||||
|
macro_rules: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// The main resolver class.
|
/// The main resolver class.
|
||||||
///
|
///
|
||||||
/// This is the visitor that walks the whole crate.
|
/// This is the visitor that walks the whole crate.
|
||||||
@ -965,7 +971,7 @@ pub struct Resolver<'a> {
|
|||||||
registered_attrs: FxHashSet<Ident>,
|
registered_attrs: FxHashSet<Ident>,
|
||||||
registered_tools: RegisteredTools,
|
registered_tools: RegisteredTools,
|
||||||
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
macro_use_prelude: FxHashMap<Symbol, &'a NameBinding<'a>>,
|
||||||
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
|
macro_map: FxHashMap<DefId, MacroData>,
|
||||||
dummy_ext_bang: Lrc<SyntaxExtension>,
|
dummy_ext_bang: Lrc<SyntaxExtension>,
|
||||||
dummy_ext_derive: Lrc<SyntaxExtension>,
|
dummy_ext_derive: Lrc<SyntaxExtension>,
|
||||||
non_macro_attr: Lrc<SyntaxExtension>,
|
non_macro_attr: Lrc<SyntaxExtension>,
|
||||||
@ -1522,7 +1528,7 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_builtin_macro(&mut self, res: Res) -> bool {
|
fn is_builtin_macro(&mut self, res: Res) -> bool {
|
||||||
self.get_macro(res).map_or(false, |ext| ext.builtin_name.is_some())
|
self.get_macro(res).map_or(false, |macro_data| macro_data.ext.builtin_name.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
|
fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId {
|
||||||
|
@ -658,7 +658,7 @@ impl<'a> Resolver<'a> {
|
|||||||
res
|
res
|
||||||
};
|
};
|
||||||
|
|
||||||
res.map(|res| (self.get_macro(res), res))
|
res.map(|res| (self.get_macro(res).map(|macro_data| macro_data.ext), res))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn finalize_macro_resolutions(&mut self) {
|
pub(crate) fn finalize_macro_resolutions(&mut self) {
|
||||||
@ -853,7 +853,7 @@ impl<'a> Resolver<'a> {
|
|||||||
// Reserve some names that are not quite covered by the general check
|
// Reserve some names that are not quite covered by the general check
|
||||||
// performed on `Resolver::builtin_attrs`.
|
// performed on `Resolver::builtin_attrs`.
|
||||||
if ident.name == sym::cfg || ident.name == sym::cfg_attr {
|
if ident.name == sym::cfg || ident.name == sym::cfg_attr {
|
||||||
let macro_kind = self.get_macro(res).map(|ext| ext.macro_kind());
|
let macro_kind = self.get_macro(res).map(|macro_data| macro_data.ext.macro_kind());
|
||||||
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
|
if macro_kind.is_some() && sub_namespace_match(macro_kind, Some(MacroKind::Attr)) {
|
||||||
self.session.span_err(
|
self.session.span_err(
|
||||||
ident.span,
|
ident.span,
|
||||||
|
17
src/test/ui/privacy/macro-private-reexport.rs
Normal file
17
src/test/ui/privacy/macro-private-reexport.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(decl_macro)]
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
macro_rules! bar {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use bar as _; //~ ERROR `bar` is only public within the crate, and cannot be re-exported outside
|
||||||
|
|
||||||
|
macro baz() {}
|
||||||
|
|
||||||
|
pub use baz as _; //~ ERROR `baz` is private, and cannot be re-exported
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
29
src/test/ui/privacy/macro-private-reexport.stderr
Normal file
29
src/test/ui/privacy/macro-private-reexport.stderr
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
error[E0364]: `bar` is only public within the crate, and cannot be re-exported outside
|
||||||
|
--> $DIR/macro-private-reexport.rs:10:13
|
||||||
|
|
|
||||||
|
LL | pub use bar as _;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
help: consider adding a `#[macro_export]` to the macro in the imported module
|
||||||
|
--> $DIR/macro-private-reexport.rs:6:5
|
||||||
|
|
|
||||||
|
LL | / macro_rules! bar {
|
||||||
|
LL | | () => {};
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
||||||
|
error[E0364]: `baz` is private, and cannot be re-exported
|
||||||
|
--> $DIR/macro-private-reexport.rs:14:13
|
||||||
|
|
|
||||||
|
LL | pub use baz as _;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
note: consider marking `baz` as `pub` in the imported module
|
||||||
|
--> $DIR/macro-private-reexport.rs:14:13
|
||||||
|
|
|
||||||
|
LL | pub use baz as _;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0364`.
|
@ -4,11 +4,11 @@ error[E0364]: `legacy_macro` is only public within the crate, and cannot be re-e
|
|||||||
LL | pub use legacy_macro as _;
|
LL | pub use legacy_macro as _;
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: consider marking `legacy_macro` as `pub` in the imported module
|
help: consider adding a `#[macro_export]` to the macro in the imported module
|
||||||
--> $DIR/macro-rules.rs:11:13
|
--> $DIR/macro-rules.rs:7:5
|
||||||
|
|
|
|
||||||
LL | pub use legacy_macro as _;
|
LL | macro_rules! legacy_macro { () => () }
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0659]: `legacy_macro` is ambiguous
|
error[E0659]: `legacy_macro` is ambiguous
|
||||||
--> $DIR/macro-rules.rs:31:13
|
--> $DIR/macro-rules.rs:31:13
|
||||||
|
Loading…
Reference in New Issue
Block a user