[COMMITTED 59/83] gccrs: Fix handling of constants in paths

arthur.cohen@opensrcsec.com arthur.cohen@opensrcsec.com
Wed Sep 16 12:30:18 GMT 2026


From: Philip Herron <herron.philip@googlemail.com>

Fixes Rust-GCC/gccrs#4851

gcc/rust/ChangeLog:

	* backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit): handle non ADT
	* typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit): likewise

gcc/testsuite/ChangeLog:

	* rust/compile/issue-4851.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
---
 gcc/rust/backend/rust-compile-pattern.cc      | 13 ++++++++--
 .../typecheck/rust-hir-type-check-pattern.cc  |  8 +++++-
 gcc/testsuite/rust/compile/issue-4851.rs      | 26 +++++++++++++++++++
 3 files changed, 44 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4851.rs

diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 82cabef784b..309d8f1953e 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -47,8 +47,17 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
 				      &lookup);
   rust_assert (ok);
 
-  // must be an ADT (?)
-  rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT);
+  if (lookup->get_kind () != TyTy::TypeKind::ADT)
+    {
+      tree constant_expr = ResolvePathRef::Compile (pattern, ctx);
+
+      check_expr
+	= Backend::comparison_expression (ComparisonOperator::EQUAL,
+					  match_scrutinee_expr, constant_expr,
+					  pattern.get_locus ());
+      return;
+    }
+
   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
 
   // if this isn't an enum, always succeed
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 83104833dbe..b5f336b42a6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -111,8 +111,14 @@ TypeCheckPattern::visit (HIR::PathInExpression &pattern)
 	}
     }
 
+  if (path_is_const_item)
+    {
+      infered = pattern_ty;
+      return;
+    }
+
   // If the path is a constructor, it must be a unit struct or unit variants.
-  if (!path_is_const_item && pattern_ty->get_kind () == TyTy::TypeKind::ADT)
+  if (pattern_ty->get_kind () == TyTy::TypeKind::ADT)
     {
       TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (pattern_ty);
       rust_assert (adt->get_variants ().size () > 0);
diff --git a/gcc/testsuite/rust/compile/issue-4851.rs b/gcc/testsuite/rust/compile/issue-4851.rs
new file mode 100644
index 00000000000..c76a4cb6652
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4851.rs
@@ -0,0 +1,26 @@
+#![feature(lang_items, no_core)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+enum FpCategory {
+    Zero,
+    Subnormal,
+    Infinite,
+    Nan,
+    Normal,
+}
+
+pub fn classify(bits: u32) -> FpCategory {
+    const EXP_MASK: u32 = 0x7f800000;
+    const MAN_MASK: u32 = 0x007fffff;
+
+    match (bits & MAN_MASK, bits & EXP_MASK) {
+        (0, 0) => FpCategory::Zero,
+        (_, 0) => FpCategory::Subnormal,
+        (0, EXP_MASK) => FpCategory::Infinite,
+        (_, EXP_MASK) => FpCategory::Nan,
+        _ => FpCategory::Normal,
+    }
+}
-- 
2.50.1



More information about the Gcc-rust mailing list