diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-04-08 14:41:16 +0200 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2025-04-14 08:03:49 +0000 |
commit | 780ebba8a9152598e0fde0528c2fc63d9f474fcd (patch) | |
tree | bf59145420917214e7efc7a30ef6bd9e11e56f60 /gcc | |
parent | 688b8d8b0e24aa7e2a7f741355d696f60337f956 (diff) | |
download | gcc-780ebba8a9152598e0fde0528c2fc63d9f474fcd.zip gcc-780ebba8a9152598e0fde0528c2fc63d9f474fcd.tar.gz gcc-780ebba8a9152598e0fde0528c2fc63d9f474fcd.tar.bz2 |
expansion: Only add fragments if the matcher succeeded
gcc/rust/ChangeLog:
* expand/rust-macro-expand.cc (MacroExpander::match_n_matches): Do not
insert fragments and substack fragments if the matcher failed.
gcc/testsuite/ChangeLog:
* rust/compile/macros/mbe/macro-issue3708.rs: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 15 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs | 80 |
2 files changed, 88 insertions, 7 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 7829757..c22db1c 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -621,9 +621,10 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser, // matched fragment get the offset in the token stream size_t offs_end = source.get_offs (); - sub_stack.insert_metavar ( - MatchedFragment (fragment->get_ident ().as_string (), - offs_begin, offs_end)); + if (valid_current_match) + sub_stack.insert_metavar ( + MatchedFragment (fragment->get_ident ().as_string (), + offs_begin, offs_end)); } break; @@ -650,15 +651,15 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser, } auto old_stack = sub_stack.pop (); - // nest metavars into repetitions - for (auto &ent : old_stack) - sub_stack.append_fragment (ent.first, std::move (ent.second)); - // If we've encountered an error once, stop trying to match more // repetitions if (!valid_current_match) break; + // nest metavars into repetitions + for (auto &ent : old_stack) + sub_stack.append_fragment (ent.first, std::move (ent.second)); + match_amount++; // Break early if we notice there's too many expressions already diff --git a/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs new file mode 100644 index 0000000..e5b38bb --- /dev/null +++ b/gcc/testsuite/rust/compile/macros/mbe/macro-issue3708.rs @@ -0,0 +1,80 @@ +// { dg-additional-options "-frust-name-resolution-2.0 -frust-compile-until=lowering" } + +macro_rules! impl_fn_for_zst { + ($( + $( #[$attr: meta] )* + struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn = + |$( $arg: ident: $ArgTy: ty ),*| -> $ReturnTy: ty + $body: block; + )+) => { + $( + $( #[$attr] )* + struct $Name; + + impl $( <$( $lifetime ),+> )? Fn<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call(&self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + $body + } + } + + impl $( <$( $lifetime ),+> )? FnMut<($( $ArgTy, )*)> for $Name { + #[inline] + extern "rust-call" fn call_mut( + &mut self, + ($( $arg, )*): ($( $ArgTy, )*) + ) -> $ReturnTy { + Fn::call(&*self, ($( $arg, )*)) + } + } + + impl $( <$( $lifetime ),+> )? FnOnce<($( $ArgTy, )*)> for $Name { + type Output = $ReturnTy; + + #[inline] + extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $ReturnTy { + Fn::call(&self, ($( $arg, )*)) + } + } + )+ + } +} + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +#[lang = "fn"] +pub trait Fn<Args>: FnMut<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call(&self, args: Args) -> Self::Output; +} + +#[lang = "fn_mut"] +#[must_use = "closures are lazy and do nothing unless called"] +pub trait FnMut<Args>: FnOnce<Args> { + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; +} + +#[lang = "fn_once"] +pub trait FnOnce<Args> { + /// The returned type after the call operator is used. + #[lang = "fn_once_output"] + #[stable(feature = "fn_once_output", since = "1.12.0")] + type Output; + + /// Performs the call operation. + #[unstable(feature = "fn_traits", issue = "29625")] + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +impl_fn_for_zst! { + #[derive(Copy)] + struct LinesAnyMap impl<'a> Fn = |line: &'a str| -> () { + }; +} |