macro_rules: Preserve all metavariable spans in a global side table
This commit is contained in:
parent
23a3d777c8
commit
9f8d05f29f
@ -6,6 +6,7 @@
|
|||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(let_chains)]
|
#![feature(let_chains)]
|
||||||
#![feature(macro_metavar_expr)]
|
#![feature(macro_metavar_expr)]
|
||||||
|
#![feature(map_try_insert)]
|
||||||
#![feature(proc_macro_diagnostic)]
|
#![feature(proc_macro_diagnostic)]
|
||||||
#![feature(proc_macro_internals)]
|
#![feature(proc_macro_internals)]
|
||||||
#![feature(proc_macro_span)]
|
#![feature(proc_macro_span)]
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
use rustc_errors::{pluralize, PResult};
|
use rustc_errors::{pluralize, PResult};
|
||||||
use rustc_span::hygiene::{LocalExpnId, Transparency};
|
use rustc_span::hygiene::{LocalExpnId, Transparency};
|
||||||
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
|
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
|
||||||
use rustc_span::{Span, SyntaxContext};
|
use rustc_span::{with_metavar_spans, Span, SyntaxContext};
|
||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@ -254,7 +254,8 @@ pub(super) fn transcribe<'a>(
|
|||||||
MatchedTokenTree(tt) => {
|
MatchedTokenTree(tt) => {
|
||||||
// `tt`s are emitted into the output stream directly as "raw tokens",
|
// `tt`s are emitted into the output stream directly as "raw tokens",
|
||||||
// without wrapping them into groups.
|
// without wrapping them into groups.
|
||||||
result.push(maybe_use_metavar_location(cx, &stack, sp, tt));
|
let tt = maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker);
|
||||||
|
result.push(tt);
|
||||||
}
|
}
|
||||||
MatchedNonterminal(nt) => {
|
MatchedNonterminal(nt) => {
|
||||||
// Other variables are emitted into the output stream as groups with
|
// Other variables are emitted into the output stream as groups with
|
||||||
@ -319,6 +320,17 @@ pub(super) fn transcribe<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Store the metavariable span for this original span into a side table.
|
||||||
|
/// FIXME: Try to put the metavariable span into `SpanData` instead of a side table (#118517).
|
||||||
|
/// An optimal encoding for inlined spans will need to be selected to minimize regressions.
|
||||||
|
/// The side table approach is relatively good, but not perfect due to collisions.
|
||||||
|
/// In particular, collisions happen when token is passed as an argument through several macro
|
||||||
|
/// calls, like in recursive macros.
|
||||||
|
/// The old heuristic below is used to improve spans in case of collisions, but diagnostics are
|
||||||
|
/// still degraded sometimes in those cases.
|
||||||
|
///
|
||||||
|
/// The old heuristic:
|
||||||
|
///
|
||||||
/// Usually metavariables `$var` produce interpolated tokens, which have an additional place for
|
/// Usually metavariables `$var` produce interpolated tokens, which have an additional place for
|
||||||
/// keeping both the original span and the metavariable span. For `tt` metavariables that's not the
|
/// keeping both the original span and the metavariable span. For `tt` metavariables that's not the
|
||||||
/// case however, and there's no place for keeping a second span. So we try to give the single
|
/// case however, and there's no place for keeping a second span. So we try to give the single
|
||||||
@ -338,15 +350,12 @@ pub(super) fn transcribe<'a>(
|
|||||||
/// These are typically used for passing larger amounts of code, and tokens in that code usually
|
/// These are typically used for passing larger amounts of code, and tokens in that code usually
|
||||||
/// combine with each other and not with tokens outside of the sequence.
|
/// combine with each other and not with tokens outside of the sequence.
|
||||||
/// - The metavariable span comes from a different crate, then we prefer the more local span.
|
/// - The metavariable span comes from a different crate, then we prefer the more local span.
|
||||||
///
|
|
||||||
/// FIXME: Find a way to keep both original and metavariable spans for all tokens without
|
|
||||||
/// regressing compilation time too much. Several experiments for adding such spans were made in
|
|
||||||
/// the past (PR #95580, #118517, #118671) and all showed some regressions.
|
|
||||||
fn maybe_use_metavar_location(
|
fn maybe_use_metavar_location(
|
||||||
cx: &ExtCtxt<'_>,
|
cx: &ExtCtxt<'_>,
|
||||||
stack: &[Frame<'_>],
|
stack: &[Frame<'_>],
|
||||||
metavar_span: Span,
|
mut metavar_span: Span,
|
||||||
orig_tt: &TokenTree,
|
orig_tt: &TokenTree,
|
||||||
|
marker: &mut Marker,
|
||||||
) -> TokenTree {
|
) -> TokenTree {
|
||||||
let undelimited_seq = matches!(
|
let undelimited_seq = matches!(
|
||||||
stack.last(),
|
stack.last(),
|
||||||
@ -357,18 +366,44 @@ fn maybe_use_metavar_location(
|
|||||||
..
|
..
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if undelimited_seq || cx.source_map().is_imported(metavar_span) {
|
if undelimited_seq {
|
||||||
|
// Do not record metavar spans for tokens from undelimited sequences, for perf reasons.
|
||||||
return orig_tt.clone();
|
return orig_tt.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let insert = |mspans: &mut FxHashMap<_, _>, s, ms| match mspans.try_insert(s, ms) {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(err) => *err.entry.get() == ms, // Tried to insert the same span, still success
|
||||||
|
};
|
||||||
|
marker.visit_span(&mut metavar_span);
|
||||||
|
let no_collision = match orig_tt {
|
||||||
|
TokenTree::Token(token, ..) => {
|
||||||
|
with_metavar_spans(|mspans| insert(mspans, token.span, metavar_span))
|
||||||
|
}
|
||||||
|
TokenTree::Delimited(dspan, ..) => with_metavar_spans(|mspans| {
|
||||||
|
insert(mspans, dspan.open, metavar_span)
|
||||||
|
&& insert(mspans, dspan.close, metavar_span)
|
||||||
|
&& insert(mspans, dspan.entire(), metavar_span)
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
if no_collision || cx.source_map().is_imported(metavar_span) {
|
||||||
|
return orig_tt.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting metavar spans for the heuristic spans gives better opportunities for combining them
|
||||||
|
// with neighboring spans even despite their different syntactic contexts.
|
||||||
match orig_tt {
|
match orig_tt {
|
||||||
TokenTree::Token(Token { kind, span }, spacing) => {
|
TokenTree::Token(Token { kind, span }, spacing) => {
|
||||||
let span = metavar_span.with_ctxt(span.ctxt());
|
let span = metavar_span.with_ctxt(span.ctxt());
|
||||||
|
with_metavar_spans(|mspans| insert(mspans, span, metavar_span));
|
||||||
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
|
TokenTree::Token(Token { kind: kind.clone(), span }, *spacing)
|
||||||
}
|
}
|
||||||
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
|
TokenTree::Delimited(dspan, dspacing, delimiter, tts) => {
|
||||||
let open = metavar_span.shrink_to_lo().with_ctxt(dspan.open.ctxt());
|
let open = metavar_span.with_ctxt(dspan.open.ctxt());
|
||||||
let close = metavar_span.shrink_to_hi().with_ctxt(dspan.close.ctxt());
|
let close = metavar_span.with_ctxt(dspan.close.ctxt());
|
||||||
|
with_metavar_spans(|mspans| {
|
||||||
|
insert(mspans, open, metavar_span) && insert(mspans, close, metavar_span)
|
||||||
|
});
|
||||||
let dspan = DelimSpan::from_pair(open, close);
|
let dspan = DelimSpan::from_pair(open, close);
|
||||||
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())
|
TokenTree::Delimited(dspan, *dspacing, *delimiter, tts.clone())
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
|
|
||||||
pub mod profiling;
|
pub mod profiling;
|
||||||
|
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher};
|
||||||
use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock, Lrc};
|
use rustc_data_structures::sync::{FreezeLock, FreezeWriteGuard, Lock, Lrc};
|
||||||
|
|
||||||
@ -98,6 +99,9 @@
|
|||||||
pub struct SessionGlobals {
|
pub struct SessionGlobals {
|
||||||
symbol_interner: symbol::Interner,
|
symbol_interner: symbol::Interner,
|
||||||
span_interner: Lock<span_encoding::SpanInterner>,
|
span_interner: Lock<span_encoding::SpanInterner>,
|
||||||
|
/// Maps a macro argument token into use of the corresponding metavariable in the macro body.
|
||||||
|
/// Collisions are possible and processed in `maybe_use_metavar_location` on best effort basis.
|
||||||
|
metavar_spans: Lock<FxHashMap<Span, Span>>,
|
||||||
hygiene_data: Lock<hygiene::HygieneData>,
|
hygiene_data: Lock<hygiene::HygieneData>,
|
||||||
|
|
||||||
/// A reference to the source map in the `Session`. It's an `Option`
|
/// A reference to the source map in the `Session`. It's an `Option`
|
||||||
@ -115,6 +119,7 @@ pub fn new(edition: Edition) -> SessionGlobals {
|
|||||||
SessionGlobals {
|
SessionGlobals {
|
||||||
symbol_interner: symbol::Interner::fresh(),
|
symbol_interner: symbol::Interner::fresh(),
|
||||||
span_interner: Lock::new(span_encoding::SpanInterner::default()),
|
span_interner: Lock::new(span_encoding::SpanInterner::default()),
|
||||||
|
metavar_spans: Default::default(),
|
||||||
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
|
hygiene_data: Lock::new(hygiene::HygieneData::new(edition)),
|
||||||
source_map: Lock::new(None),
|
source_map: Lock::new(None),
|
||||||
}
|
}
|
||||||
@ -168,6 +173,11 @@ pub fn create_default_session_globals_then<R>(f: impl FnOnce() -> R) -> R {
|
|||||||
// deserialization.
|
// deserialization.
|
||||||
scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
|
scoped_tls::scoped_thread_local!(static SESSION_GLOBALS: SessionGlobals);
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn with_metavar_spans<R>(f: impl FnOnce(&mut FxHashMap<Span, Span>) -> R) -> R {
|
||||||
|
with_session_globals(|session_globals| f(&mut session_globals.metavar_spans.lock()))
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: We should use this enum or something like it to get rid of the
|
// FIXME: We should use this enum or something like it to get rid of the
|
||||||
// use of magic `/rust/1.x/...` paths across the board.
|
// use of magic `/rust/1.x/...` paths across the board.
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)]
|
#[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Decodable)]
|
||||||
@ -824,29 +834,64 @@ pub fn split_at(self, pos: u32) -> (Span, Span) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if you can select metavar spans for the given spans to get matching contexts.
|
||||||
|
fn try_metavars(a: SpanData, b: SpanData, a_orig: Span, b_orig: Span) -> (SpanData, SpanData) {
|
||||||
|
let get = |mspans: &FxHashMap<_, _>, s| mspans.get(&s).copied();
|
||||||
|
match with_metavar_spans(|mspans| (get(mspans, a_orig), get(mspans, b_orig))) {
|
||||||
|
(None, None) => {}
|
||||||
|
(Some(meta_a), None) => {
|
||||||
|
let meta_a = meta_a.data();
|
||||||
|
if meta_a.ctxt == b.ctxt {
|
||||||
|
return (meta_a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(None, Some(meta_b)) => {
|
||||||
|
let meta_b = meta_b.data();
|
||||||
|
if a.ctxt == meta_b.ctxt {
|
||||||
|
return (a, meta_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some(meta_a), Some(meta_b)) => {
|
||||||
|
let meta_b = meta_b.data();
|
||||||
|
if a.ctxt == meta_b.ctxt {
|
||||||
|
return (a, meta_b);
|
||||||
|
}
|
||||||
|
let meta_a = meta_a.data();
|
||||||
|
if meta_a.ctxt == b.ctxt {
|
||||||
|
return (meta_a, b);
|
||||||
|
} else if meta_a.ctxt == meta_b.ctxt {
|
||||||
|
return (meta_a, meta_b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
/// Prepare two spans to a combine operation like `to` or `between`.
|
/// Prepare two spans to a combine operation like `to` or `between`.
|
||||||
/// FIXME: consider using declarative macro metavariable spans for the given spans if they are
|
|
||||||
/// better suitable for combining (#119412).
|
|
||||||
fn prepare_to_combine(
|
fn prepare_to_combine(
|
||||||
a_orig: Span,
|
a_orig: Span,
|
||||||
b_orig: Span,
|
b_orig: Span,
|
||||||
) -> Result<(SpanData, SpanData, Option<LocalDefId>), Span> {
|
) -> Result<(SpanData, SpanData, Option<LocalDefId>), Span> {
|
||||||
let (a, b) = (a_orig.data(), b_orig.data());
|
let (a, b) = (a_orig.data(), b_orig.data());
|
||||||
|
if a.ctxt == b.ctxt {
|
||||||
if a.ctxt != b.ctxt {
|
return Ok((a, b, if a.parent == b.parent { a.parent } else { None }));
|
||||||
// Context mismatches usually happen when procedural macros combine spans copied from
|
|
||||||
// the macro input with spans produced by the macro (`Span::*_site`).
|
|
||||||
// In that case we consider the combined span to be produced by the macro and return
|
|
||||||
// the original macro-produced span as the result.
|
|
||||||
// Otherwise we just fall back to returning the first span.
|
|
||||||
// Combining locations typically doesn't make sense in case of context mismatches.
|
|
||||||
// `is_root` here is a fast path optimization.
|
|
||||||
let a_is_callsite = a.ctxt.is_root() || a.ctxt == b.span().source_callsite().ctxt();
|
|
||||||
return Err(if a_is_callsite { b_orig } else { a_orig });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let parent = if a.parent == b.parent { a.parent } else { None };
|
let (a, b) = Span::try_metavars(a, b, a_orig, b_orig);
|
||||||
Ok((a, b, parent))
|
if a.ctxt == b.ctxt {
|
||||||
|
return Ok((a, b, if a.parent == b.parent { a.parent } else { None }));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context mismatches usually happen when procedural macros combine spans copied from
|
||||||
|
// the macro input with spans produced by the macro (`Span::*_site`).
|
||||||
|
// In that case we consider the combined span to be produced by the macro and return
|
||||||
|
// the original macro-produced span as the result.
|
||||||
|
// Otherwise we just fall back to returning the first span.
|
||||||
|
// Combining locations typically doesn't make sense in case of context mismatches.
|
||||||
|
// `is_root` here is a fast path optimization.
|
||||||
|
let a_is_callsite = a.ctxt.is_root() || a.ctxt == b.span().source_callsite().ctxt();
|
||||||
|
Err(if a_is_callsite { b_orig } else { a_orig })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This span, but in a larger context, may switch to the metavariable span if suitable.
|
/// This span, but in a larger context, may switch to the metavariable span if suitable.
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
Function name: no_spans::affected_function
|
||||||
|
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1a, 1c, 00, 1d]
|
||||||
|
Number of files: 1
|
||||||
|
- file 0 => global file 1
|
||||||
|
Number of expressions: 0
|
||||||
|
Number of file 0 mappings: 1
|
||||||
|
- Code(Counter(0)) at (prev + 26, 28) to (start + 0, 29)
|
||||||
|
|
||||||
Function name: no_spans::affected_function::{closure#0}
|
Function name: no_spans::affected_function::{closure#0}
|
||||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e]
|
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e]
|
||||||
Number of files: 1
|
Number of files: 1
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
Function name: no_spans_if_not::affected_function
|
||||||
|
Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 16, 1c, 01, 12, 02, 02, 0d, 00, 0f, 00, 02, 0d, 00, 0f]
|
||||||
|
Number of files: 1
|
||||||
|
- file 0 => global file 1
|
||||||
|
Number of expressions: 1
|
||||||
|
- expression 0 operands: lhs = Counter(0), rhs = Zero
|
||||||
|
Number of file 0 mappings: 3
|
||||||
|
- Code(Counter(0)) at (prev + 22, 28) to (start + 1, 18)
|
||||||
|
- Code(Expression(0, Sub)) at (prev + 2, 13) to (start + 0, 15)
|
||||||
|
= (c0 - Zero)
|
||||||
|
- Code(Zero) at (prev + 2, 13) to (start + 0, 15)
|
||||||
|
|
||||||
Function name: no_spans_if_not::main
|
Function name: no_spans_if_not::main
|
||||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
|
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02]
|
||||||
Number of files: 1
|
Number of files: 1
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//@ check-pass
|
||||||
//@ edition:2018
|
//@ edition:2018
|
||||||
//@ aux-build:anon-params-edition-hygiene.rs
|
//@ aux-build:anon-params-edition-hygiene.rs
|
||||||
|
|
||||||
@ -8,7 +9,6 @@
|
|||||||
extern crate anon_params_edition_hygiene;
|
extern crate anon_params_edition_hygiene;
|
||||||
|
|
||||||
generate_trait_2015_ident!(u8);
|
generate_trait_2015_ident!(u8);
|
||||||
// FIXME: Edition hygiene doesn't work correctly with `tt`s in this case.
|
generate_trait_2015_tt!(u8);
|
||||||
generate_trait_2015_tt!(u8); //~ ERROR expected one of `:`, `@`, or `|`, found `)`
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
error: expected one of `:`, `@`, or `|`, found `)`
|
|
||||||
--> $DIR/anon-params-edition-hygiene.rs:12:1
|
|
||||||
|
|
|
||||||
LL | generate_trait_2015_tt!(u8);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected one of `:`, `@`, or `|`
|
|
||||||
|
|
|
||||||
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
|
|
||||||
= note: this error originates in the macro `generate_trait_2015_tt` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
help: if this is a `self` type, give it a parameter name
|
|
||||||
|
|
|
||||||
LL | generate_trait_2015_tt!(self: u8);
|
|
||||||
| +++++
|
|
||||||
help: if this is a parameter name, give it a type
|
|
||||||
|
|
|
||||||
LL | generate_trait_2015_tt!(u8: TypeName);
|
|
||||||
| ++++++++++
|
|
||||||
help: if this is a type, explicitly ignore the parameter name
|
|
||||||
|
|
|
||||||
LL | generate_trait_2015_tt!(_: u8);
|
|
||||||
| ++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
@ -16,7 +16,7 @@ macro_rules! local_passes_ident {
|
|||||||
($i: ident) => ($i) //~ ERROR macro expansion ends with an incomplete expression
|
($i: ident) => ($i) //~ ERROR macro expansion ends with an incomplete expression
|
||||||
}
|
}
|
||||||
macro_rules! local_passes_tt {
|
macro_rules! local_passes_tt {
|
||||||
($i: tt) => ($i) //~ ERROR macro expansion ends with an incomplete expression
|
($i: tt) => ($i)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_async() {
|
pub fn check_async() {
|
||||||
@ -34,7 +34,7 @@ pub fn check_async() {
|
|||||||
if passes_tt!(r#async) == 1 {} // OK
|
if passes_tt!(r#async) == 1 {} // OK
|
||||||
if local_passes_ident!(async) == 1 {} // Error reported above in the macro
|
if local_passes_ident!(async) == 1 {} // Error reported above in the macro
|
||||||
if local_passes_ident!(r#async) == 1 {} // OK
|
if local_passes_ident!(r#async) == 1 {} // OK
|
||||||
if local_passes_tt!(async) == 1 {} // Error reported above in the macro
|
if local_passes_tt!(async) == 1 {} //~ ERROR macro expansion ends with an incomplete expression
|
||||||
if local_passes_tt!(r#async) == 1 {} // OK
|
if local_passes_tt!(r#async) == 1 {} // OK
|
||||||
module::async(); //~ ERROR expected identifier, found keyword `async`
|
module::async(); //~ ERROR expected identifier, found keyword `async`
|
||||||
module::r#async(); // OK
|
module::r#async(); // OK
|
||||||
|
@ -68,10 +68,10 @@ LL | ($i: ident) => ($i)
|
|||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `|`, or `||`
|
||||||
|
|
||||||
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
error: macro expansion ends with an incomplete expression: expected one of `move`, `|`, or `||`
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:19:20
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:37:30
|
||||||
|
|
|
|
||||||
LL | ($i: tt) => ($i)
|
LL | if local_passes_tt!(async) == 1 {}
|
||||||
| ^ expected one of `move`, `|`, or `||`
|
| ^ expected one of `move`, `|`, or `||`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/edition-keywords-2018-2018-parsing.rs:42:33
|
--> $DIR/edition-keywords-2018-2018-parsing.rs:42:33
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
macro_rules! identity_mbe {
|
macro_rules! identity_mbe {
|
||||||
($tt:tt) => {
|
($tt:tt) => {
|
||||||
$tt
|
$tt
|
||||||
//~^ ERROR there is no argument named `a`
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,6 +15,7 @@ fn main() {
|
|||||||
format!(identity_pm!("{a}"));
|
format!(identity_pm!("{a}"));
|
||||||
//~^ ERROR there is no argument named `a`
|
//~^ ERROR there is no argument named `a`
|
||||||
format!(identity_mbe!("{a}"));
|
format!(identity_mbe!("{a}"));
|
||||||
|
//~^ ERROR there is no argument named `a`
|
||||||
format!(concat!("{a}"));
|
format!(concat!("{a}"));
|
||||||
//~^ ERROR there is no argument named `a`
|
//~^ ERROR there is no argument named `a`
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: there is no argument named `a`
|
error: there is no argument named `a`
|
||||||
--> $DIR/format-args-capture-first-literal-is-macro.rs:16:26
|
--> $DIR/format-args-capture-first-literal-is-macro.rs:15:26
|
||||||
|
|
|
|
||||||
LL | format!(identity_pm!("{a}"));
|
LL | format!(identity_pm!("{a}"));
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -8,10 +8,10 @@ LL | format!(identity_pm!("{a}"));
|
|||||||
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
|
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
|
||||||
|
|
||||||
error: there is no argument named `a`
|
error: there is no argument named `a`
|
||||||
--> $DIR/format-args-capture-first-literal-is-macro.rs:8:9
|
--> $DIR/format-args-capture-first-literal-is-macro.rs:17:27
|
||||||
|
|
|
|
||||||
LL | $tt
|
LL | format!(identity_mbe!("{a}"));
|
||||||
| ^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: did you intend to capture a variable `a` from the surrounding scope?
|
= note: did you intend to capture a variable `a` from the surrounding scope?
|
||||||
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
|
= note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
|
||||||
|
@ -110,10 +110,12 @@ fn cmp<T: ?Sized>(a: *mut T, b: *mut T) -> bool {
|
|||||||
{
|
{
|
||||||
macro_rules! cmp {
|
macro_rules! cmp {
|
||||||
($a:tt, $b:tt) => { $a == $b }
|
($a:tt, $b:tt) => { $a == $b }
|
||||||
//~^ WARN ambiguous wide pointer comparison
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This lint uses some custom span combination logic.
|
||||||
|
// Rewrite it to adapt to the new metavariable span rules.
|
||||||
cmp!(a, b);
|
cmp!(a, b);
|
||||||
|
//~^ WARN ambiguous wide pointer comparison
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -421,18 +421,18 @@ LL | std::ptr::eq(*a, *b)
|
|||||||
| ~~~~~~~~~~~~~ ~ +
|
| ~~~~~~~~~~~~~ ~ +
|
||||||
|
|
||||||
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
||||||
--> $DIR/wide_pointer_comparisons.rs:112:33
|
--> $DIR/wide_pointer_comparisons.rs:117:14
|
||||||
|
|
|
|
||||||
LL | ($a:tt, $b:tt) => { $a == $b }
|
LL | cmp!(a, b);
|
||||||
| ^^^^^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
help: use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
||||||
|
|
|
|
||||||
LL | ($a:tt, $b:tt) => { std::ptr::addr_eq($a, $b) }
|
LL | cmp!(std::ptr::addr_eq(a, b));
|
||||||
| ++++++++++++++++++ ~ +
|
| ++++++++++++++++++ ~ +
|
||||||
|
|
||||||
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
||||||
--> $DIR/wide_pointer_comparisons.rs:121:39
|
--> $DIR/wide_pointer_comparisons.rs:123:39
|
||||||
|
|
|
|
||||||
LL | ($a:ident, $b:ident) => { $a == $b }
|
LL | ($a:ident, $b:ident) => { $a == $b }
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
@ -447,7 +447,7 @@ LL | ($a:ident, $b:ident) => { std::ptr::addr_eq($a, $b) }
|
|||||||
| ++++++++++++++++++ ~ +
|
| ++++++++++++++++++ ~ +
|
||||||
|
|
||||||
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
warning: ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
||||||
--> $DIR/wide_pointer_comparisons.rs:131:37
|
--> $DIR/wide_pointer_comparisons.rs:133:37
|
||||||
|
|
|
|
||||||
LL | ($a:expr, $b:expr) => { $a == $b }
|
LL | ($a:expr, $b:expr) => { $a == $b }
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
macro_rules! make_macro {
|
macro_rules! make_macro {
|
||||||
($macro_name:tt) => {
|
($macro_name:tt) => {
|
||||||
macro_rules! $macro_name {
|
macro_rules! $macro_name {
|
||||||
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
//~^ ERROR macro expansion ignores token `{` and any following
|
||||||
//~| ERROR macro expansion ignores token `{` and any following
|
|
||||||
//~| ERROR cannot find macro `macro_rules` in this scope
|
//~| ERROR cannot find macro `macro_rules` in this scope
|
||||||
() => {}
|
() => {}
|
||||||
}
|
}
|
||||||
@ -14,3 +13,4 @@ macro_rules! $macro_name {
|
|||||||
}
|
}
|
||||||
|
|
||||||
make_macro!((meow));
|
make_macro!((meow));
|
||||||
|
//~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
error: macros that expand to items must be delimited with braces or followed by a semicolon
|
||||||
--> $DIR/issue-118786.rs:7:22
|
--> $DIR/issue-118786.rs:15:13
|
||||||
|
|
|
|
||||||
LL | macro_rules! $macro_name {
|
LL | make_macro!((meow));
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
help: change the delimiters to curly braces
|
help: change the delimiters to curly braces
|
||||||
|
|
|
|
||||||
LL | macro_rules! {$macro_name} {
|
LL | make_macro!({meow});
|
||||||
| + +
|
| ~ ~
|
||||||
help: add a semicolon
|
help: add a semicolon
|
||||||
|
|
|
|
||||||
LL | macro_rules! $macro_name; {
|
LL | macro_rules! $macro_name; {
|
||||||
|
@ -47,8 +47,8 @@ LL | local_bar_tt.pow(2);
|
|||||||
|
|
|
|
||||||
help: you must specify a type for this binding, like `i32`
|
help: you must specify a type for this binding, like `i32`
|
||||||
|
|
|
|
||||||
LL | ($tt:tt) => { let $tt: i32 = 42; }
|
LL | local_mac_tt!(local_bar_tt: i32);
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
|
error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}`
|
||||||
--> $DIR/method-on-ambiguous-numeric-type.rs:37:9
|
--> $DIR/method-on-ambiguous-numeric-type.rs:37:9
|
||||||
|
@ -15,7 +15,7 @@ LL | bar { baz: $rest }
|
|||||||
help: if `bar` is a function, use the arguments directly
|
help: if `bar` is a function, use the arguments directly
|
||||||
|
|
|
|
||||||
LL - bar(baz: $rest)
|
LL - bar(baz: $rest)
|
||||||
LL + bar(: $rest)
|
LL + bar($rest)
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
@ -5,6 +5,11 @@ LL | $($c)ö* {}
|
|||||||
| ^ - if this block is the condition of the `if` expression, then it must be followed by another block
|
| ^ - if this block is the condition of the `if` expression, then it must be followed by another block
|
||||||
| |
|
| |
|
||||||
| expected condition here
|
| expected condition here
|
||||||
|
...
|
||||||
|
LL | x!(if);
|
||||||
|
| ------ in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `x` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
macro_rules! x {
|
macro_rules! x {
|
||||||
($($c:tt)*) => {
|
($($c:tt)*) => {
|
||||||
$($c)ö* //~ ERROR macro expansion ends with an incomplete expression: expected expression
|
$($c)ö*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
x!(!);
|
x!(!); //~ ERROR macro expansion ends with an incomplete expression: expected expression
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: macro expansion ends with an incomplete expression: expected expression
|
error: macro expansion ends with an incomplete expression: expected expression
|
||||||
--> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:3:13
|
--> $DIR/issue-68092-unicode-ident-after-incomplete-expr.rs:8:9
|
||||||
|
|
|
|
||||||
LL | $($c)ö*
|
LL | x!(!);
|
||||||
| ^ expected expression
|
| ^ expected expression
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
|
|||||||
span: $DIR/capture-macro-rules-invoke.rs:47:19: 47:20 (#0),
|
span: $DIR/capture-macro-rules-invoke.rs:47:19: 47:20 (#0),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
span: $DIR/capture-macro-rules-invoke.rs:15:60: 15:63 (#0),
|
span: $DIR/capture-macro-rules-invoke.rs:47:13: 47:22 (#0),
|
||||||
},
|
},
|
||||||
Punct {
|
Punct {
|
||||||
ch: ',',
|
ch: ',',
|
||||||
|
@ -111,10 +111,13 @@ mod everything_outside_with_tt_inner {
|
|||||||
mod everything_outside_with_tt_outer {
|
mod everything_outside_with_tt_outer {
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($b:lifetime $colon:tt $a:tt) => {
|
($b:lifetime $colon:tt $a:tt) => {
|
||||||
struct Foo<$a, $b >(&$a &$b ());
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
||||||
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||||
|
// ^ ERROR: outlives requirements can be inferred
|
||||||
|
struct Bar<$a, $b>(&$a &$b ()) ;
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
|
||||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m!('b: 'a);
|
m!('b: 'a);
|
||||||
@ -123,9 +126,10 @@ mod everything_outside_with_tt_outer {
|
|||||||
mod everything_outside_with_tt_both {
|
mod everything_outside_with_tt_both {
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($b:tt $colon:tt $a:tt) => {
|
($b:tt $colon:tt $a:tt) => {
|
||||||
struct Foo<$a, $b >(&$a &$b ());
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||||
struct Bar<$a, $b>(&$a &$b ()) where ;
|
// ^ ERROR: outlives requirements can be inferred
|
||||||
|
struct Bar<$a, $b>(&$a &$b ()) ;
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
|
@ -111,10 +111,13 @@ macro_rules! m {
|
|||||||
mod everything_outside_with_tt_outer {
|
mod everything_outside_with_tt_outer {
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($b:lifetime $colon:tt $a:tt) => {
|
($b:lifetime $colon:tt $a:tt) => {
|
||||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||||
|
// ^ ERROR: outlives requirements can be inferred
|
||||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||||
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m!('b: 'a);
|
m!('b: 'a);
|
||||||
@ -123,8 +126,9 @@ macro_rules! m {
|
|||||||
mod everything_outside_with_tt_both {
|
mod everything_outside_with_tt_both {
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($b:tt $colon:tt $a:tt) => {
|
($b:tt $colon:tt $a:tt) => {
|
||||||
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
||||||
|
// ^ ERROR: outlives requirements can be inferred
|
||||||
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||||
//~^ ERROR: outlives requirements can be inferred
|
//~^ ERROR: outlives requirements can be inferred
|
||||||
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||||
|
@ -83,25 +83,40 @@ LL | m!('b: 'a);
|
|||||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: outlives requirements can be inferred
|
error: outlives requirements can be inferred
|
||||||
--> $DIR/edition-lint-infer-outlives-macro.rs:114:31
|
--> $DIR/edition-lint-infer-outlives-macro.rs:117:44
|
||||||
|
|
|
||||||
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
||||||
| ^^^^^^^^^ help: remove this bound
|
|
||||||
|
|
||||||
error: outlives requirements can be inferred
|
|
||||||
--> $DIR/edition-lint-infer-outlives-macro.rs:126:31
|
|
||||||
|
|
|
||||||
LL | struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
||||||
| ^^^^^^^^^ help: remove this bound
|
|
||||||
|
|
||||||
error: outlives requirements can be inferred
|
|
||||||
--> $DIR/edition-lint-infer-outlives-macro.rs:128:50
|
|
||||||
|
|
|
|
||||||
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||||
| ^^^^^^^^^^^^ help: remove this bound
|
| ^^^^^^^^^^^^^^^^^^ help: remove this bound
|
||||||
|
...
|
||||||
|
LL | m!('b: 'a);
|
||||||
|
| ---------- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: outlives requirements can be inferred
|
error: outlives requirements can be inferred
|
||||||
--> $DIR/edition-lint-infer-outlives-macro.rs:130:61
|
--> $DIR/edition-lint-infer-outlives-macro.rs:119:61
|
||||||
|
|
|
||||||
|
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||||
|
| ^^^^^^^^^^^^ help: remove this bound
|
||||||
|
...
|
||||||
|
LL | m!('b: 'a);
|
||||||
|
| ---------- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: outlives requirements can be inferred
|
||||||
|
--> $DIR/edition-lint-infer-outlives-macro.rs:132:44
|
||||||
|
|
|
||||||
|
LL | struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ help: remove this bound
|
||||||
|
...
|
||||||
|
LL | m!('b: 'a);
|
||||||
|
| ---------- in this macro invocation
|
||||||
|
|
|
||||||
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: outlives requirements can be inferred
|
||||||
|
--> $DIR/edition-lint-infer-outlives-macro.rs:134:61
|
||||||
|
|
|
|
||||||
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
LL | struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
||||||
| ^^^^^^^^^^^^ help: remove this bound
|
| ^^^^^^^^^^^^ help: remove this bound
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
($a:tt $b:tt) => {
|
($a:tt $b:tt) => {
|
||||||
$b $a; //~ WARN struct `S` is never constructed
|
$b $a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
m!(S struct);
|
m!(S struct); //~ WARN struct `S` is never constructed
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
warning: struct `S` is never constructed
|
warning: struct `S` is never constructed
|
||||||
--> $DIR/macro-span-replacement.rs:7:12
|
--> $DIR/macro-span-replacement.rs:12:8
|
||||||
|
|
|
|
||||||
LL | $b $a;
|
|
||||||
| ^^
|
|
||||||
...
|
|
||||||
LL | m!(S struct);
|
LL | m!(S struct);
|
||||||
| ------------ in this macro invocation
|
| ^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/macro-span-replacement.rs:3:9
|
--> $DIR/macro-span-replacement.rs:3:9
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: function can not have more than 65535 arguments
|
error: function can not have more than 65535 arguments
|
||||||
--> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:22
|
--> $DIR/issue-88577-check-fn-with-more-than-65535-arguments.rs:6:17
|
||||||
|
|
|
|
||||||
LL | fn _f($($t: ()),*) {}
|
LL | fn _f($($t: ()),*) {}
|
||||||
| ^
|
| ^^^^^^
|
||||||
...
|
...
|
||||||
LL | many_args!{[_]########## ######}
|
LL | many_args!{[_]########## ######}
|
||||||
| -------------------------------- in this macro invocation
|
| -------------------------------- in this macro invocation
|
||||||
|
@ -58,12 +58,12 @@ macro_rules! nested2_ident {
|
|||||||
// instead of the enum variant
|
// instead of the enum variant
|
||||||
macro_rules! nested1_tt_args_in_first_macro {
|
macro_rules! nested1_tt_args_in_first_macro {
|
||||||
() => (nested2_tt_args_in_first_macro!(i32, u32));
|
() => (nested2_tt_args_in_first_macro!(i32, u32));
|
||||||
|
//~^ ERROR type arguments are not allowed on this type
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! nested2_tt_args_in_first_macro {
|
macro_rules! nested2_tt_args_in_first_macro {
|
||||||
($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
||||||
//~^ ERROR type arguments are not allowed on this type
|
//~^ ERROR mismatched types
|
||||||
//~| ERROR mismatched types
|
|
||||||
= 5 { true } else { false });
|
= 5 { true } else { false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
error[E0109]: type arguments are not allowed on this type
|
error[E0109]: type arguments are not allowed on this type
|
||||||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:51
|
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:15:51
|
||||||
|
|
|
|
||||||
|
LL | () => (recursive_tt!(VariantB));
|
||||||
|
| -------- not allowed on this type
|
||||||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
|
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
|
||||||
| -------- ^^^ ^^^ type argument not allowed
|
| ^^^ ^^^ type argument not allowed
|
||||||
| |
|
|
||||||
| not allowed on this type
|
|
||||||
...
|
...
|
||||||
LL | recursive_tt!();
|
LL | recursive_tt!();
|
||||||
| --------------- in this macro invocation
|
| --------------- in this macro invocation
|
||||||
@ -69,10 +69,11 @@ LL | recursive_ident!();
|
|||||||
error[E0109]: type arguments are not allowed on this type
|
error[E0109]: type arguments are not allowed on this type
|
||||||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:51
|
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:38:51
|
||||||
|
|
|
|
||||||
|
LL | () => (nested2_tt!(VariantB));
|
||||||
|
| -------- not allowed on this type
|
||||||
|
...
|
||||||
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
|
LL | ($variant:tt) => (if let EnumUnit::$variant::<i32, u32> {} = 5 { true } else { false });
|
||||||
| -------- ^^^ ^^^ type argument not allowed
|
| ^^^ ^^^ type argument not allowed
|
||||||
| |
|
|
||||||
| not allowed on this type
|
|
||||||
...
|
...
|
||||||
LL | nested1_tt!();
|
LL | nested1_tt!();
|
||||||
| ------------- in this macro invocation
|
| ------------- in this macro invocation
|
||||||
@ -136,12 +137,13 @@ LL | nested1_ident!();
|
|||||||
= note: this error originates in the macro `nested2_ident` which comes from the expansion of the macro `nested1_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `nested2_ident` which comes from the expansion of the macro `nested1_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0109]: type arguments are not allowed on this type
|
error[E0109]: type arguments are not allowed on this type
|
||||||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:58
|
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:60:44
|
||||||
|
|
|
|
||||||
|
LL | () => (nested2_tt_args_in_first_macro!(i32, u32));
|
||||||
|
| ^^^ ^^^ type argument not allowed
|
||||||
|
...
|
||||||
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
||||||
| -------- ^^^^^ ^^^^^ type argument not allowed
|
| -------- not allowed on this type
|
||||||
| |
|
|
||||||
| not allowed on this type
|
|
||||||
...
|
...
|
||||||
LL | nested1_tt_args_in_first_macro!();
|
LL | nested1_tt_args_in_first_macro!();
|
||||||
| --------------------------------- in this macro invocation
|
| --------------------------------- in this macro invocation
|
||||||
@ -155,11 +157,11 @@ LL + ($arg1:tt, $arg2:tt) => (if let EnumUnit::<$arg1, $arg2>::VariantB {}
|
|||||||
|
|
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:64:37
|
--> $DIR/issue-116473-ice-wrong-span-variant-args.rs:65:37
|
||||||
|
|
|
|
||||||
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
LL | ($arg1:tt, $arg2:tt) => (if let EnumUnit::VariantB::<$arg1, $arg2> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected integer, found `Enum<(), ()>`
|
||||||
...
|
LL |
|
||||||
LL | = 5 { true } else { false });
|
LL | = 5 { true } else { false });
|
||||||
| - this expression has type `{integer}`
|
| - this expression has type `{integer}`
|
||||||
...
|
...
|
||||||
|
Loading…
Reference in New Issue
Block a user