mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #155339 - JonathanBrouwer:rollup-2nyGW0a, r=JonathanBrouwer
Rollup of 5 pull requests Successful merges: - rust-lang/rust#155331 (Reformat `top_level_options!` and `options!` macro declarations) - rust-lang/rust#155332 (bump std libc to `0.2.185`) - rust-lang/rust#155286 (attribute cleanup: rustc_confusables) - rust-lang/rust#155306 (`CValue::zst()` - add missing "ZST" in docs) - rust-lang/rust#155311 (various small `rustc_expand` cleanups)
This commit is contained in:
@@ -44,9 +44,6 @@ fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(AttributeKind::RustcConfusables {
|
||||
symbols: self.confusables,
|
||||
first_span: self.first_span.unwrap(),
|
||||
})
|
||||
Some(AttributeKind::RustcConfusables { confusables: self.confusables })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ pub(crate) fn by_val_pair(
|
||||
|
||||
/// Create an instance of a ZST
|
||||
///
|
||||
/// The is represented by a dangling pointer of suitable alignment.
|
||||
/// The ZST is represented by a dangling pointer of suitable alignment.
|
||||
pub(crate) fn zst(layout: TyAndLayout<'tcx>) -> CValue<'tcx> {
|
||||
assert!(layout.is_zst());
|
||||
CValue::by_ref(crate::Pointer::dangling(layout.align.abi), layout)
|
||||
|
||||
@@ -409,17 +409,10 @@ pub trait GlobDelegationExpander {
|
||||
fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()>;
|
||||
}
|
||||
|
||||
// Use a macro because forwarding to a simple function has type system issues
|
||||
macro_rules! make_stmts_default {
|
||||
($me:expr) => {
|
||||
$me.make_expr().map(|e| {
|
||||
smallvec![ast::Stmt {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: e.span,
|
||||
kind: ast::StmtKind::Expr(e),
|
||||
}]
|
||||
})
|
||||
};
|
||||
fn make_stmts_default(expr: Option<Box<ast::Expr>>) -> Option<SmallVec<[ast::Stmt; 1]>> {
|
||||
expr.map(|e| {
|
||||
smallvec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: e.span, kind: ast::StmtKind::Expr(e) }]
|
||||
})
|
||||
}
|
||||
|
||||
/// The result of a macro expansion. The return values of the various
|
||||
@@ -465,7 +458,7 @@ fn make_pat(self: Box<Self>) -> Option<Box<ast::Pat>> {
|
||||
/// By default this attempts to create an expression statement,
|
||||
/// returning None if that fails.
|
||||
fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
|
||||
make_stmts_default!(self)
|
||||
make_stmts_default(self.make_expr())
|
||||
}
|
||||
|
||||
fn make_ty(self: Box<Self>) -> Option<Box<ast::Ty>> {
|
||||
@@ -571,9 +564,10 @@ fn make_expr(self: Box<Self>) -> Option<Box<ast::Expr>> {
|
||||
}
|
||||
|
||||
fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
|
||||
match self.stmts.as_ref().map_or(0, |s| s.len()) {
|
||||
0 => make_stmts_default!(self),
|
||||
_ => self.stmts,
|
||||
if self.stmts.as_ref().is_none_or(|s| s.is_empty()) {
|
||||
make_stmts_default(self.make_expr())
|
||||
} else {
|
||||
self.stmts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,7 +892,7 @@ pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
|
||||
fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
|
||||
let flag = sess.opts.cg.collapse_macro_debuginfo;
|
||||
let attr = if let Some(info) = find_attr!(attrs, CollapseDebugInfo(info) => info) {
|
||||
info.clone()
|
||||
*info
|
||||
} else if find_attr!(attrs, RustcBuiltinMacro { .. }) {
|
||||
CollapseMacroDebuginfo::Yes
|
||||
} else {
|
||||
|
||||
@@ -106,33 +106,24 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
|
||||
|
||||
// If the enabled feature is unstable, record it.
|
||||
if UNSTABLE_LANG_FEATURES.iter().find(|f| feature_ident.name == f.name).is_some() {
|
||||
// When the ICE comes from a standard library crate, there's a chance that the person
|
||||
// hitting the ICE may be using -Zbuild-std or similar with an untested target.
|
||||
// The bug is probably in the standard library and not the compiler in that case,
|
||||
// but that doesn't really matter - we want a bug report.
|
||||
if features.internal(feature_ident.name)
|
||||
&& !STDLIB_STABLE_CRATES.contains(&crate_name)
|
||||
{
|
||||
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
|
||||
features.set_enabled_lang_feature(EnabledLangFeature {
|
||||
gate_name: feature_ident.name,
|
||||
attr_sp: feature_ident.span,
|
||||
stable_since: None,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
// Otherwise, the feature is unknown. Enable it as a lib feature.
|
||||
// It will be checked later whether the feature really exists.
|
||||
features.set_enabled_lib_feature(EnabledLibFeature {
|
||||
gate_name: feature_ident.name,
|
||||
attr_sp: feature_ident.span,
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise, the feature is unknown. Enable it as a lib feature.
|
||||
// It will be checked later whether the feature really exists.
|
||||
features.set_enabled_lib_feature(EnabledLibFeature {
|
||||
gate_name: feature_ident.name,
|
||||
attr_sp: feature_ident.span,
|
||||
});
|
||||
|
||||
// Similar to above, detect internal lib features to suppress
|
||||
// the ICE message that asks for a report.
|
||||
// When the ICE comes from a standard library crate, there's a chance that the person
|
||||
// hitting the ICE may be using -Zbuild-std or similar with an untested target.
|
||||
// The bug is probably in the standard library and not the compiler in that case,
|
||||
// but that doesn't really matter - we want a bug report.
|
||||
if features.internal(feature_ident.name) && !STDLIB_STABLE_CRATES.contains(&crate_name)
|
||||
{
|
||||
sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
@@ -285,7 +276,7 @@ pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> V
|
||||
|
||||
let Some((cfg_predicate, expanded_attrs)) = rustc_attr_parsing::parse_cfg_attr(
|
||||
cfg_attr,
|
||||
&self.sess,
|
||||
self.sess,
|
||||
self.features,
|
||||
self.lint_node_id,
|
||||
) else {
|
||||
@@ -422,7 +413,7 @@ pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
|
||||
&& !attr.span.allows_unstable(sym::stmt_expr_attributes)
|
||||
{
|
||||
let mut err = feature_err(
|
||||
&self.sess,
|
||||
self.sess,
|
||||
sym::stmt_expr_attributes,
|
||||
attr.span,
|
||||
msg!("attributes on expressions are experimental"),
|
||||
|
||||
@@ -1050,7 +1050,7 @@ fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
|
||||
return;
|
||||
}
|
||||
feature_err(
|
||||
&self.cx.sess,
|
||||
self.cx.sess,
|
||||
sym::proc_macro_hygiene,
|
||||
span,
|
||||
format!("custom attributes cannot be applied to {kind}"),
|
||||
@@ -1085,7 +1085,7 @@ fn visit_item(&mut self, item: &'ast ast::Item) {
|
||||
}
|
||||
|
||||
if !self.cx.ecfg.features.proc_macro_hygiene() {
|
||||
annotatable.visit_with(&mut GateProcMacroInput { sess: &self.cx.sess });
|
||||
annotatable.visit_with(&mut GateProcMacroInput { sess: self.cx.sess });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1474,7 +1474,7 @@ fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
|
||||
}
|
||||
}
|
||||
let mut idents = Vec::new();
|
||||
collect_use_tree_leaves(&ut, &mut idents);
|
||||
collect_use_tree_leaves(ut, &mut idents);
|
||||
idents
|
||||
} else {
|
||||
self.kind.ident().into_iter().collect()
|
||||
@@ -1482,7 +1482,7 @@ fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
|
||||
}
|
||||
|
||||
fn as_target(&self) -> Target {
|
||||
Target::from_ast_item(&*self)
|
||||
Target::from_ast_item(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -288,27 +288,24 @@ pub(super) fn emit_frag_parse_err(
|
||||
_ => annotate_err_with_kind(&mut e, kind, site_span),
|
||||
};
|
||||
|
||||
let mut bindings_rules = vec![];
|
||||
for rule in bindings {
|
||||
let MacroRule::Func { lhs, .. } = rule else { continue };
|
||||
for param in lhs {
|
||||
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
|
||||
bindings_rules.push(*bind);
|
||||
}
|
||||
}
|
||||
|
||||
let mut matched_rule_bindings_rules = vec![];
|
||||
for param in matched_rule_bindings {
|
||||
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
|
||||
matched_rule_bindings_rules.push(*bind);
|
||||
}
|
||||
|
||||
let matched_rule_bindings_names: Vec<_> =
|
||||
matched_rule_bindings_rules.iter().map(|bind| bind.name).collect();
|
||||
let bindings_name: Vec<_> = bindings_rules.iter().map(|bind| bind.name).collect();
|
||||
if parser.token.kind == token::Dollar {
|
||||
parser.bump();
|
||||
if let token::Ident(name, _) = parser.token.kind {
|
||||
let mut bindings_names = vec![];
|
||||
for rule in bindings {
|
||||
let MacroRule::Func { lhs, .. } = rule else { continue };
|
||||
for param in lhs {
|
||||
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
|
||||
bindings_names.push(bind.name);
|
||||
}
|
||||
}
|
||||
|
||||
let mut matched_rule_bindings_names = vec![];
|
||||
for param in matched_rule_bindings {
|
||||
let MatcherLoc::MetaVarDecl { bind, .. } = param else { continue };
|
||||
matched_rule_bindings_names.push(bind.name);
|
||||
}
|
||||
|
||||
if let Some(matched_name) = rustc_span::edit_distance::find_best_match_for_name(
|
||||
&matched_rule_bindings_names[..],
|
||||
name,
|
||||
@@ -316,24 +313,22 @@ pub(super) fn emit_frag_parse_err(
|
||||
) {
|
||||
e.span_suggestion_verbose(
|
||||
parser.token.span,
|
||||
"there is a macro metavariable with similar name",
|
||||
format!("{matched_name}"),
|
||||
"there is a macro metavariable with a similar name",
|
||||
matched_name,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if bindings_name.contains(&name) {
|
||||
} else if bindings_names.contains(&name) {
|
||||
e.span_label(
|
||||
parser.token.span,
|
||||
format!(
|
||||
"there is an macro metavariable with this name in another macro matcher"
|
||||
),
|
||||
"there is an macro metavariable with this name in another macro matcher",
|
||||
);
|
||||
} else if let Some(matched_name) =
|
||||
rustc_span::edit_distance::find_best_match_for_name(&bindings_name[..], name, None)
|
||||
rustc_span::edit_distance::find_best_match_for_name(&bindings_names[..], name, None)
|
||||
{
|
||||
e.span_suggestion_verbose(
|
||||
parser.token.span,
|
||||
"there is a macro metavariable with a similar name in another macro matcher",
|
||||
format!("{matched_name}"),
|
||||
matched_name,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
@@ -343,7 +338,7 @@ pub(super) fn emit_frag_parse_err(
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
e.span_label(parser.token.span, format!("macro metavariable not found"));
|
||||
e.span_label(parser.token.span, "macro metavariable not found");
|
||||
if !matched_rule_bindings_names.is_empty() {
|
||||
e.note(format!("available metavariable names are: {msg}"));
|
||||
}
|
||||
|
||||
@@ -199,8 +199,8 @@ fn inner(
|
||||
let idx_seq = idx_first - 1;
|
||||
inner(&seq.tts, locs, next_metavar, seq_depth + 1);
|
||||
|
||||
if let Some(separator) = &seq.separator {
|
||||
locs.push(MatcherLoc::SequenceSep { separator: separator.clone() });
|
||||
if let Some(separator) = seq.separator {
|
||||
locs.push(MatcherLoc::SequenceSep { separator });
|
||||
locs.push(MatcherLoc::SequenceKleeneOpAfterSep { idx_first });
|
||||
} else {
|
||||
locs.push(MatcherLoc::SequenceKleeneOpNoSep { op, idx_first });
|
||||
|
||||
@@ -214,7 +214,7 @@ fn parse_tree<'a>(
|
||||
// during parsing.
|
||||
let mut next = outer_iter.next();
|
||||
let mut iter_storage;
|
||||
let mut iter: &mut TokenStreamIter<'_> = match next {
|
||||
let iter: &mut TokenStreamIter<'_> = match next {
|
||||
Some(tokenstream::TokenTree::Delimited(.., delim, tts)) if delim.skip() => {
|
||||
iter_storage = tts.iter();
|
||||
next = iter_storage.next();
|
||||
@@ -284,7 +284,7 @@ fn parse_tree<'a>(
|
||||
let sequence = parse(tts, part, sess, node_id, features, edition);
|
||||
// Get the Kleene operator and optional separator
|
||||
let (separator, kleene) =
|
||||
parse_sep_and_kleene_op(&mut iter, delim_span.entire(), sess);
|
||||
parse_sep_and_kleene_op(iter, delim_span.entire(), sess);
|
||||
// Count the number of captured "names" (i.e., named metavars)
|
||||
let num_captures =
|
||||
if part.is_pattern() { count_metavar_decls(&sequence) } else { 0 };
|
||||
|
||||
@@ -396,7 +396,7 @@ fn transcribe_sequence<'tx, 'itp>(
|
||||
// The first time we encounter the sequence we push it to the stack. It
|
||||
// then gets reused (see the beginning of the loop) until we are done
|
||||
// repeating.
|
||||
tscx.stack.push(Frame::new_sequence(seq_rep, seq.separator.clone(), seq.kleene.op));
|
||||
tscx.stack.push(Frame::new_sequence(seq_rep, seq.separator, seq.kleene.op));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -629,7 +629,7 @@ fn metavar_expr_concat<'tx>(
|
||||
) -> PResult<'tx, TokenTree> {
|
||||
let dcx = tscx.psess.dcx();
|
||||
let mut concatenated = String::new();
|
||||
for element in elements.into_iter() {
|
||||
for element in elements {
|
||||
let symbol = match element {
|
||||
MetaVarExprConcatElem::Ident(elem) => elem.name,
|
||||
MetaVarExprConcatElem::Literal(elem) => *elem,
|
||||
@@ -747,7 +747,7 @@ fn maybe_use_metavar_location(
|
||||
TokenTree::Token(Token { kind, span }, spacing) => {
|
||||
let span = metavar_span.with_ctxt(span.ctxt());
|
||||
with_metavar_spans(|mspans| mspans.insert(span, metavar_span));
|
||||
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
|
||||
TokenTree::Token(Token { kind: *kind, span }, *spacing)
|
||||
}
|
||||
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
|
||||
let open = metavar_span.with_ctxt(dspan.open.ctxt());
|
||||
|
||||
@@ -77,7 +77,7 @@ pub(crate) fn parse_external_mod(
|
||||
Some(span),
|
||||
));
|
||||
let (inner_attrs, items, inner_span) =
|
||||
parser.parse_mod(exp!(Eof)).map_err(|err| ModError::ParserError(err))?;
|
||||
parser.parse_mod(exp!(Eof)).map_err(ModError::ParserError)?;
|
||||
attrs.extend(inner_attrs);
|
||||
(items, inner_span, mp.file_path)
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_data_structures::profiling::TimingGuard;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_parse::parser::{AllowConstBlockItems, ForceCollect, Parser};
|
||||
@@ -19,6 +20,16 @@ fn exec_strategy(sess: &Session) -> impl pm::bridge::server::ExecutionStrategy +
|
||||
}
|
||||
}
|
||||
|
||||
fn record_expand_proc_macro<'a>(
|
||||
ecx: &ExtCtxt<'a>,
|
||||
name: &'static str,
|
||||
span: Span,
|
||||
) -> TimingGuard<'a> {
|
||||
ecx.sess.prof.generic_activity_with_arg_recorder(name, |recorder| {
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||
})
|
||||
}
|
||||
|
||||
pub struct BangProcMacro {
|
||||
pub client: pm::bridge::client::Client<pm::TokenStream, pm::TokenStream>,
|
||||
}
|
||||
@@ -30,10 +41,7 @@ fn expand(
|
||||
span: Span,
|
||||
input: TokenStream,
|
||||
) -> Result<TokenStream, ErrorGuaranteed> {
|
||||
let _timer =
|
||||
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||
});
|
||||
let _timer = record_expand_proc_macro(ecx, "expand_proc_macro", span);
|
||||
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
let strategy = exec_strategy(ecx.sess);
|
||||
@@ -41,9 +49,7 @@ fn expand(
|
||||
self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| {
|
||||
ecx.dcx().emit_err(errors::ProcMacroPanicked {
|
||||
span,
|
||||
message: e
|
||||
.as_str()
|
||||
.map(|message| errors::ProcMacroPanickedHelp { message: message.into() }),
|
||||
message: e.into_string().map(|message| errors::ProcMacroPanickedHelp { message }),
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -61,10 +67,7 @@ fn expand(
|
||||
annotation: TokenStream,
|
||||
annotated: TokenStream,
|
||||
) -> Result<TokenStream, ErrorGuaranteed> {
|
||||
let _timer =
|
||||
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||
});
|
||||
let _timer = record_expand_proc_macro(ecx, "expand_proc_macro", span);
|
||||
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
let strategy = exec_strategy(ecx.sess);
|
||||
@@ -73,9 +76,9 @@ fn expand(
|
||||
|e| {
|
||||
ecx.dcx().emit_err(errors::CustomAttributePanicked {
|
||||
span,
|
||||
message: e.as_str().map(|message| errors::CustomAttributePanickedHelp {
|
||||
message: message.into(),
|
||||
}),
|
||||
message: e
|
||||
.into_string()
|
||||
.map(|message| errors::CustomAttributePanickedHelp { message }),
|
||||
})
|
||||
},
|
||||
)
|
||||
@@ -95,12 +98,7 @@ fn expand(
|
||||
item: Annotatable,
|
||||
_is_derive_const: bool,
|
||||
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
|
||||
let _timer = ecx.sess.prof.generic_activity_with_arg_recorder(
|
||||
"expand_derive_proc_macro_outer",
|
||||
|recorder| {
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span);
|
||||
},
|
||||
);
|
||||
let _timer = record_expand_proc_macro(ecx, "expand_derive_proc_macro_outer", span);
|
||||
|
||||
// We need special handling for statement items
|
||||
// (e.g. `fn foo() { #[derive(Debug)] struct Bar; }`)
|
||||
@@ -191,7 +189,7 @@ fn expand_derive_macro(
|
||||
let invoc_expn_data = invoc_id.expn_data();
|
||||
let span = invoc_expn_data.call_site;
|
||||
let event_arg = invoc_expn_data.kind.descr();
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), event_arg.clone(), span);
|
||||
recorder.record_arg_with_span(ecx.sess.source_map(), event_arg, span);
|
||||
});
|
||||
|
||||
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
|
||||
@@ -206,9 +204,9 @@ fn expand_derive_macro(
|
||||
ecx.dcx().emit_err({
|
||||
errors::ProcMacroDerivePanicked {
|
||||
span,
|
||||
message: e.as_str().map(|message| errors::ProcMacroDerivePanickedHelp {
|
||||
message: message.into(),
|
||||
}),
|
||||
message: e
|
||||
.into_string()
|
||||
.map(|message| errors::ProcMacroDerivePanickedHelp { message }),
|
||||
}
|
||||
});
|
||||
Err(())
|
||||
@@ -232,7 +230,7 @@ fn enter<F, R>(ecx: &mut ExtCtxt<'_>, client: DeriveClient, f: F) -> R
|
||||
{
|
||||
// We need erasure to get rid of the lifetime
|
||||
let ctx = Self { expansion_ctx: ecx as *mut _ as *mut (), client };
|
||||
DERIVE_EXPAND_CTX.set(&ctx, || f())
|
||||
DERIVE_EXPAND_CTX.set(&ctx, f)
|
||||
}
|
||||
|
||||
/// Accesses the thread local value of the derive expansion context.
|
||||
|
||||
@@ -110,26 +110,22 @@ fn from_internal(stream: TokenStream) -> Self {
|
||||
// Estimate the capacity as `stream.len()` rounded up to the next power
|
||||
// of two to limit the number of required reallocations.
|
||||
let mut trees = Vec::with_capacity(stream.len().next_power_of_two());
|
||||
let mut iter = stream.iter();
|
||||
|
||||
while let Some(tree) = iter.next() {
|
||||
for tree in stream.iter() {
|
||||
let (Token { kind, span }, joint) = match tree.clone() {
|
||||
tokenstream::TokenTree::Delimited(span, _, mut delim, mut stream) => {
|
||||
// In `mk_delimited` we avoid nesting invisible delimited
|
||||
// of the same `MetaVarKind`. Here we do the same but
|
||||
// ignore the `MetaVarKind` because it is discarded when we
|
||||
// convert it to a `Group`.
|
||||
while let Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) = delim {
|
||||
if stream.len() == 1
|
||||
&& let tree = stream.iter().next().unwrap()
|
||||
&& let tokenstream::TokenTree::Delimited(_, _, delim2, stream2) = tree
|
||||
&& let Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) = delim2
|
||||
{
|
||||
delim = *delim2;
|
||||
stream = stream2.clone();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
while let Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) = delim
|
||||
&& stream.len() == 1
|
||||
&& let tree = stream.get(0).unwrap()
|
||||
&& let tokenstream::TokenTree::Delimited(_, _, delim2, stream2) = tree
|
||||
&& let Delimiter::Invisible(InvisibleOrigin::MetaVar(_)) = delim2
|
||||
{
|
||||
delim = *delim2;
|
||||
stream = stream2.clone();
|
||||
}
|
||||
|
||||
trees.push(TokenTree::Group(Group {
|
||||
|
||||
@@ -152,7 +152,7 @@ pub(crate) fn update_macro_stats(
|
||||
}
|
||||
|
||||
// The recorded size is the difference between the input and the output.
|
||||
let entry = ecx.macro_stats.entry((name, macro_kind)).or_insert(MacroStat::default());
|
||||
let entry = ecx.macro_stats.entry((name, macro_kind)).or_default();
|
||||
entry.uses += 1;
|
||||
entry.lines += num_lines;
|
||||
entry.bytes += num_bytes;
|
||||
|
||||
@@ -1336,9 +1336,7 @@ pub enum AttributeKind {
|
||||
|
||||
/// Represents `#[rustc_confusables]`.
|
||||
RustcConfusables {
|
||||
symbols: ThinVec<Symbol>,
|
||||
// FIXME(jdonszelmann): remove when target validation code is moved
|
||||
first_span: Span,
|
||||
confusables: ThinVec<Symbol>,
|
||||
},
|
||||
/// Represents `#[rustc_const_stable]` and `#[rustc_const_unstable]`.
|
||||
RustcConstStability {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
use rustc_span::edit_distance::{
|
||||
edit_distance_with_substrings, find_best_match_for_name_with_substrings,
|
||||
};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
|
||||
use rustc_span::{DUMMY_SP, Ident, Span, Symbol};
|
||||
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::solve::Goal;
|
||||
@@ -2592,38 +2592,25 @@ fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
|
||||
}
|
||||
|
||||
/// Determine if the associated item with the given DefId matches
|
||||
/// the desired name via a doc alias.
|
||||
/// the desired name via a doc alias or rustc_confusables
|
||||
fn matches_by_doc_alias(&self, def_id: DefId) -> bool {
|
||||
let Some(method) = self.method_name else {
|
||||
return false;
|
||||
};
|
||||
let Some(local_def_id) = def_id.as_local() else {
|
||||
return false;
|
||||
};
|
||||
let hir_id = self.fcx.tcx.local_def_id_to_hir_id(local_def_id);
|
||||
let attrs = self.fcx.tcx.hir_attrs(hir_id);
|
||||
|
||||
if let Some(d) = find_attr!(attrs, Doc(d) => d)
|
||||
if let Some(d) = find_attr!(self.tcx, def_id, Doc(d) => d)
|
||||
&& d.aliases.contains_key(&method.name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for attr in attrs {
|
||||
if attr.has_name(sym::rustc_confusables) {
|
||||
let Some(confusables) = attr.meta_item_list() else {
|
||||
continue;
|
||||
};
|
||||
// #[rustc_confusables("foo", "bar"))]
|
||||
for n in confusables {
|
||||
if let Some(lit) = n.lit()
|
||||
&& method.name == lit.symbol
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(confusables) =
|
||||
find_attr!(self.tcx, def_id, RustcConfusables{ confusables } => confusables)
|
||||
&& confusables.contains(&method.name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
|
||||
@@ -2276,8 +2276,8 @@ pub(crate) fn confusable_method_name(
|
||||
for inherent_method in
|
||||
self.tcx.associated_items(inherent_impl_did).in_definition_order()
|
||||
{
|
||||
if let Some(candidates) = find_attr!(self.tcx, inherent_method.def_id, RustcConfusables{symbols, ..} => symbols)
|
||||
&& candidates.contains(&item_name.name)
|
||||
if let Some(confusables) = find_attr!(self.tcx, inherent_method.def_id, RustcConfusables{confusables} => confusables)
|
||||
&& confusables.contains(&item_name.name)
|
||||
&& inherent_method.is_fn()
|
||||
{
|
||||
let args =
|
||||
|
||||
@@ -51,14 +51,14 @@ macro_rules! hash_substruct {
|
||||
($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [UNTRACKED]) => {{}};
|
||||
($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [TRACKED]) => {{}};
|
||||
($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [TRACKED_NO_CRATE_HASH]) => {{}};
|
||||
($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [SUBSTRUCT]) => {
|
||||
($opt_name:ident, $opt_expr:expr, $error_format:expr, $for_crate_hash:expr, $hasher:expr, [SUBSTRUCT]) => {{
|
||||
use crate::config::dep_tracking::DepTrackingHash;
|
||||
$opt_expr.dep_tracking_hash($for_crate_hash, $error_format).hash(
|
||||
$hasher,
|
||||
$error_format,
|
||||
$for_crate_hash,
|
||||
);
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
/// Extended target modifier info.
|
||||
@@ -309,19 +309,33 @@ pub fn is_target_modifier(flag_name: &str) -> bool {
|
||||
}
|
||||
|
||||
macro_rules! top_level_options {
|
||||
( $( #[$top_level_attr:meta] )* pub struct Options { $(
|
||||
$( #[$attr:meta] )*
|
||||
$opt:ident : $t:ty [$dep_tracking_marker:ident $( $tmod:ident $variant:ident )?],
|
||||
)* } ) => (
|
||||
top_level_tmod_enum!( {$([$dep_tracking_marker $($tmod $variant),*])|*} );
|
||||
|
||||
#[derive(Clone)]
|
||||
$( #[$top_level_attr] )*
|
||||
(
|
||||
$(#[$top_level_attr:meta])*
|
||||
pub struct Options {
|
||||
$(
|
||||
$( #[$attr] )*
|
||||
pub $opt: $t
|
||||
),*,
|
||||
$(#[$attr:meta])*
|
||||
$opt:ident : $t:ty [
|
||||
$dep_tracking_marker:ident
|
||||
$( $tmod:ident $variant:ident )?
|
||||
],
|
||||
)*
|
||||
}
|
||||
) => {
|
||||
top_level_tmod_enum!(
|
||||
{
|
||||
$(
|
||||
[$dep_tracking_marker $($tmod $variant),*]
|
||||
)|*
|
||||
}
|
||||
);
|
||||
|
||||
#[derive(Clone)]
|
||||
$(#[$top_level_attr])*
|
||||
pub struct Options {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
pub $opt: $t,
|
||||
)*
|
||||
pub target_modifiers: BTreeMap<OptionsTargetModifiers, String>,
|
||||
pub mitigation_coverage_map: mitigation_coverage::MitigationCoverageMap,
|
||||
}
|
||||
@@ -329,41 +343,51 @@ pub struct Options {
|
||||
impl Options {
|
||||
pub fn dep_tracking_hash(&self, for_crate_hash: bool) -> Hash64 {
|
||||
let mut sub_hashes = BTreeMap::new();
|
||||
$({
|
||||
hash_opt!($opt,
|
||||
&self.$opt,
|
||||
&mut sub_hashes,
|
||||
for_crate_hash,
|
||||
[$dep_tracking_marker]);
|
||||
})*
|
||||
$(
|
||||
hash_opt!(
|
||||
$opt,
|
||||
&self.$opt,
|
||||
&mut sub_hashes,
|
||||
for_crate_hash,
|
||||
[$dep_tracking_marker]
|
||||
);
|
||||
)*
|
||||
let mut hasher = StableHasher::new();
|
||||
dep_tracking::stable_hash(sub_hashes,
|
||||
&mut hasher,
|
||||
self.error_format,
|
||||
for_crate_hash);
|
||||
$({
|
||||
hash_substruct!($opt,
|
||||
dep_tracking::stable_hash(
|
||||
sub_hashes,
|
||||
&mut hasher,
|
||||
self.error_format,
|
||||
for_crate_hash,
|
||||
);
|
||||
$(
|
||||
hash_substruct!(
|
||||
$opt,
|
||||
&self.$opt,
|
||||
self.error_format,
|
||||
for_crate_hash,
|
||||
&mut hasher,
|
||||
[$dep_tracking_marker]);
|
||||
})*
|
||||
[$dep_tracking_marker]
|
||||
);
|
||||
)*
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
pub fn gather_target_modifiers(&self) -> Vec<TargetModifier> {
|
||||
let mut mods = Vec::<TargetModifier>::new();
|
||||
$({
|
||||
gather_tmods_top_level!($opt,
|
||||
&self.$opt, &mut mods, &self.target_modifiers,
|
||||
[$dep_tracking_marker $($tmod),*]);
|
||||
})*
|
||||
$(
|
||||
gather_tmods_top_level!(
|
||||
$opt,
|
||||
&self.$opt,
|
||||
&mut mods,
|
||||
&self.target_modifiers,
|
||||
[$dep_tracking_marker $($tmod),*]
|
||||
);
|
||||
)*
|
||||
mods.sort_by(|a, b| a.opt.cmp(&b.opt));
|
||||
mods
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
top_level_options!(
|
||||
@@ -658,80 +682,130 @@ pub(super) fn $opt(
|
||||
/// generated code to parse an option into its respective field in the struct. There are a few
|
||||
/// hand-written parsers for parsing specific types of values in this module.
|
||||
macro_rules! options {
|
||||
($struct_name:ident, $tmod_enum_name:ident, $stat:ident, $optmod:ident, $prefix:expr, $outputname:expr,
|
||||
$($( #[$attr:meta] )* $opt:ident : $t:ty = (
|
||||
$init:expr,
|
||||
$parse:ident,
|
||||
[$dep_tracking_marker:ident $( $modifier_kind:ident )?],
|
||||
$desc:expr
|
||||
$(, removed: $removed:ident )?)
|
||||
),* ,) =>
|
||||
(
|
||||
#[derive(Clone)]
|
||||
#[rustc_lint_opt_ty]
|
||||
pub struct $struct_name { $( $( #[$attr] )* pub $opt: $t),* }
|
||||
(
|
||||
$struct_name:ident,
|
||||
$tmod_enum_name:ident,
|
||||
$stat:ident,
|
||||
$optmod:ident,
|
||||
$prefix:expr,
|
||||
$outputname:expr,
|
||||
|
||||
tmod_enum!( $tmod_enum_name, $prefix, {$($opt, $parse, $t, [$($modifier_kind),*])|*} );
|
||||
$(
|
||||
$(#[$attr:meta])*
|
||||
$opt:ident : $t:ty = (
|
||||
$init:expr,
|
||||
$parse:ident,
|
||||
[$dep_tracking_marker:ident $( $modifier_kind:ident )?],
|
||||
$desc:expr
|
||||
$(, removed: $removed:ident )?
|
||||
),
|
||||
)*
|
||||
) => {
|
||||
#[derive(Clone)]
|
||||
#[rustc_lint_opt_ty]
|
||||
pub struct $struct_name {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
pub $opt: $t,
|
||||
)*
|
||||
}
|
||||
|
||||
impl Default for $struct_name {
|
||||
fn default() -> $struct_name {
|
||||
$struct_name { $($opt: $init),* }
|
||||
tmod_enum!(
|
||||
$tmod_enum_name,
|
||||
$prefix,
|
||||
{
|
||||
$(
|
||||
$opt, $parse, $t, [$($modifier_kind),*]
|
||||
)|*
|
||||
}
|
||||
);
|
||||
|
||||
impl Default for $struct_name {
|
||||
fn default() -> $struct_name {
|
||||
$struct_name {
|
||||
$(
|
||||
$opt: $init,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl $struct_name {
|
||||
pub fn build(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
matches: &getopts::Matches,
|
||||
target_modifiers: &mut CollectedOptions,
|
||||
) -> $struct_name {
|
||||
build_options(early_dcx, matches, target_modifiers, $stat, $prefix, $outputname)
|
||||
}
|
||||
|
||||
fn dep_tracking_hash(
|
||||
&self,
|
||||
for_crate_hash: bool,
|
||||
error_format: ErrorOutputType,
|
||||
) -> Hash64 {
|
||||
let mut sub_hashes = BTreeMap::new();
|
||||
$(
|
||||
hash_opt!(
|
||||
$opt,
|
||||
&self.$opt,
|
||||
&mut sub_hashes,
|
||||
for_crate_hash,
|
||||
[$dep_tracking_marker]
|
||||
);
|
||||
)*
|
||||
let mut hasher = StableHasher::new();
|
||||
dep_tracking::stable_hash(
|
||||
sub_hashes,
|
||||
&mut hasher,
|
||||
error_format,
|
||||
for_crate_hash,
|
||||
);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
pub fn gather_target_modifiers(
|
||||
&self,
|
||||
_mods: &mut Vec<TargetModifier>,
|
||||
_tmod_vals: &BTreeMap<OptionsTargetModifiers, String>,
|
||||
) {
|
||||
$(
|
||||
gather_tmods!(
|
||||
$struct_name,
|
||||
$tmod_enum_name,
|
||||
$opt,
|
||||
&self.$opt,
|
||||
$init,
|
||||
_mods,
|
||||
_tmod_vals,
|
||||
[$dep_tracking_marker],
|
||||
[$($modifier_kind),*]
|
||||
);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
pub const $stat: OptionDescrs<$struct_name> = &[
|
||||
$(
|
||||
OptionDesc {
|
||||
name: stringify!($opt),
|
||||
setter: $optmod::$opt,
|
||||
type_desc: desc::$parse,
|
||||
desc: $desc,
|
||||
removed: None $( .or(Some(RemovedOption::$removed)) )?,
|
||||
tmod: tmod_enum_opt!($struct_name, $tmod_enum_name, $opt, $($modifier_kind),*),
|
||||
mitigation: mitigation_enum_opt!($opt, $($modifier_kind),*),
|
||||
},
|
||||
)*
|
||||
];
|
||||
|
||||
mod $optmod {
|
||||
$(
|
||||
setter_for!($opt, $struct_name, $parse);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl $struct_name {
|
||||
pub fn build(
|
||||
early_dcx: &EarlyDiagCtxt,
|
||||
matches: &getopts::Matches,
|
||||
target_modifiers: &mut CollectedOptions,
|
||||
) -> $struct_name {
|
||||
build_options(early_dcx, matches, target_modifiers, $stat, $prefix, $outputname)
|
||||
}
|
||||
|
||||
fn dep_tracking_hash(&self, for_crate_hash: bool, error_format: ErrorOutputType) -> Hash64 {
|
||||
let mut sub_hashes = BTreeMap::new();
|
||||
$({
|
||||
hash_opt!($opt,
|
||||
&self.$opt,
|
||||
&mut sub_hashes,
|
||||
for_crate_hash,
|
||||
[$dep_tracking_marker]);
|
||||
})*
|
||||
let mut hasher = StableHasher::new();
|
||||
dep_tracking::stable_hash(sub_hashes,
|
||||
&mut hasher,
|
||||
error_format,
|
||||
for_crate_hash
|
||||
);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
pub fn gather_target_modifiers(
|
||||
&self,
|
||||
_mods: &mut Vec<TargetModifier>,
|
||||
_tmod_vals: &BTreeMap<OptionsTargetModifiers, String>,
|
||||
) {
|
||||
$({
|
||||
gather_tmods!($struct_name, $tmod_enum_name, $opt, &self.$opt, $init, _mods, _tmod_vals,
|
||||
[$dep_tracking_marker], [$($modifier_kind),*]);
|
||||
})*
|
||||
}
|
||||
}
|
||||
|
||||
pub const $stat: OptionDescrs<$struct_name> =
|
||||
&[ $( OptionDesc{ name: stringify!($opt), setter: $optmod::$opt,
|
||||
type_desc: desc::$parse, desc: $desc, removed: None $( .or(Some(RemovedOption::$removed)) )?,
|
||||
tmod: tmod_enum_opt!($struct_name, $tmod_enum_name, $opt, $($modifier_kind),*),
|
||||
mitigation: mitigation_enum_opt!($opt, $($modifier_kind),*),
|
||||
} ),* ];
|
||||
|
||||
mod $optmod {
|
||||
$(
|
||||
setter_for!($opt, $struct_name, $parse);
|
||||
)*
|
||||
}
|
||||
|
||||
) }
|
||||
}
|
||||
|
||||
impl CodegenOptions {
|
||||
// JUSTIFICATION: defn of the suggested wrapper fn
|
||||
|
||||
+2
-2
@@ -146,9 +146,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.184"
|
||||
version = "0.2.185"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af"
|
||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
||||
@@ -244,6 +244,14 @@ pub fn as_str(&self) -> Option<&str> {
|
||||
PanicMessage::Unknown => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> Option<String> {
|
||||
match self {
|
||||
PanicMessage::StaticStr(s) => Some(s.into()),
|
||||
PanicMessage::String(s) => Some(s),
|
||||
PanicMessage::Unknown => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Encode<S> for PanicMessage {
|
||||
|
||||
@@ -33,7 +33,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false }
|
||||
addr2line = { version = "0.25.0", optional = true, default-features = false }
|
||||
|
||||
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
||||
libc = { version = "0.2.184", default-features = false, features = [
|
||||
libc = { version = "0.2.185", default-features = false, features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
impl From<bridge::PanicMessage> for crate::PanicMessage {
|
||||
fn from(p: bridge::PanicMessage) -> Self {
|
||||
Self { message: p.as_str().map(|s| s.to_owned()) }
|
||||
Self { message: p.into_string() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ error[E0599]: no method named `push` found for struct `rustc_confusables_across_
|
||||
--> $DIR/rustc_confusables.rs:17:7
|
||||
|
|
||||
LL | x.push();
|
||||
| ^^^^ method not found in `rustc_confusables_across_crate::BTreeSet`
|
||||
| ^^^^
|
||||
|
|
||||
help: you might have meant to use `insert`
|
||||
|
|
||||
|
||||
@@ -20,7 +20,7 @@ LL | struct S;
|
||||
| -------- method `baz` not found for this struct
|
||||
...
|
||||
LL | s.baz(10);
|
||||
| ^^^ method not found in `S`
|
||||
| ^^^
|
||||
|
|
||||
help: you might have meant to use `qux`
|
||||
|
|
||||
|
||||
@@ -2,7 +2,7 @@ error[E0599]: no method named `push` found for struct `BTreeSet<T, A>` in the cu
|
||||
--> $DIR/rustc_confusables_std_cases.rs:6:7
|
||||
|
|
||||
LL | x.push(1);
|
||||
| ^^^^ method not found in `BTreeSet<_>`
|
||||
| ^^^^
|
||||
|
|
||||
help: you might have meant to use `insert`
|
||||
|
|
||||
@@ -14,7 +14,7 @@ error[E0599]: no method named `push_back` found for struct `Vec<_>` in the curre
|
||||
--> $DIR/rustc_confusables_std_cases.rs:9:7
|
||||
|
|
||||
LL | x.push_back(1);
|
||||
| ^^^^^^^^^ method not found in `Vec<_>`
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
help: you might have meant to use `push`
|
||||
|
|
||||
@@ -26,7 +26,7 @@ error[E0599]: no method named `push` found for struct `VecDeque<T, A>` in the cu
|
||||
--> $DIR/rustc_confusables_std_cases.rs:12:7
|
||||
|
|
||||
LL | x.push(1);
|
||||
| ^^^^ method not found in `VecDeque<_>`
|
||||
| ^^^^
|
||||
|
|
||||
note: there's an earlier shadowed binding `x` of type `Vec<_>` that has method `push` available
|
||||
--> $DIR/rustc_confusables_std_cases.rs:8:9
|
||||
@@ -104,7 +104,7 @@ error[E0599]: no method named `append` found for struct `String` in the current
|
||||
--> $DIR/rustc_confusables_std_cases.rs:24:19
|
||||
|
|
||||
LL | String::new().append("");
|
||||
| ^^^^^^ method not found in `String`
|
||||
| ^^^^^^
|
||||
|
|
||||
help: you might have meant to use `push_str`
|
||||
|
|
||||
@@ -116,7 +116,7 @@ error[E0599]: no method named `get_line` found for struct `Stdin` in the current
|
||||
--> $DIR/rustc_confusables_std_cases.rs:28:11
|
||||
|
|
||||
LL | stdin.get_line(&mut buffer).unwrap();
|
||||
| ^^^^^^^^ method not found in `Stdin`
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: you might have meant to use `read_line`
|
||||
|
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
macro_rules! m {
|
||||
(begin $ard:ident end) => {
|
||||
[$ard] //~ ERROR: expected expression, found `$`
|
||||
//~^ HELP: there is a macro metavariable with similar name
|
||||
//~^ HELP: there is a macro metavariable with a similar name
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
macro_rules! m {
|
||||
(begin $ard:ident end) => {
|
||||
[$arg] //~ ERROR: expected expression, found `$`
|
||||
//~^ HELP: there is a macro metavariable with similar name
|
||||
//~^ HELP: there is a macro metavariable with a similar name
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ LL | let _ = m![begin x end];
|
||||
| --------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: there is a macro metavariable with similar name
|
||||
help: there is a macro metavariable with a similar name
|
||||
|
|
||||
LL - [$arg]
|
||||
LL + [$ard]
|
||||
|
||||
Reference in New Issue
Block a user