resolve: Implement a lint for out-of-scope use of macro_rules
This commit is contained in:
parent
0195758c1a
commit
c4c7859e40
12 changed files with 283 additions and 102 deletions
|
@ -604,6 +604,9 @@ lint_opaque_hidden_inferred_bound_sugg = add this bound
|
||||||
lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
|
lint_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
|
||||||
.suggestion = use pat_param to preserve semantics
|
.suggestion = use pat_param to preserve semantics
|
||||||
|
|
||||||
|
lint_out_of_scope_macro_calls = cannot find macro `{$path}` in this scope
|
||||||
|
.help = import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
lint_overflowing_bin_hex = literal out of range for `{$ty}`
|
lint_overflowing_bin_hex = literal out of range for `{$ty}`
|
||||||
.negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
|
.negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
|
||||||
.negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
|
.negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
|
||||||
|
|
|
@ -434,5 +434,8 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
|
||||||
lints::InnerAttributeUnstable::CustomInnerAttribute
|
lints::InnerAttributeUnstable::CustomInnerAttribute
|
||||||
}
|
}
|
||||||
.decorate_lint(diag),
|
.decorate_lint(diag),
|
||||||
|
BuiltinLintDiag::OutOfScopeMacroCalls { path } => {
|
||||||
|
lints::OutOfScopeMacroCalls { path }.decorate_lint(diag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2911,3 +2911,10 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion {
|
||||||
#[suggestion_part(code = ")")]
|
#[suggestion_part(code = ")")]
|
||||||
pub right: Span,
|
pub right: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(lint_out_of_scope_macro_calls)]
|
||||||
|
#[help]
|
||||||
|
pub struct OutOfScopeMacroCalls {
|
||||||
|
pub path: String,
|
||||||
|
}
|
||||||
|
|
|
@ -4945,3 +4945,42 @@ declare_lint! {
|
||||||
reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>",
|
reference: "issue #123757 <https://github.com/rust-lang/rust/issues/123757>",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope,
|
||||||
|
/// above their definition, which may happen in key-value attributes.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #![doc = in_root!()]
|
||||||
|
///
|
||||||
|
/// macro_rules! in_root { () => { "" } }
|
||||||
|
///
|
||||||
|
/// fn main() {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// The scope in which a `macro_rules` item is visible starts at that item and continues
|
||||||
|
/// below it. This is more similar to `let` than to other items, which are in scope both above
|
||||||
|
/// and below their definition.
|
||||||
|
/// Due to a bug `macro_rules` were accidentally in scope inside some key-value attributes
|
||||||
|
/// above their definition. The lint catches such cases.
|
||||||
|
/// To address the issue turn the `macro_rules` into a regularly scoped item by importing it
|
||||||
|
/// with `use`.
|
||||||
|
///
|
||||||
|
/// This is a [future-incompatible] lint to transition this to a
|
||||||
|
/// hard error in the future.
|
||||||
|
///
|
||||||
|
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||||
|
pub OUT_OF_SCOPE_MACRO_CALLS,
|
||||||
|
Warn,
|
||||||
|
"detects out of scope calls to `macro_rules` in key-value attributes",
|
||||||
|
@future_incompatible = FutureIncompatibleInfo {
|
||||||
|
reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
|
||||||
|
reference: "issue #124535 <https://github.com/rust-lang/rust/issues/124535>",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -744,6 +744,9 @@ pub enum BuiltinLintDiag {
|
||||||
InnerAttributeUnstable {
|
InnerAttributeUnstable {
|
||||||
is_macro: bool,
|
is_macro: bool,
|
||||||
},
|
},
|
||||||
|
OutOfScopeMacroCalls {
|
||||||
|
path: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lints that are buffered up early on in the `Session` before the
|
/// Lints that are buffered up early on in the `Session` before the
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, Modul
|
||||||
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError};
|
use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, ResolutionError};
|
||||||
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError};
|
use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, Used, VisResolutionError};
|
||||||
|
|
||||||
use rustc_ast::visit::{self, AssocCtxt, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
|
||||||
use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
|
use rustc_ast::{self as ast, AssocItem, AssocItemKind, MetaItemKind, StmtKind};
|
||||||
use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
|
use rustc_ast::{Block, ForeignItem, ForeignItemKind, Impl, Item, ItemKind, NodeId};
|
||||||
use rustc_attr as attr;
|
use rustc_attr as attr;
|
||||||
|
@ -1313,7 +1313,17 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
let orig_macro_rules_scope = self.parent_scope.macro_rules;
|
let orig_macro_rules_scope = self.parent_scope.macro_rules;
|
||||||
self.build_reduced_graph_for_item(item);
|
self.build_reduced_graph_for_item(item);
|
||||||
visit::walk_item(self, item);
|
match item.kind {
|
||||||
|
ItemKind::Mod(..) => {
|
||||||
|
// Visit attributes after items for backward compatibility.
|
||||||
|
// This way they can use `macro_rules` defined later.
|
||||||
|
self.visit_vis(&item.vis);
|
||||||
|
self.visit_ident(item.ident);
|
||||||
|
item.kind.walk(item, AssocCtxt::Trait, self);
|
||||||
|
visit::walk_list!(self, visit_attribute, &item.attrs);
|
||||||
|
}
|
||||||
|
_ => visit::walk_item(self, item),
|
||||||
|
}
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
|
ItemKind::Mod(..) if self.contains_macro_use(&item.attrs) => {
|
||||||
self.parent_scope.macro_rules
|
self.parent_scope.macro_rules
|
||||||
|
@ -1514,7 +1524,10 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||||
if krate.is_placeholder {
|
if krate.is_placeholder {
|
||||||
self.visit_invoc_in_module(krate.id);
|
self.visit_invoc_in_module(krate.id);
|
||||||
} else {
|
} else {
|
||||||
visit::walk_crate(self, krate);
|
// Visit attributes after items for backward compatibility.
|
||||||
|
// This way they can use `macro_rules` defined later.
|
||||||
|
visit::walk_list!(self, visit_item, &krate.items);
|
||||||
|
visit::walk_list!(self, visit_attribute, &krate.attrs);
|
||||||
self.contains_macro_use(&krate.attrs);
|
self.contains_macro_use(&krate.attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::errors::CannotDetermineMacroResolution;
|
||||||
use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope};
|
use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope};
|
||||||
use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive};
|
use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive};
|
||||||
use crate::Namespace::*;
|
use crate::Namespace::*;
|
||||||
use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, Used};
|
use crate::{BindingKey, BuiltinMacroState, Determinacy, MacroData, NameBindingKind, Used};
|
||||||
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
|
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
|
||||||
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
|
use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding};
|
||||||
use rustc_ast::expand::StrippedCfgItem;
|
use rustc_ast::expand::StrippedCfgItem;
|
||||||
|
@ -18,15 +18,18 @@ use rustc_errors::{Applicability, StashKey};
|
||||||
use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
|
use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
|
||||||
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
|
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
|
||||||
use rustc_expand::compile_declarative_macro;
|
use rustc_expand::compile_declarative_macro;
|
||||||
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
|
use rustc_expand::expand::{
|
||||||
|
AstFragment, AstFragmentKind, Invocation, InvocationKind, SupportsMacroExpansion,
|
||||||
|
};
|
||||||
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
|
use rustc_hir::def::{self, DefKind, Namespace, NonMacroAttrKind};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
|
||||||
use rustc_middle::middle::stability;
|
use rustc_middle::middle::stability;
|
||||||
use rustc_middle::ty::RegisteredTools;
|
use rustc_middle::ty::RegisteredTools;
|
||||||
use rustc_middle::ty::{TyCtxt, Visibility};
|
use rustc_middle::ty::{TyCtxt, Visibility};
|
||||||
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
|
use rustc_session::lint::builtin::{
|
||||||
use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
|
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, SOFT_UNSTABLE,
|
||||||
use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
|
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACROS, UNUSED_MACRO_RULES,
|
||||||
|
};
|
||||||
use rustc_session::lint::BuiltinLintDiag;
|
use rustc_session::lint::BuiltinLintDiag;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::edit_distance::edit_distance;
|
use rustc_span::edit_distance::edit_distance;
|
||||||
|
@ -288,6 +291,16 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
|
||||||
let parent_scope = &ParentScope { derives, ..parent_scope };
|
let parent_scope = &ParentScope { derives, ..parent_scope };
|
||||||
let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion();
|
let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion();
|
||||||
let node_id = invoc.expansion_data.lint_node_id;
|
let node_id = invoc.expansion_data.lint_node_id;
|
||||||
|
// This is a heuristic, but it's good enough for the lint.
|
||||||
|
let looks_like_invoc_in_mod_inert_attr = self
|
||||||
|
.invocation_parents
|
||||||
|
.get(&invoc_id)
|
||||||
|
.or_else(|| self.invocation_parents.get(&eager_expansion_root))
|
||||||
|
.map(|&(mod_def_id, _)| mod_def_id)
|
||||||
|
.filter(|&mod_def_id| {
|
||||||
|
invoc.fragment_kind == AstFragmentKind::Expr
|
||||||
|
&& self.tcx.def_kind(mod_def_id) == DefKind::Mod
|
||||||
|
});
|
||||||
let (ext, res) = self.smart_resolve_macro_path(
|
let (ext, res) = self.smart_resolve_macro_path(
|
||||||
path,
|
path,
|
||||||
kind,
|
kind,
|
||||||
|
@ -298,6 +311,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
|
||||||
force,
|
force,
|
||||||
soft_custom_inner_attributes_gate(path, invoc),
|
soft_custom_inner_attributes_gate(path, invoc),
|
||||||
deleg_impl,
|
deleg_impl,
|
||||||
|
looks_like_invoc_in_mod_inert_attr,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let span = invoc.span();
|
let span = invoc.span();
|
||||||
|
@ -520,6 +534,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
force: bool,
|
force: bool,
|
||||||
soft_custom_inner_attributes_gate: bool,
|
soft_custom_inner_attributes_gate: bool,
|
||||||
deleg_impl: Option<LocalDefId>,
|
deleg_impl: Option<LocalDefId>,
|
||||||
|
invoc_in_mod_inert_attr: Option<LocalDefId>,
|
||||||
) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
|
) -> Result<(Lrc<SyntaxExtension>, Res), Indeterminate> {
|
||||||
let (ext, res) = match self.resolve_macro_or_delegation_path(
|
let (ext, res) = match self.resolve_macro_or_delegation_path(
|
||||||
path,
|
path,
|
||||||
|
@ -528,6 +543,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
true,
|
true,
|
||||||
force,
|
force,
|
||||||
deleg_impl,
|
deleg_impl,
|
||||||
|
invoc_in_mod_inert_attr.map(|def_id| (def_id, node_id)),
|
||||||
) {
|
) {
|
||||||
Ok((Some(ext), res)) => (ext, res),
|
Ok((Some(ext), res)) => (ext, res),
|
||||||
Ok((None, res)) => (self.dummy_ext(kind), res),
|
Ok((None, res)) => (self.dummy_ext(kind), res),
|
||||||
|
@ -682,20 +698,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
trace: bool,
|
trace: bool,
|
||||||
force: bool,
|
force: bool,
|
||||||
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
|
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
|
||||||
self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None)
|
self.resolve_macro_or_delegation_path(path, kind, parent_scope, trace, force, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_macro_or_delegation_path(
|
fn resolve_macro_or_delegation_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &ast::Path,
|
ast_path: &ast::Path,
|
||||||
kind: Option<MacroKind>,
|
kind: Option<MacroKind>,
|
||||||
parent_scope: &ParentScope<'a>,
|
parent_scope: &ParentScope<'a>,
|
||||||
trace: bool,
|
trace: bool,
|
||||||
force: bool,
|
force: bool,
|
||||||
deleg_impl: Option<LocalDefId>,
|
deleg_impl: Option<LocalDefId>,
|
||||||
|
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
|
||||||
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
|
) -> Result<(Option<Lrc<SyntaxExtension>>, Res), Determinacy> {
|
||||||
let path_span = path.span;
|
let path_span = ast_path.span;
|
||||||
let mut path = Segment::from_path(path);
|
let mut path = Segment::from_path(ast_path);
|
||||||
|
|
||||||
// Possibly apply the macro helper hack
|
// Possibly apply the macro helper hack
|
||||||
if deleg_impl.is_none()
|
if deleg_impl.is_none()
|
||||||
|
@ -761,6 +778,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
|
|
||||||
let res = binding.map(|binding| binding.res());
|
let res = binding.map(|binding| binding.res());
|
||||||
self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
|
self.prohibit_imported_non_macro_attrs(binding.ok(), res.ok(), path_span);
|
||||||
|
self.report_out_of_scope_macro_calls(
|
||||||
|
ast_path,
|
||||||
|
parent_scope,
|
||||||
|
invoc_in_mod_inert_attr,
|
||||||
|
binding.ok(),
|
||||||
|
);
|
||||||
res
|
res
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1013,6 +1036,45 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_out_of_scope_macro_calls(
|
||||||
|
&mut self,
|
||||||
|
path: &ast::Path,
|
||||||
|
parent_scope: &ParentScope<'a>,
|
||||||
|
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
|
||||||
|
binding: Option<NameBinding<'a>>,
|
||||||
|
) {
|
||||||
|
if let Some((mod_def_id, node_id)) = invoc_in_mod_inert_attr
|
||||||
|
&& let Some(binding) = binding
|
||||||
|
// This is a `macro_rules` itself, not some import.
|
||||||
|
&& let NameBindingKind::Res(res) = binding.kind
|
||||||
|
&& let Res::Def(DefKind::Macro(MacroKind::Bang), def_id) = res
|
||||||
|
// And the `macro_rules` is defined inside the attribute's module,
|
||||||
|
// so it cannot be in scope unless imported.
|
||||||
|
&& self.tcx.is_descendant_of(def_id, mod_def_id.to_def_id())
|
||||||
|
{
|
||||||
|
// Try to resolve our ident ignoring `macro_rules` scopes.
|
||||||
|
// If such resolution is successful and gives the same result
|
||||||
|
// (e.g. if the macro is re-imported), then silence the lint.
|
||||||
|
let no_macro_rules = self.arenas.alloc_macro_rules_scope(MacroRulesScope::Empty);
|
||||||
|
let fallback_binding = self.early_resolve_ident_in_lexical_scope(
|
||||||
|
path.segments[0].ident,
|
||||||
|
ScopeSet::Macro(MacroKind::Bang),
|
||||||
|
&ParentScope { macro_rules: no_macro_rules, ..*parent_scope },
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
if fallback_binding.ok().and_then(|b| b.res().opt_def_id()) != Some(def_id) {
|
||||||
|
self.tcx.sess.psess.buffer_lint(
|
||||||
|
OUT_OF_SCOPE_MACRO_CALLS,
|
||||||
|
path.span,
|
||||||
|
node_id,
|
||||||
|
BuiltinLintDiag::OutOfScopeMacroCalls { path: pprust::path_to_string(path) },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
|
pub(crate) fn check_reserved_macro_name(&mut self, ident: Ident, res: Res) {
|
||||||
// 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`.
|
||||||
|
|
18
tests/ui/attributes/key-value-expansion-scope-pass.rs
Normal file
18
tests/ui/attributes/key-value-expansion-scope-pass.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Imports suppress the `out_of_scope_macro_calls` lint.
|
||||||
|
|
||||||
|
//@ check-pass
|
||||||
|
//@ edition:2018
|
||||||
|
|
||||||
|
#![doc = in_root!()]
|
||||||
|
|
||||||
|
macro_rules! in_root { () => { "" } }
|
||||||
|
use in_root;
|
||||||
|
|
||||||
|
mod macros_stay {
|
||||||
|
#![doc = in_mod!()]
|
||||||
|
|
||||||
|
macro_rules! in_mod { () => { "" } }
|
||||||
|
use in_mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,6 +1,8 @@
|
||||||
#![doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
|
#![doc = in_root!()] //~ WARN cannot find macro `in_root` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
|
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
|
||||||
#![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
|
#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
|
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
|
||||||
|
|
||||||
#[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
|
#[doc = in_root!()] //~ ERROR cannot find macro `in_root` in this scope
|
||||||
|
@ -16,8 +18,11 @@ fn before() {
|
||||||
|
|
||||||
macro_rules! in_root { () => { "" } }
|
macro_rules! in_root { () => { "" } }
|
||||||
|
|
||||||
|
#[doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
mod macros_stay {
|
mod macros_stay {
|
||||||
#![doc = in_mod!()] //~ ERROR cannot find macro `in_mod` in this scope
|
#![doc = in_mod!()] //~ WARN cannot find macro `in_mod` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
|
|
||||||
macro_rules! in_mod { () => { "" } }
|
macro_rules! in_mod { () => { "" } }
|
||||||
|
|
||||||
|
@ -28,8 +33,11 @@ mod macros_stay {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
#[doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
mod macros_escape {
|
mod macros_escape {
|
||||||
#![doc = in_mod_escape!()] //~ ERROR cannot find macro `in_mod_escape` in this scope
|
#![doc = in_mod_escape!()] //~ WARN cannot find macro `in_mod_escape` in this scope
|
||||||
|
//~| WARN this was previously accepted by the compiler
|
||||||
|
|
||||||
macro_rules! in_mod_escape { () => { "" } }
|
macro_rules! in_mod_escape { () => { "" } }
|
||||||
|
|
||||||
|
@ -39,8 +47,9 @@ mod macros_escape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
|
||||||
fn block() {
|
fn block() {
|
||||||
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
|
#![doc = in_block!()] //~ ERROR cannot find macro `in_block` in this scope
|
||||||
|
|
||||||
macro_rules! in_block { () => { "" } }
|
macro_rules! in_block { () => { "" } }
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,13 @@
|
||||||
error: cannot find macro `in_root` in this scope
|
|
||||||
--> $DIR/key-value-expansion-scope.rs:1:10
|
|
||||||
|
|
|
||||||
LL | #![doc = in_root!()]
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
error: cannot find macro `in_mod` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:2:10
|
--> $DIR/key-value-expansion-scope.rs:3:10
|
||||||
|
|
|
|
||||||
LL | #![doc = in_mod!()]
|
LL | #![doc = in_mod!()]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod_escape` in this scope
|
|
||||||
--> $DIR/key-value-expansion-scope.rs:3:10
|
|
||||||
|
|
|
||||||
LL | #![doc = in_mod_escape!()]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
error: cannot find macro `in_block` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:4:10
|
--> $DIR/key-value-expansion-scope.rs:6:10
|
||||||
|
|
|
|
||||||
LL | #![doc = in_block!()]
|
LL | #![doc = in_block!()]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -31,7 +15,7 @@ LL | #![doc = in_block!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_root` in this scope
|
error: cannot find macro `in_root` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:6:9
|
--> $DIR/key-value-expansion-scope.rs:8:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_root!()]
|
LL | #[doc = in_root!()]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -39,7 +23,7 @@ LL | #[doc = in_root!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
error: cannot find macro `in_mod` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:7:9
|
--> $DIR/key-value-expansion-scope.rs:9:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_mod!()]
|
LL | #[doc = in_mod!()]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -47,7 +31,7 @@ LL | #[doc = in_mod!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod_escape` in this scope
|
error: cannot find macro `in_mod_escape` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:8:9
|
--> $DIR/key-value-expansion-scope.rs:10:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_mod_escape!()]
|
LL | #[doc = in_mod_escape!()]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -55,7 +39,7 @@ LL | #[doc = in_mod_escape!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
error: cannot find macro `in_block` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:9:9
|
--> $DIR/key-value-expansion-scope.rs:11:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_block!()]
|
LL | #[doc = in_block!()]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -63,7 +47,7 @@ LL | #[doc = in_block!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_root` in this scope
|
error: cannot find macro `in_root` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:11:14
|
--> $DIR/key-value-expansion-scope.rs:13:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_root!()]
|
LL | #![doc = in_root!()]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -71,39 +55,15 @@ LL | #![doc = in_root!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
error: cannot find macro `in_mod` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:12:14
|
|
||||||
|
|
|
||||||
LL | #![doc = in_mod!()]
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
|
||||||
|
|
||||||
error: cannot find macro `in_mod_escape` in this scope
|
|
||||||
--> $DIR/key-value-expansion-scope.rs:13:14
|
|
||||||
|
|
|
||||||
LL | #![doc = in_mod_escape!()]
|
|
||||||
| ^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
|
||||||
--> $DIR/key-value-expansion-scope.rs:14:14
|
--> $DIR/key-value-expansion-scope.rs:14:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_block!()]
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
|
||||||
--> $DIR/key-value-expansion-scope.rs:20:14
|
|
||||||
|
|
|
||||||
LL | #![doc = in_mod!()]
|
LL | #![doc = in_mod!()]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod_escape` in this scope
|
error: cannot find macro `in_mod_escape` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:32:14
|
--> $DIR/key-value-expansion-scope.rs:15:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_mod_escape!()]
|
LL | #![doc = in_mod_escape!()]
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -111,7 +71,23 @@ LL | #![doc = in_mod_escape!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
error: cannot find macro `in_block` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:43:14
|
--> $DIR/key-value-expansion-scope.rs:16:14
|
||||||
|
|
|
||||||
|
LL | #![doc = in_block!()]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
|
error: cannot find macro `in_block` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:50:9
|
||||||
|
|
|
||||||
|
LL | #[doc = in_block!()]
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
|
error: cannot find macro `in_block` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:52:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_block!()]
|
LL | #![doc = in_block!()]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -119,7 +95,7 @@ LL | #![doc = in_block!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
error: cannot find macro `in_mod` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:54:9
|
--> $DIR/key-value-expansion-scope.rs:63:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_mod!()]
|
LL | #[doc = in_mod!()]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -127,7 +103,7 @@ LL | #[doc = in_mod!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
error: cannot find macro `in_block` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:56:9
|
--> $DIR/key-value-expansion-scope.rs:65:9
|
||||||
|
|
|
|
||||||
LL | #[doc = in_block!()]
|
LL | #[doc = in_block!()]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -135,7 +111,7 @@ LL | #[doc = in_block!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_mod` in this scope
|
error: cannot find macro `in_mod` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:59:14
|
--> $DIR/key-value-expansion-scope.rs:68:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_mod!()]
|
LL | #![doc = in_mod!()]
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -143,12 +119,73 @@ LL | #![doc = in_mod!()]
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: cannot find macro `in_block` in this scope
|
error: cannot find macro `in_block` in this scope
|
||||||
--> $DIR/key-value-expansion-scope.rs:61:14
|
--> $DIR/key-value-expansion-scope.rs:70:14
|
||||||
|
|
|
|
||||||
LL | #![doc = in_block!()]
|
LL | #![doc = in_block!()]
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: have you added the `#[macro_use]` on the module/import?
|
= help: have you added the `#[macro_use]` on the module/import?
|
||||||
|
|
||||||
error: aborting due to 19 previous errors
|
warning: cannot find macro `in_root` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:1:10
|
||||||
|
|
|
||||||
|
LL | #![doc = in_root!()]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
= note: `#[warn(out_of_scope_macro_calls)]` on by default
|
||||||
|
|
||||||
|
warning: cannot find macro `in_mod_escape` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:4:10
|
||||||
|
|
|
||||||
|
LL | #![doc = in_mod_escape!()]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
|
warning: cannot find macro `in_mod` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:21:9
|
||||||
|
|
|
||||||
|
LL | #[doc = in_mod!()]
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
|
warning: cannot find macro `in_mod` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:24:14
|
||||||
|
|
|
||||||
|
LL | #![doc = in_mod!()]
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
|
warning: cannot find macro `in_mod_escape` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:36:9
|
||||||
|
|
|
||||||
|
LL | #[doc = in_mod_escape!()]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
|
warning: cannot find macro `in_mod_escape` in this scope
|
||||||
|
--> $DIR/key-value-expansion-scope.rs:39:14
|
||||||
|
|
|
||||||
|
LL | #![doc = in_mod_escape!()]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
|
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||||
|
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||||
|
|
||||||
|
error: aborting due to 16 previous errors; 6 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ warning: unknown lint: `x5100`
|
||||||
LL | #![deny(x5100)]
|
LL | #![deny(x5100)]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: use of deprecated attribute `crate_id`: no longer used.
|
warning: use of deprecated attribute `crate_id`: no longer used
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:84:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:84:1
|
||||||
|
|
|
|
||||||
LL | #![crate_id = "10"]
|
LL | #![crate_id = "10"]
|
||||||
|
@ -50,7 +50,7 @@ LL | #![crate_id = "10"]
|
||||||
|
|
|
|
||||||
= note: `#[warn(deprecated)]` on by default
|
= note: `#[warn(deprecated)]` on by default
|
||||||
|
|
||||||
warning: use of deprecated attribute `no_start`: no longer used.
|
warning: use of deprecated attribute `no_start`: no longer used
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
|
||||||
|
|
|
|
||||||
LL | #![no_start]
|
LL | #![no_start]
|
||||||
|
@ -200,20 +200,6 @@ warning: unknown lint: `x5100`
|
||||||
LL | #[deny(x5100)] impl S { }
|
LL | #[deny(x5100)] impl S { }
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
warning: use of deprecated attribute `crate_id`: no longer used
|
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:84:1
|
|
||||||
|
|
|
||||||
LL | #![crate_id = "10"]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
|
||||||
|
|
|
||||||
= note: `#[warn(deprecated)]` on by default
|
|
||||||
|
|
||||||
warning: use of deprecated attribute `no_start`: no longer used
|
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
|
|
||||||
|
|
|
||||||
LL | #![no_start]
|
|
||||||
| ^^^^^^^^^^^^ help: remove this attribute
|
|
||||||
|
|
||||||
warning: `#[macro_export]` only has an effect on macro definitions
|
warning: `#[macro_export]` only has an effect on macro definitions
|
||||||
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:1
|
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:1
|
||||||
|
|
|
|
||||||
|
@ -1192,3 +1178,4 @@ LL | #![feature(rust1)]
|
||||||
= note: `#[warn(stable_features)]` on by default
|
= note: `#[warn(stable_features)]` on by default
|
||||||
|
|
||||||
warning: 173 warnings emitted
|
warning: 173 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,6 @@ error[E0425]: cannot find value `NonExistent` in this scope
|
||||||
LL | NonExistent;
|
LL | NonExistent;
|
||||||
| ^^^^^^^^^^^ not found in this scope
|
| ^^^^^^^^^^^ not found in this scope
|
||||||
|
|
||||||
error[E0659]: `feature` is ambiguous
|
|
||||||
--> $DIR/ambiguous-builtin-attrs.rs:3:4
|
|
||||||
|
|
|
||||||
LL | #![feature(decl_macro)]
|
|
||||||
| ^^^^^^^ ambiguous name
|
|
||||||
|
|
|
||||||
= note: ambiguous because of a name conflict with a builtin attribute
|
|
||||||
= note: `feature` could refer to a built-in attribute
|
|
||||||
note: `feature` could also refer to the attribute macro imported here
|
|
||||||
--> $DIR/ambiguous-builtin-attrs.rs:6:5
|
|
||||||
|
|
|
||||||
LL | use builtin_attrs::*;
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
= help: use `crate::feature` to refer to this attribute macro unambiguously
|
|
||||||
|
|
||||||
error[E0659]: `repr` is ambiguous
|
error[E0659]: `repr` is ambiguous
|
||||||
--> $DIR/ambiguous-builtin-attrs.rs:9:3
|
--> $DIR/ambiguous-builtin-attrs.rs:9:3
|
||||||
|
|
|
|
||||||
|
@ -94,6 +79,21 @@ LL | use deny as allow;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
= help: use `crate::allow` to refer to this built-in attribute unambiguously
|
= help: use `crate::allow` to refer to this built-in attribute unambiguously
|
||||||
|
|
||||||
|
error[E0659]: `feature` is ambiguous
|
||||||
|
--> $DIR/ambiguous-builtin-attrs.rs:3:4
|
||||||
|
|
|
||||||
|
LL | #![feature(decl_macro)]
|
||||||
|
| ^^^^^^^ ambiguous name
|
||||||
|
|
|
||||||
|
= note: ambiguous because of a name conflict with a builtin attribute
|
||||||
|
= note: `feature` could refer to a built-in attribute
|
||||||
|
note: `feature` could also refer to the attribute macro imported here
|
||||||
|
--> $DIR/ambiguous-builtin-attrs.rs:6:5
|
||||||
|
|
|
||||||
|
LL | use builtin_attrs::*;
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
= help: use `crate::feature` to refer to this attribute macro unambiguously
|
||||||
|
|
||||||
error[E0517]: attribute should be applied to a struct, enum, or union
|
error[E0517]: attribute should be applied to a struct, enum, or union
|
||||||
--> $DIR/ambiguous-builtin-attrs.rs:20:39
|
--> $DIR/ambiguous-builtin-attrs.rs:20:39
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue