https://gcc.gnu.org/g:2d06661660f19fc9a17e9f9e01271e0b4f6eee97
commit r17-4336-g2d06661660f19fc9a17e9f9e01271e0b4f6eee97 Author: Philip Herron <[email protected]> Date: Sun Sep 6 21:04:46 2026 +0100 gccrs: Fix handling of constants in paths 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 <[email protected]> Diff: --- gcc/rust/backend/rust-compile-pattern.cc | 13 ++++++++++-- gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 8 ++++++- gcc/testsuite/rust/compile/issue-4851.rs | 26 +++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index 82cabef784b0..309d8f1953ee 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 83104833dbea..b5f336b42a65 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 000000000000..c76a4cb66524 --- /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, + } +}
