Skip to content

Commit f651b43

Browse files
committedDec 13, 2023
Auto merge of #117050 - c410-f3r:here-we-go-again, r=petrochenkov
[`RFC 3086`] Attempt to try to resolve blocking concerns Implements what is described at #83527 (comment) to hopefully make some progress. It is unknown if such approach is or isn't desired due to the lack of further feedback, as such, it is probably best to nominate this PR to the official entities. `@rustbot` labels +I-compiler-nominated
·
1.88.01.76.0
2 parents 9f1bfe5 + 0278505 commit f651b43

File tree

16 files changed

+676
-242
lines changed

16 files changed

+676
-242
lines changed
 

‎compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
/// E::A,
8282
/// }
8383
/// ```
84+
#[cfg(bootstrap)]
8485
#[macro_export]
8586
macro_rules! impl_tag {
8687
(
@@ -140,5 +141,148 @@ macro_rules! impl_tag {
140141
};
141142
}
142143

144+
/// Implements [`Tag`] for a given type.
145+
///
146+
/// You can use `impl_tag` on structs and enums.
147+
/// You need to specify the type and all its possible values,
148+
/// which can only be paths with optional fields.
149+
///
150+
/// [`Tag`]: crate::tagged_ptr::Tag
151+
///
152+
/// # Examples
153+
///
154+
/// Basic usage:
155+
///
156+
/// ```
157+
/// #![feature(macro_metavar_expr)]
158+
/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag};
159+
///
160+
/// #[derive(Copy, Clone, PartialEq, Debug)]
161+
/// enum SomeTag {
162+
/// A,
163+
/// B,
164+
/// X { v: bool },
165+
/// Y(bool, bool),
166+
/// }
167+
///
168+
/// impl_tag! {
169+
/// // The type for which the `Tag` will be implemented
170+
/// impl Tag for SomeTag;
171+
/// // You need to specify all possible tag values:
172+
/// SomeTag::A, // 0
173+
/// SomeTag::B, // 1
174+
/// // For variants with fields, you need to specify the fields:
175+
/// SomeTag::X { v: true }, // 2
176+
/// SomeTag::X { v: false }, // 3
177+
/// // For tuple variants use named syntax:
178+
/// SomeTag::Y { 0: true, 1: true }, // 4
179+
/// SomeTag::Y { 0: false, 1: true }, // 5
180+
/// SomeTag::Y { 0: true, 1: false }, // 6
181+
/// SomeTag::Y { 0: false, 1: false }, // 7
182+
/// }
183+
///
184+
/// // Tag values are assigned in order:
185+
/// assert_eq!(SomeTag::A.into_usize(), 0);
186+
/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3);
187+
/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5);
188+
///
189+
/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B);
190+
/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true });
191+
/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false));
192+
/// ```
193+
///
194+
/// Structs are supported:
195+
///
196+
/// ```
197+
/// #![feature(macro_metavar_expr)]
198+
/// # use rustc_data_structures::impl_tag;
199+
/// #[derive(Copy, Clone)]
200+
/// struct Flags { a: bool, b: bool }
201+
///
202+
/// impl_tag! {
203+
/// impl Tag for Flags;
204+
/// Flags { a: true, b: true },
205+
/// Flags { a: false, b: true },
206+
/// Flags { a: true, b: false },
207+
/// Flags { a: false, b: false },
208+
/// }
209+
/// ```
210+
///
211+
/// Not specifying all values results in a compile error:
212+
///
213+
/// ```compile_fail,E0004
214+
/// #![feature(macro_metavar_expr)]
215+
/// # use rustc_data_structures::impl_tag;
216+
/// #[derive(Copy, Clone)]
217+
/// enum E {
218+
/// A,
219+
/// B,
220+
/// }
221+
///
222+
/// impl_tag! {
223+
/// impl Tag for E;
224+
/// E::A,
225+
/// }
226+
/// ```
227+
#[cfg(not(bootstrap))]
228+
#[macro_export]
229+
macro_rules! impl_tag {
230+
(
231+
impl Tag for $Self:ty;
232+
$(
233+
$($path:ident)::* $( { $( $fields:tt )* })?,
234+
)*
235+
) => {
236+
// Safety:
237+
// `bits_for_tags` is called on the same `${index()}`-es as
238+
// `into_usize` returns, thus `BITS` constant is correct.
239+
unsafe impl $crate::tagged_ptr::Tag for $Self {
240+
const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[
241+
$(
242+
${index()},
243+
$( ${ignore($path)} )*
244+
)*
245+
]);
246+
247+
#[inline]
248+
fn into_usize(self) -> usize {
249+
// This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc)
250+
// (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>)
251+
#[forbid(unreachable_patterns)]
252+
match self {
253+
// `match` is doing heavy lifting here, by requiring exhaustiveness
254+
$(
255+
$($path)::* $( { $( $fields )* } )? => ${index()},
256+
)*
257+
}
258+
}
259+
260+
#[inline]
261+
unsafe fn from_usize(tag: usize) -> Self {
262+
match tag {
263+
$(
264+
${index()} => $($path)::* $( { $( $fields )* } )?,
265+
)*
266+
267+
// Safety:
268+
// `into_usize` only returns `${index()}` of the same
269+
// repetition as we are filtering above, thus if this is
270+
// reached, the safety contract of this function was
271+
// already breached.
272+
_ => unsafe {
273+
debug_assert!(
274+
false,
275+
"invalid tag: {tag}\
276+
(this is a bug in the caller of `from_usize`)"
277+
);
278+
std::hint::unreachable_unchecked()
279+
},
280+
}
281+
}
282+
283+
}
284+
};
285+
}
286+
143287
#[cfg(test)]
144288
mod tests;

