diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index a214ca906bf..df258bd96ec 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -435,7 +435,7 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> &parser,
 
 bool
 MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
-			      AST::MacroMatcher &matcher)
+			      AST::MacroMatcher &matcher, bool in_repetition)
 {
   if (depth_exceeds_recursion_limit ())
     {
@@ -485,8 +485,12 @@ MacroExpander::match_matcher (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 (), offs_begin, offs_end));
+	    if (in_repetition)
+	      sub_stack.append_fragment (
+		MatchedFragment (fragment->get_ident (), offs_begin, offs_end));
+	    else
+	      sub_stack.insert_metavar (
+		MatchedFragment (fragment->get_ident (), offs_begin, offs_end));
 	  }
 	  break;
 
@@ -509,7 +513,7 @@ MacroExpander::match_matcher (Parser<MacroInvocLexer> &parser,
 	    AST::MacroMatcher *m
 	      = static_cast<AST::MacroMatcher *> (match.get ());
 	    expansion_depth++;
-	    if (!match_matcher (parser, *m))
+	    if (!match_matcher (parser, *m, in_repetition))
 	      {
 		expansion_depth--;
 		return false;
@@ -619,7 +623,7 @@ MacroExpander::match_n_matches (Parser<MacroInvocLexer> &parser,
 	      case AST::MacroMatch::MacroMatchType::Matcher: {
 		AST::MacroMatcher *m
 		  = static_cast<AST::MacroMatcher *> (match.get ());
-		valid_current_match = match_matcher (parser, *m);
+		valid_current_match = match_matcher (parser, *m, true);
 	      }
 	      break;
 	    }
diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 97a02692d1f..bef140236b3 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -273,7 +273,7 @@ struct MacroExpander
 			 AST::MacroMatchRepetition &rep);
 
   bool match_matcher (Parser<MacroInvocLexer> &parser,
-		      AST::MacroMatcher &matcher);
+		      AST::MacroMatcher &matcher, bool in_repetition = false);
 
   /**
    * Match any amount of matches
diff --git a/gcc/testsuite/rust/compile/macro43.rs b/gcc/testsuite/rust/compile/macro43.rs
new file mode 100644
index 00000000000..c7bf50a030e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro43.rs
@@ -0,0 +1,64 @@
+macro_rules! nonzero_integers {
+    ( $( $Ty: ident($Int: ty); )+ ) => {
+        $(
+            /// An integer that is known not to equal zero.
+            ///
+            /// This enables some memory layout optimization.
+            /// For example, `Option<NonZeroU32>` is the same size as `u32`:
+            ///
+            /// ```rust
+            /// use std::mem::size_of;
+            /// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
+            /// ```
+            #[stable(feature = "nonzero", since = "1.28.0")]
+            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+            #[repr(transparent)]
+            pub struct $Ty(NonZero<$Int>);
+
+            impl $Ty {
+                /// Create a non-zero without checking the value.
+                ///
+                /// # Safety
+                ///
+                /// The value must not be zero.
+                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[inline]
+                pub const unsafe fn new_unchecked(n: $Int) -> Self {
+                    $Ty(NonZero(n))
+                }
+
+                /// Create a non-zero if the given value is not zero.
+                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[inline]
+                pub fn new(n: $Int) -> Option<Self> {
+                    if n != 0 {
+                        Some($Ty(NonZero(n)))
+                    } else {
+                        None
+                    }
+                }
+
+                /// Returns the value as a primitive type.
+                #[stable(feature = "nonzero", since = "1.28.0")]
+                #[inline]
+                pub fn get(self) -> $Int {
+                    self.0 .0
+                }
+
+            }
+
+            impl_nonzero_fmt! { // { dg-error "unknown macro" }
+                (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+            }
+        )+
+    }
+}
+
+nonzero_integers! {
+    NonZeroU8(u8);
+    NonZeroU16(u16);
+    NonZeroU32(u32);
+    NonZeroU64(u64);
+    NonZeroU128(u128);
+    NonZeroUsize(usize);
+}