‎compiler/rustc_expand/src/expand.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ use std::path::PathBuf;
4141
use std::rc::Rc;
4242
use std::{iter, mem};
4343

44+
#[cfg(bootstrap)]
4445
macro_rules! ast_fragments {
4546
(
4647
$($Kind:ident($AstTy:ty) {
@@ -165,6 +166,131 @@ macro_rules! ast_fragments {
165166
}
166167
}
167168

169+
#[cfg(not(bootstrap))]
170+
macro_rules! ast_fragments {
171+
(
172+
$($Kind:ident($AstTy:ty) {
173+
$kind_name:expr;
174+
$(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)?
175+
$(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)?
176+
fn $make_ast:ident;
177+
})*
178+
) => {
179+
/// A fragment of AST that can be produced by a single macro expansion.
180+
/// Can also serve as an input and intermediate result for macro expansion operations.
181+
pub enum AstFragment {
182+
OptExpr(Option<P<ast::Expr>>),
183+
MethodReceiverExpr(P<ast::Expr>),
184+
$($Kind($AstTy),)*
185+
}
186+
187+
/// "Discriminant" of an AST fragment.
188+
#[derive(Copy, Clone, PartialEq, Eq)]
189+
pub enum AstFragmentKind {
190+
OptExpr,
191+
MethodReceiverExpr,
192+
$($Kind,)*
193+
}
194+
195+
impl AstFragmentKind {
196+
pub fn name(self) -> &'static str {
197+
match self {
198+
AstFragmentKind::OptExpr => "expression",
199+
AstFragmentKind::MethodReceiverExpr => "expression",
200+
$(AstFragmentKind::$Kind => $kind_name,)*
201+
}
202+
}
203+
204+
fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> {
205+
match self {
206+
AstFragmentKind::OptExpr =>
207+
result.make_expr().map(Some).map(AstFragment::OptExpr),
208+
AstFragmentKind::MethodReceiverExpr =>
209+
result.make_expr().map(AstFragment::MethodReceiverExpr),
210+
$(AstFragmentKind::$Kind => result.$make_ast().map(AstFragment::$Kind),)*
211+
}
212+
}
213+
}
214+
215+
impl AstFragment {
216+
pub fn add_placeholders(&mut self, placeholders: &[NodeId]) {
217+
if placeholders.is_empty() {
218+
return;
219+
}
220+
match self {
221+
$($(AstFragment::$Kind(ast) => ast.extend(placeholders.iter().flat_map(|id| {
222+
${ignore($flat_map_ast_elt)}
223+
placeholder(AstFragmentKind::$Kind, *id, None).$make_ast()
224+
})),)?)*
225+
_ => panic!("unexpected AST fragment kind")
226+
}
227+
}
228+
229+
pub fn make_opt_expr(self) -> Option<P<ast::Expr>> {
230+
match self {
231+
AstFragment::OptExpr(expr) => expr,
232+
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
233+
}
234+
}
235+
236+
pub fn make_method_receiver_expr(self) -> P<ast::Expr> {
237+
match self {
238+
AstFragment::MethodReceiverExpr(expr) => expr,
239+
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
240+
}
241+
}
242+
243+
$(pub fn $make_ast(self) -> $AstTy {
244+
match self {
245+
AstFragment::$Kind(ast) => ast,
246+
_ => panic!("AstFragment::make_* called on the wrong kind of fragment"),
247+
}
248+
})*
249+
250+
fn make_ast<T: InvocationCollectorNode>(self) -> T::OutputTy {
251+
T::fragment_to_output(self)
252+
}
253+
254+
pub fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) {
255+
match self {
256+
AstFragment::OptExpr(opt_expr) => {
257+
visit_clobber(opt_expr, |opt_expr| {
258+
if let Some(expr) = opt_expr {
259+
vis.filter_map_expr(expr)
260+
} else {
261+
None
262+
}
263+
});
264+
}
265+
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
266+
$($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
267+
$($(AstFragment::$Kind(ast) =>
268+
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
269+
}
270+
}
271+
272+
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
273+
match self {
274+
AstFragment::OptExpr(Some(expr)) => visitor.visit_expr(expr),
275+
AstFragment::OptExpr(None) => {}
276+
AstFragment::MethodReceiverExpr(expr) => visitor.visit_method_receiver_expr(expr),
277+
$($(AstFragment::$Kind(ast) => visitor.$visit_ast(ast),)?)*
278+
$($(AstFragment::$Kind(ast) => for ast_elt in &ast[..] {
279+
visitor.$visit_ast_elt(ast_elt, $($args)*);
280+
})?)*
281+
}
282+
}
283+
}
284+
285+
impl<'a> MacResult for crate::mbe::macro_rules::ParserAnyMacro<'a> {
286+
$(fn $make_ast(self: Box<crate::mbe::macro_rules::ParserAnyMacro<'a>>)
287+
-> Option<$AstTy> {
288+
Some(self.make(AstFragmentKind::$Kind).$make_ast())
289+
})*
290+
}
291+
}
292+
}
293+
168294
ast_fragments! {
169295
Expr(P<ast::Expr>) { "expression"; one fn visit_expr; fn visit_expr; fn make_expr; }
170296
Pat(P<ast::Pat>) { "pattern"; one fn visit_pat; fn visit_pat; fn make_pat; }

‎compiler/rustc_expand/src/mbe/metavar_expr.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ use rustc_span::Span;
1010
/// A meta-variable expression, for expansions based on properties of meta-variables.
1111
#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
1212
pub(crate) enum MetaVarExpr {
13-
/// The number of repetitions of an identifier, optionally limited to a number
14-
/// of outer-most repetition depths. If the depth limit is `None` then the depth is unlimited.
15-
Count(Ident, Option<usize>),
13+
/// The number of repetitions of an identifier.
14+
Count(Ident, usize),
1615

1716
/// Ignore a meta-variable for repetition without expansion.
1817
Ignore(Ident),
@@ -43,7 +42,10 @@ impl MetaVarExpr {
4342
let mut iter = args.trees();
4443
let rslt = match ident.as_str() {
4544
"count" => parse_count(&mut iter, sess, ident.span)?,
46-
"ignore" => MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?),
45+
"ignore" => {
46+
eat_dollar(&mut iter, sess, ident.span)?;
47+
MetaVarExpr::Ignore(parse_ident(&mut iter, sess, ident.span)?)
48+
}
4749
"index" => MetaVarExpr::Index(parse_depth(&mut iter, sess, ident.span)?),
4850
"length" => MetaVarExpr::Length(parse_depth(&mut iter, sess, ident.span)?),
4951
_ => {
@@ -92,6 +94,7 @@ fn parse_count<'sess>(
9294
sess: &'sess ParseSess,
9395
span: Span,
9496
) -> PResult<'sess, MetaVarExpr> {
97+
eat_dollar(iter, sess, span)?;
9598
let ident = parse_ident(iter, sess, span)?;
9699
let depth = if try_eat_comma(iter) {
97100
if iter.look_ahead(0).is_none() {
@@ -100,9 +103,9 @@ fn parse_count<'sess>(
100103
"`count` followed by a comma must have an associated index indicating its depth",
101104
));
102105
}
103-
Some(parse_depth(iter, sess, span)?)
106+
parse_depth(iter, sess, span)?
104107
} else {
105-
None
108+
0
106109
};
107110
Ok(MetaVarExpr::Count(ident, depth))
108111
}
@@ -166,3 +169,20 @@ fn try_eat_comma(iter: &mut RefTokenTreeCursor<'_>) -> bool {
166169
}
167170
false
168171
}
172+
173+
/// Expects that the next item is a dollar sign.
174+
fn eat_dollar<'sess>(
175+
iter: &mut RefTokenTreeCursor<'_>,
176+
sess: &'sess ParseSess,
177+
span: Span,
178+
) -> PResult<'sess, ()> {
179+
if let Some(TokenTree::Token(token::Token { kind: token::Dollar, .. }, _)) = iter.look_ahead(0)
180+
{
181+
let _ = iter.next();
182+
return Ok(());
183+
}
184+
Err(sess.span_diagnostic.struct_span_err(
185+
span,
186+
"meta-variables within meta-variable expressions must be referenced using a dollar sign",
187+
))
188+
}

‎compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ fn lockstep_iter_size(
440440
/// declared inside a single repetition and the index `1` implies two nested repetitions.
441441
fn count_repetitions<'a>(
442442
cx: &ExtCtxt<'a>,
443-
depth_opt: Option<usize>,
443+
depth_user: usize,
444444
mut matched: &NamedMatch,
445445
repeats: &[(usize, usize)],
446446
sp: &DelimSpan,
@@ -449,37 +449,45 @@ fn count_repetitions<'a>(
449449
// (or at the top-level of `matched` if no depth is given).
450450
fn count<'a>(
451451
cx: &ExtCtxt<'a>,
452-
declared_lhs_depth: usize,
453-
depth_opt: Option<usize>,
452+
depth_curr: usize,
453+
depth_max: usize,
454454
matched: &NamedMatch,
455455
sp: &DelimSpan,
456456
) -> PResult<'a, usize> {
457457
match matched {
458-
MatchedTokenTree(_) | MatchedNonterminal(_) => {
459-
if declared_lhs_depth == 0 {
460-
return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
461-
}
462-
match depth_opt {
463-
None => Ok(1),
464-
Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
465-
}
466-
}
458+
MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1),
467459
MatchedSeq(named_matches) => {
468-
let new_declared_lhs_depth = declared_lhs_depth + 1;
469-
match depth_opt {
470-
None => named_matches
471-
.iter()
472-
.map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp))
473-
.sum(),
474-
Some(0) => Ok(named_matches.len()),
475-
Some(depth) => named_matches
460+
if depth_curr == depth_max {
461+
Ok(named_matches.len())
462+
} else {
463+
named_matches
476464
.iter()
477-
.map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp))
478-
.sum(),
465+
.map(|elem| count(cx, depth_curr + 1, depth_max, elem, sp))
466+
.sum()
479467
}
480468
}
481469
}
482470
}
471+
472+
/// Maximum depth
473+
fn depth(counter: usize, matched: &NamedMatch) -> usize {
474+
match matched {
475+
MatchedTokenTree(_) | MatchedNonterminal(_) => counter,
476+
MatchedSeq(named_matches) => {
477+
let rslt = counter + 1;
478+
if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt }
479+
}
480+
}
481+
}
482+
483+
let depth_max = depth(0, matched)
484+
.checked_sub(1)
485+
.and_then(|el| el.checked_sub(repeats.len()))
486+
.unwrap_or_default();
487+
if depth_user > depth_max {
488+
return Err(out_of_bounds_err(cx, depth_max + 1, sp.entire(), "count"));
489+
}
490+
483491
// `repeats` records all of the nested levels at which we are currently
484492
// matching meta-variables. The meta-var-expr `count($x)` only counts
485493
// matches that occur in this "subtree" of the `NamedMatch` where we
@@ -491,7 +499,12 @@ fn count_repetitions<'a>(
491499
matched = &ads[idx];
492500
}
493501
}
494-
count(cx, 0, depth_opt, matched, sp)
502+
503+
if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched {
504+
return Err(cx.create_err(CountRepetitionMisplaced { span: sp.entire() }));
505+
}
506+
507+
count(cx, depth_user, depth_max, matched, sp)
495508
}
496509

497510
/// Returns a `NamedMatch` item declared on the LHS given an arbitrary [Ident]
@@ -523,7 +536,7 @@ fn out_of_bounds_err<'a>(
523536
)
524537
} else {
525538
format!(
526-
"depth parameter on meta-variable expression `{ty}` \
539+
"depth parameter of meta-variable expression `{ty}` \
527540
must be less than {max}"
528541
)
529542
};
@@ -545,9 +558,9 @@ fn transcribe_metavar_expr<'a>(
545558
span
546559
};
547560
match *expr {
548-
MetaVarExpr::Count(original_ident, depth_opt) => {
561+
MetaVarExpr::Count(original_ident, depth) => {
549562
let matched = matched_from_ident(cx, original_ident, interp)?;
550-
let count = count_repetitions(cx, depth_opt, matched, repeats, sp)?;
563+
let count = count_repetitions(cx, depth, matched, repeats, sp)?;
551564
let tt = TokenTree::token_alone(
552565
TokenKind::lit(token::Integer, sym::integer(count), None),
553566
visited_span(),

‎library/core/src/tuple.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::marker::{StructuralEq, StructuralPartialEq};
88
//
99
// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
1010
// will implement everything for (A, B, C), (A, B) and (A,).
11+
#[cfg(bootstrap)]
1112
macro_rules! tuple_impls {
1213
// Stopping criteria (1-ary tuple)
1314
($T:ident) => {
@@ -142,6 +143,148 @@ macro_rules! tuple_impls {
142143
}
143144
}
144145

146+
// Recursive macro for implementing n-ary tuple functions and operations
147+
//
148+
// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
149+
// will implement everything for (A, B, C), (A, B) and (A,).
150+
#[cfg(not(bootstrap))]
151+
macro_rules! tuple_impls {
152+
// Stopping criteria (1-ary tuple)
153+
($T:ident) => {
154+
tuple_impls!(@impl $T);
155+
};
156+
// Running criteria (n-ary tuple, with n >= 2)
157+
($T:ident $( $U:ident )+) => {
158+
tuple_impls!($( $U )+);
159+
tuple_impls!(@impl $T $( $U )+);
160+
};
161+
// "Private" internal implementation
162+
(@impl $( $T:ident )+) => {
163+
maybe_tuple_doc! {
164+
$($T)+ @
165+
#[stable(feature = "rust1", since = "1.0.0")]
166+
impl<$($T: PartialEq),+> PartialEq for ($($T,)+)
167+
where
168+
last_type!($($T,)+): ?Sized
169+
{
170+
#[inline]
171+
fn eq(&self, other: &($($T,)+)) -> bool {
172+
$( ${ignore($T)} self.${index()} == other.${index()} )&&+
173+
}
174+
#[inline]
175+
fn ne(&self, other: &($($T,)+)) -> bool {
176+
$( ${ignore($T)} self.${index()} != other.${index()} )||+
177+
}
178+
}
179+
}
180+
181+
maybe_tuple_doc! {
182+
$($T)+ @
183+
#[stable(feature = "rust1", since = "1.0.0")]
184+
impl<$($T: Eq),+> Eq for ($($T,)+)
185+
where
186+
last_type!($($T,)+): ?Sized
187+
{}
188+
}
189+
190+
maybe_tuple_doc! {
191+
$($T)+ @
192+
#[unstable(feature = "structural_match", issue = "31434")]
193+
impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+)
194+
{}
195+
}
196+
197+
maybe_tuple_doc! {
198+
$($T)+ @
199+
#[unstable(feature = "structural_match", issue = "31434")]
200+
impl<$($T),+> StructuralPartialEq for ($($T,)+)
201+
{}
202+
}
203+
204+
maybe_tuple_doc! {
205+
$($T)+ @
206+
#[unstable(feature = "structural_match", issue = "31434")]
207+
impl<$($T),+> StructuralEq for ($($T,)+)
208+
{}
209+
}
210+
211+
maybe_tuple_doc! {
212+
$($T)+ @
213+
#[stable(feature = "rust1", since = "1.0.0")]
214+
impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
215+
where
216+
last_type!($($T,)+): ?Sized
217+
{
218+
#[inline]
219+
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
220+
lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
221+
}
222+
#[inline]
223+
fn lt(&self, other: &($($T,)+)) -> bool {
224+
lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
225+
}
226+
#[inline]
227+
fn le(&self, other: &($($T,)+)) -> bool {
228+
lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
229+
}
230+
#[inline]
231+
fn ge(&self, other: &($($T,)+)) -> bool {
232+
lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
233+
}
234+
#[inline]
235+
fn gt(&self, other: &($($T,)+)) -> bool {
236+
lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
237+
}
238+
}
239+
}
240+
241+
maybe_tuple_doc! {
242+
$($T)+ @
243+
#[stable(feature = "rust1", since = "1.0.0")]
244+
impl<$($T: Ord),+> Ord for ($($T,)+)
245+
where
246+
last_type!($($T,)+): ?Sized
247+
{
248+
#[inline]
249+
fn cmp(&self, other: &($($T,)+)) -> Ordering {
250+
lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
251+
}
252+
}
253+
}
254+
255+
maybe_tuple_doc! {
256+
$($T)+ @
257+
#[stable(feature = "rust1", since = "1.0.0")]
258+
impl<$($T: Default),+> Default for ($($T,)+) {
259+
#[inline]
260+
fn default() -> ($($T,)+) {
261+
($({ let x: $T = Default::default(); x},)+)
262+
}
263+
}
264+
}
265+
266+
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
267+
impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
268+
#[inline]
269+
#[allow(non_snake_case)]
270+
fn from(array: [T; ${count($T)}]) -> Self {
271+
let [$($T,)+] = array;
272+
($($T,)+)
273+
}
274+
}
275+
276+
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
277+
impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
278+
#[inline]
279+
#[allow(non_snake_case)]
280+
fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
281+
let ($($T,)+) = tuple;
282+
[$($T,)+]
283+
}
284+
}
285+
}
286+
}
287+
145288
// If this is a unary tuple, it adds a doc comment.
146289
// Otherwise, it hides the docs entirely.
147290
macro_rules! maybe_tuple_doc {

‎tests/ui/macros/rfc-3086-metavar-expr/count-and-length-are-distinct.rs

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ fn main() {
1010
$(
1111
// inner-most repetition
1212
$(
13-
${ignore(l)} ${index()}, ${length()},
13+
${ignore($l)} ${index()}, ${length()},
1414
)*
15-
${count(l)}, ${index()}, ${length()},
15+
${count($l)}, ${index()}, ${length()},
1616
)*
17-
${count(l)},
17+
${count($l)},
1818
]
1919
};
2020
}
@@ -72,30 +72,30 @@ fn main() {
7272
&[
7373
$( $( $(
7474
&[
75-
${ignore(i)} ${count(i, 0)},
75+
${ignore($i)} ${count($i, 0)},
7676
][..],
7777
)* )* )*
7878

7979
$( $(
8080
&[
81-
${ignore(i)} ${count(i, 0)},
82-
${ignore(i)} ${count(i, 1)},
81+
${ignore($i)} ${count($i, 0)},
82+
${ignore($i)} ${count($i, 1)},
8383
][..],
8484
)* )*
8585

8686
$(
8787
&[
88-
${ignore(i)} ${count(i, 0)},
89-
${ignore(i)} ${count(i, 1)},
90-
${ignore(i)} ${count(i, 2)},
88+
${ignore($i)} ${count($i, 0)},
89+
${ignore($i)} ${count($i, 1)},
90+
${ignore($i)} ${count($i, 2)},
9191
][..],
9292
)*
9393

9494
&[
95-
${count(i, 0)},
96-
${count(i, 1)},
97-
${count(i, 2)},
98-
${count(i, 3)},
95+
${count($i, 0)},
96+
${count($i, 1)},
97+
${count($i, 2)},
98+
${count($i, 3)},
9999
][..]
100100
][..]
101101
}
@@ -133,23 +133,23 @@ fn main() {
133133
&[7][..],
134134

135135
// (a b c) (d e f)
136-
&[2, 6][..],
136+
&[6, 2][..],
137137
// (g h) (i j k l m)
138-
&[2, 7][..],
138+
&[7, 2][..],
139139
// (n)
140140
&[1, 1][..],
141141
// (o) (p q) (r s)
142-
&[3, 5][..],
142+
&[5, 3][..],
143143
// (t u v w x y z)
144-
&[1, 7][..],
144+
&[7, 1][..],
145145

146146
// [ (a b c) (d e f) ]
147147
// [ (g h) (i j k l m) ]
148148
// [ (n) ]
149-
&[3, 5, 14][..],
149+
&[14, 5, 3][..],
150150
// [ (o) (p q) (r s) ]
151151
// [ (t u v w x y z) ]
152-
&[2, 4, 12][..],
152+
&[12, 4, 2][..],
153153

154154
// {
155155
// [ (a b c) (d e f) ]
@@ -160,7 +160,7 @@ fn main() {
160160
// [ (o) (p q) (r s) ]
161161
// [ (t u v w x y z) ]
162162
// }
163-
&[2, 5, 9, 26][..]
163+
&[26, 9, 5, 2][..]
164164
][..]
165165
);
166166

@@ -170,31 +170,31 @@ fn main() {
170170
&[
171171
$( $( $( $(
172172
&[
173-
${ignore(i)} ${length(3)},
174-
${ignore(i)} ${length(2)},
175-
${ignore(i)} ${length(1)},
176-
${ignore(i)} ${length(0)},
173+
${ignore($i)} ${length(3)},
174+
${ignore($i)} ${length(2)},
175+
${ignore($i)} ${length(1)},
176+
${ignore($i)} ${length(0)},
177177
][..],
178178
)* )* )* )*
179179

180180
$( $( $(
181181
&[
182-
${ignore(i)} ${length(2)},
183-
${ignore(i)} ${length(1)},
184-
${ignore(i)} ${length(0)},
182+
${ignore($i)} ${length(2)},
183+
${ignore($i)} ${length(1)},
184+
${ignore($i)} ${length(0)},
185185
][..],
186186
)* )* )*
187187

188188
$( $(
189189
&[
190-
${ignore(i)} ${length(1)},
191-
${ignore(i)} ${length(0)},
190+
${ignore($i)} ${length(1)},
191+
${ignore($i)} ${length(0)},
192192
][..],
193193
)* )*
194194

195195
$(
196196
&[
197-
${ignore(i)} ${length(0)},
197+
${ignore($i)} ${length(0)},
198198
][..],
199199
)*
200200
][..]

‎tests/ui/macros/rfc-3086-metavar-expr/feature-gate-macro_metavar_expr.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
/// Count the number of idents in a macro repetition.
66
macro_rules! count_idents {
77
( $( $i:ident ),* ) => {
8-
${count(i)}
8+
${count($i)}
99
};
1010
}
1111

1212
/// Count the number of idents in a 2-dimensional macro repetition.
1313
macro_rules! count_idents_2 {
1414
( $( [ $( $i:ident ),* ] ),* ) => {
15-
${count(i)}
15+
${count($i)}
1616
};
1717
}
1818

@@ -21,17 +21,17 @@ macro_rules! count_depth_limits {
2121
( $( { $( [ $( $outer:ident : ( $( $inner:ident )* ) )* ] )* } )* ) => {
2222
(
2323
(
24-
${count(inner)},
25-
${count(inner, 0)},
26-
${count(inner, 1)},
27-
${count(inner, 2)},
28-
${count(inner, 3)},
24+
${count($inner)},
25+
${count($inner, 0)},
26+
${count($inner, 1)},
27+
${count($inner, 2)},
28+
${count($inner, 3)},
2929
),
3030
(
31-
${count(outer)},
32-
${count(outer, 0)},
33-
${count(outer, 1)},
34-
${count(outer, 2)},
31+
${count($outer)},
32+
${count($outer, 0)},
33+
${count($outer, 1)},
34+
${count($outer, 2)},
3535
),
3636
)
3737
};
@@ -43,7 +43,7 @@ macro_rules! count_depth_limits {
4343
/// repetition binding.
4444
macro_rules! enumerate_literals {
4545
( $( ($l:stmt) ),* ) => {
46-
[$( ${ignore(l)} (${index()}, ${length()}) ),*]
46+
[$( ${ignore($l)} (${index()}, ${length()}) ),*]
4747
};
4848
}
4949

@@ -77,7 +77,7 @@ macro_rules! make_count_adders {
7777
$(
7878
macro_rules! $i {
7979
( $$( $$j:ident ),* ) => {
80-
$b + $${count(j)}
80+
$b + $${count($j)}
8181
};
8282
}
8383
)*
@@ -122,7 +122,7 @@ fn main() {
122122
[ T: (t u v w x y z) ]
123123
}
124124
},
125-
((26, 2, 5, 9, 26), (9, 2, 5, 9))
125+
((26, 26, 9, 5, 2), (9, 9, 5, 2))
126126
);
127127
assert_eq!(enumerate_literals![("foo"), ("bar")], [(0, 2), (1, 2)]);
128128
assert_eq!(

‎tests/ui/macros/rfc-3086-metavar-expr/issue-111904.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![feature(macro_metavar_expr)]
22

33
macro_rules! foo {
4-
( $( $($t:ident),* );* ) => { ${count(t,)} }
4+
( $( $($t:ident),* );* ) => { ${count($t,)} }
55
//~^ ERROR `count` followed by a comma must have an associated
66
//~| ERROR expected expression, found `$`
77
}

‎tests/ui/macros/rfc-3086-metavar-expr/issue-111904.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: `count` followed by a comma must have an associated index indicating its depth
22
--> $DIR/issue-111904.rs:4:37
33
|
4-
LL | ( $( $($t:ident),* );* ) => { ${count(t,)} }
4+
LL | ( $( $($t:ident),* );* ) => { ${count($t,)} }
55
| ^^^^^
66

77
error: expected expression, found `$`
88
--> $DIR/issue-111904.rs:4:35
99
|
10-
LL | ( $( $($t:ident),* );* ) => { ${count(t,)} }
10+
LL | ( $( $($t:ident),* );* ) => { ${count($t,)} }
1111
| ^ expected expression
1212
...
1313
LL | foo!(a, a; b, b);

‎tests/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ macro_rules! example {
1313
( $( [ $( ( $( $x:ident )* ) )* ] )* ) => {
1414
Example {
1515
_indexes: &[],
16-
_counts: &[${count(x, 0)}, ${count(x, 1)}, ${count(x, 2)}],
16+
_counts: &[${count($x, 0)}, ${count($x, 1)}, ${count($x, 2)}],
1717
_nested: vec![
1818
$(
1919
Example {
2020
_indexes: &[(${index()}, ${length()})],
21-
_counts: &[${count(x, 0)}, ${count(x, 1)}],
21+
_counts: &[${count($x, 0)}, ${count($x, 1)}],
2222
_nested: vec![
2323
$(
2424
Example {
2525
_indexes: &[(${index(1)}, ${length(1)}), (${index()}, ${length()})],
26-
_counts: &[${count(x)}],
26+
_counts: &[${count($x)}],
2727
_nested: vec![
2828
$(
2929
Example {
@@ -34,7 +34,7 @@ macro_rules! example {
3434
],
3535
_counts: &[],
3636
_nested: vec![],
37-
${ignore(x)}
37+
${ignore($x)}
3838
}
3939
),*
4040
]
@@ -49,9 +49,9 @@ macro_rules! example {
4949
}
5050

5151
static EXPECTED: &str = concat!(
52-
"Example { _indexes: [], _counts: [2, 4, 13], _nested: [",
52+
"Example { _indexes: [], _counts: [13, 4, 2], _nested: [",
5353
concat!(
54-
"Example { _indexes: [(0, 2)], _counts: [3, 10], _nested: [",
54+
"Example { _indexes: [(0, 2)], _counts: [10, 3], _nested: [",
5555
concat!(
5656
"Example { _indexes: [(0, 2), (0, 3)], _counts: [4], _nested: [",
5757
concat!(
@@ -77,7 +77,7 @@ static EXPECTED: &str = concat!(
7777
"] }",
7878
),
7979
"] }, ",
80-
"Example { _indexes: [(1, 2)], _counts: [1, 3], _nested: [",
80+
"Example { _indexes: [(1, 2)], _counts: [3, 1], _nested: [",
8181
concat!(
8282
"Example { _indexes: [(1, 2), (0, 1)], _counts: [3], _nested: [",
8383
concat!(

‎tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
macro_rules! a {
44
( $( { $( [ $( ( $( $foo:ident )* ) )* ] )* } )* ) => {
55
(
6-
${count(foo, 0)},
7-
${count(foo, 10)},
8-
//~^ ERROR depth parameter on meta-variable expression `count` must be less than 4
6+
${count($foo, 0)},
7+
${count($foo, 10)},
8+
//~^ ERROR depth parameter of meta-variable expression `count` must be less than 4
99
)
1010
};
1111
}
@@ -14,10 +14,10 @@ macro_rules! b {
1414
( $( { $( [ $( $foo:ident )* ] )* } )* ) => {
1515
(
1616
$( $( $(
17-
${ignore(foo)}
17+
${ignore($foo)}
1818
${index(0)},
1919
${index(10)},
20-
//~^ ERROR depth parameter on meta-variable expression `index` must be less than 3
20+
//~^ ERROR depth parameter of meta-variable expression `index` must be less than 3
2121
)* )* )*
2222
)
2323
};
@@ -27,10 +27,10 @@ macro_rules! c {
2727
( $( { $( $foo:ident )* } )* ) => {
2828
(
2929
$( $(
30-
${ignore(foo)}
30+
${ignore($foo)}
3131
${length(0)}
3232
${length(10)}
33-
//~^ ERROR depth parameter on meta-variable expression `length` must be less than 2
33+
//~^ ERROR depth parameter of meta-variable expression `length` must be less than 2
3434
)* )*
3535
)
3636
};

‎tests/ui/macros/rfc-3086-metavar-expr/out-of-bounds-arguments.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
error: depth parameter on meta-variable expression `count` must be less than 4
1+
error: depth parameter of meta-variable expression `count` must be less than 4
22
--> $DIR/out-of-bounds-arguments.rs:7:14
33
|
4-
LL | ${count(foo, 10)},
5-
| ^^^^^^^^^^^^^^^^
4+
LL | ${count($foo, 10)},
5+
| ^^^^^^^^^^^^^^^^^
66

7-
error: depth parameter on meta-variable expression `index` must be less than 3
7+
error: depth parameter of meta-variable expression `index` must be less than 3
88
--> $DIR/out-of-bounds-arguments.rs:19:18
99
|
1010
LL | ${index(10)},
1111
| ^^^^^^^^^^^
1212

13-
error: depth parameter on meta-variable expression `length` must be less than 2
13+
error: depth parameter of meta-variable expression `length` must be less than 2
1414
--> $DIR/out-of-bounds-arguments.rs:32:18
1515
|
1616
LL | ${length(10)}

‎tests/ui/macros/rfc-3086-metavar-expr/required-feature.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! count {
22
( $( $e:stmt ),* ) => {
3-
${ count(e) }
3+
${ count($e) }
44
//~^ ERROR meta-variable expressions are unstable
55
};
66
}
@@ -19,22 +19,22 @@ macro_rules! dollar_dollar {
1919

2020
macro_rules! index {
2121
( $( $e:stmt ),* ) => {
22-
$( ${ignore(e)} ${index()} )*
22+
$( ${ignore($e)} ${index()} )*
2323
//~^ ERROR meta-variable expressions are unstable
2424
//~| ERROR meta-variable expressions are unstable
2525
};
2626
}
2727

2828
macro_rules! ignore {
2929
( $( $i:stmt ),* ) => {{
30-
0 $( + 1 ${ignore(i)} )*
30+
0 $( + 1 ${ignore($i)} )*
3131
//~^ ERROR meta-variable expressions are unstable
3232
}};
3333
}
3434

3535
macro_rules! length {
3636
( $( $e:stmt ),* ) => {
37-
$( ${ignore(e)} ${length()} )*
37+
$( ${ignore($e)} ${length()} )*
3838
//~^ ERROR meta-variable expressions are unstable
3939
//~| ERROR meta-variable expressions are unstable
4040
};

‎tests/ui/macros/rfc-3086-metavar-expr/required-feature.stderr

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0658]: meta-variable expressions are unstable
22
--> $DIR/required-feature.rs:3:10
33
|
4-
LL | ${ count(e) }
5-
| ^^^^^^^^^^^^
4+
LL | ${ count($e) }
5+
| ^^^^^^^^^^^^^
66
|
77
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
88
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
@@ -46,44 +46,44 @@ LL | ( $$( $$any:tt )* ) => { $$( $$any )* };
4646
error[E0658]: meta-variable expressions are unstable
4747
--> $DIR/required-feature.rs:22:13
4848
|
49-
LL | $( ${ignore(e)} ${index()} )*
50-
| ^^^^^^^^^^^
49+
LL | $( ${ignore($e)} ${index()} )*
50+
| ^^^^^^^^^^^^
5151
|
5252
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
5353
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
5454

5555
error[E0658]: meta-variable expressions are unstable
56-
--> $DIR/required-feature.rs:22:26
56+
--> $DIR/required-feature.rs:22:27
5757
|
58-
LL | $( ${ignore(e)} ${index()} )*
59-
| ^^^^^^^^^
58+
LL | $( ${ignore($e)} ${index()} )*
59+
| ^^^^^^^^^
6060
|
6161
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
6262
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
6363

6464
error[E0658]: meta-variable expressions are unstable
6565
--> $DIR/required-feature.rs:30:19
6666
|
67-
LL | 0 $( + 1 ${ignore(i)} )*
68-
| ^^^^^^^^^^^
67+
LL | 0 $( + 1 ${ignore($i)} )*
68+
| ^^^^^^^^^^^^
6969
|
7070
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
7171
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
7272

7373
error[E0658]: meta-variable expressions are unstable
7474
--> $DIR/required-feature.rs:37:13
7575
|
76-
LL | $( ${ignore(e)} ${length()} )*
77-
| ^^^^^^^^^^^
76+
LL | $( ${ignore($e)} ${length()} )*
77+
| ^^^^^^^^^^^^
7878
|
7979
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
8080
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable
8181

8282
error[E0658]: meta-variable expressions are unstable
83-
--> $DIR/required-feature.rs:37:26
83+
--> $DIR/required-feature.rs:37:27
8484
|
85-
LL | $( ${ignore(e)} ${length()} )*
86-
| ^^^^^^^^^^
85+
LL | $( ${ignore($e)} ${length()} )*
86+
| ^^^^^^^^^^
8787
|
8888
= note: see issue #83527 <https://github.com/rust-lang/rust/issues/83527> for more information
8989
= help: add `#![feature(macro_metavar_expr)]` to the crate attributes to enable

‎tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,17 @@
55
// `round` = Left hand side round brackets
66

77
macro_rules! curly__no_rhs_dollar__round {
8-
( $( $i:ident ),* ) => { ${ count(i) } };
8+
( $( $i:ident ),* ) => { ${ count($i) } };
99
}
1010

1111
macro_rules! curly__no_rhs_dollar__no_round {
12-
( $i:ident ) => { ${ count(i) } };
12+
( $i:ident ) => { ${ count($i) } };
1313
//~^ ERROR `count` can not be placed inside the inner-most repetition
1414
}
1515

16-
macro_rules! curly__rhs_dollar__round {
17-
( $( $i:ident ),* ) => { ${ count($i) } };
18-
//~^ ERROR expected identifier, found `$`
19-
//~| ERROR expected expression, found `$`
20-
}
21-
2216
macro_rules! curly__rhs_dollar__no_round {
2317
( $i:ident ) => { ${ count($i) } };
24-
//~^ ERROR expected identifier, found `$`
25-
//~| ERROR expected expression, found `$`
18+
//~^ ERROR `count` can not be placed inside the inner-most repetition
2619
}
2720

2821
macro_rules! no_curly__no_rhs_dollar__round {
@@ -60,16 +53,16 @@ macro_rules! extra_garbage_after_metavar {
6053
${count() a b c}
6154
//~^ ERROR unexpected token: a
6255
//~| ERROR expected expression, found `$`
63-
${count(i a b c)}
56+
${count($i a b c)}
6457
//~^ ERROR unexpected token: a
65-
${count(i, 1 a b c)}
58+
${count($i, 1 a b c)}
6659
//~^ ERROR unexpected token: a
67-
${count(i) a b c}
60+
${count($i) a b c}
6861
//~^ ERROR unexpected token: a
6962

70-
${ignore(i) a b c}
63+
${ignore($i) a b c}
7164
//~^ ERROR unexpected token: a
72-
${ignore(i a b c)}
65+
${ignore($i a b c)}
7366
//~^ ERROR unexpected token: a
7467

7568
${index() a b c}
@@ -100,8 +93,8 @@ macro_rules! metavar_in_the_lhs {
10093

10194
macro_rules! metavar_token_without_ident {
10295
( $( $i:ident ),* ) => { ${ ignore() } };
103-
//~^ ERROR expected identifier
104-
//~| ERROR expected expression, found `$`
96+
//~^ ERROR meta-variable expressions must be referenced using a dollar sign
97+
//~| ERROR expected expression
10598
}
10699

107100
macro_rules! metavar_with_literal_suffix {
@@ -125,14 +118,16 @@ macro_rules! open_brackets_without_tokens {
125118
macro_rules! unknown_count_ident {
126119
( $( $i:ident )* ) => {
127120
${count(foo)}
128-
//~^ ERROR variable `foo` is not recognized in meta-variable expression
121+
//~^ ERROR meta-variable expressions must be referenced using a dollar sign
122+
//~| ERROR expected expression
129123
};
130124
}
131125

132126
macro_rules! unknown_ignore_ident {
133127
( $( $i:ident )* ) => {
134128
${ignore(bar)}
135-
//~^ ERROR variable `bar` is not recognized in meta-variable expression
129+
//~^ ERROR meta-variable expressions must be referenced using a dollar sign
130+
//~| ERROR expected expression
136131
};
137132
}
138133

@@ -145,7 +140,6 @@ macro_rules! unknown_metavar {
145140
fn main() {
146141
curly__no_rhs_dollar__round!(a, b, c);
147142
curly__no_rhs_dollar__no_round!(a);
148-
curly__rhs_dollar__round!(a, b, c);
149143
curly__rhs_dollar__no_round!(a);
150144
no_curly__no_rhs_dollar__round!(a, b, c);
151145
no_curly__no_rhs_dollar__no_round!(a);

‎tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr

Lines changed: 100 additions & 106 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.