Skip to content

Conversation

@Pasta-coder
Copy link
Contributor

@Pasta-coder Pasta-coder commented Jan 6, 2026

The compiler previously treated literal patterns (like 0, 'a', or true) as
wildcards, causing the exhaustiveness checker to incorrectly accept incomplete
match blocks.

This patch modifies lower_pattern to lower literals into integer ranges
using std::strtoll (for -fno-exceptions compatibility). It updates
split_constructors to handle finite boolean universes and defaults other
scalars to wildcards.

Additionally, WitnessMatrix::apply_constructor and WitnessPat::to_string
are updated to handle INT_RANGE constructors, preventing Internal Compiler
Errors (ICEs). Existing tests were updated to include wildcard arms to
satisfy the correct exhaustiveness checks.

Fixes #4296

gcc/rust/ChangeLog:

* checks/errors/rust-hir-pattern-analysis.h (Constructor::make_int_range):
Add helper to create integer range constructors.
* checks/errors/rust-hir-pattern-analysis.cc (lower_pattern): Lower
literals (int, bool, char) to integer ranges.
(split_constructors): Handle integer, bool, and char types correctly.
(WitnessPat::to_string): Handle INT_RANGE to prevent ICE.
(WitnessMatrix::apply_constructor): Handle INT_RANGE to prevent ICE.

gcc/testsuite/ChangeLog:

* rust/compile/issue-4296.rs: New test.
* rust/compile/issue-3929-2.rs: Add wildcard arm to match block.
* rust/execute/torture/struct-pattern-match.rs: Add wildcard arm.

@Pasta-coder Pasta-coder force-pushed the fix/non-exhaustive-match-4296 branch 7 times, most recently from 7305cc3 to 38e3261 Compare January 8, 2026 10:16
@Pasta-coder
Copy link
Contributor Author

replaced the wildcard stub in lower_pattern with actual literal lowering using std::strtoll. I then updated split_constructors to handle primitive types correctly—defining Booleans as a finite set {true, false} and Integers as requiring a wildcard. Finally, I patched the Witness functions to handle INT_RANGE constructors to prevent ICEs and updated existing tests that were relying on the previous buggy behavior.

@Pasta-coder
Copy link
Contributor Author

Sequence of Changes:

Lowering (lower_pattern):

  • Replaced the wildcard stub with actual literal parsing.
  • Used std::strtoll for integer parsing to satisfy -fno-exceptions.
  • Lowered all literals (Int, Bool, Char) into Constructor::INT_RANGE.

Analysis Logic (split_constructors):

  • Booleans: Defined universe as finite set {false, true}.
  • Integers/Chars: Defined universe as wildcard (_) to force exhaustiveness.
  • Safety: Removed aggressive assertions to prevent crashes on non-ADT types (Tuples, Refs).

Crash Prevention (Witness Functions):

  • Updated WitnessMatrix::apply_constructor and WitnessPat::to_string to explicitly handle INT_RANGE constructors instead of hitting rust_unreachable() and crashing.

Verification (Tests):

  • Added issue-4296.rs to verify the fix.
  • Updated issue-3929-2.rs and struct-pattern-match.rs by adding wildcard arms, as they were previously passing only due to the bug.

@Pasta-coder Pasta-coder force-pushed the fix/non-exhaustive-match-4296 branch 2 times, most recently from 33b96fc to 26ba7b7 Compare January 14, 2026 08:10
The compiler previously treated literal patterns (like 0, 'a', or true) as
wildcards, causing the exhaustiveness checker to incorrectly accept incomplete
match blocks.

This patch modifies lower_pattern to lower literals into integer ranges
using std::strtoll (for -fno-exceptions compatibility). It updates
split_constructors to handle finite boolean universes and defaults other
scalars to wildcards.

Additionally, WitnessMatrix::apply_constructor and WitnessPat::to_string
are updated to handle INT_RANGE constructors, preventing Internal Compiler
Errors (ICEs). Existing tests were updated to include wildcard arms to
satisfy the correct exhaustiveness checks.

Fixes Rust-GCC#4296

gcc/rust/ChangeLog:

	* checks/errors/rust-hir-pattern-analysis.h (Constructor::make_int_range):
	Add helper to create integer range constructors.
	* checks/errors/rust-hir-pattern-analysis.cc (lower_pattern): Lower
	literals (int, bool, char) to integer ranges.
	(split_constructors): Handle integer, bool, and char types correctly.
	(WitnessPat::to_string): Handle INT_RANGE to prevent ICE.
	(WitnessMatrix::apply_constructor): Handle INT_RANGE to prevent ICE.

gcc/testsuite/ChangeLog:

	* rust/compile/issue-4296.rs: New test.
	* rust/compile/issue-3929-2.rs: Add wildcard arm to match block.
	* rust/execute/torture/struct-pattern-match.rs: Add wildcard arm.

Signed-off-by: Jayant Chauhan <[email protected]>
@Pasta-coder Pasta-coder force-pushed the fix/non-exhaustive-match-4296 branch from 26ba7b7 to b92bca2 Compare January 14, 2026 09:46
@Pasta-coder
Copy link
Contributor Author

final updates

Regression Fix (Integer Parsing):

  • The addition of the parse_check_literal static helper correctly handles Rust-specific syntax that strtoll missed.
  • Underscores: 1_000 is now correctly sanitized to 1000.
  • Suffixes: 10u8 is correctly truncated to 10 before parsing.
  • Bases: 0x, 0b, 0o prefixes are correctly detected and handled.

Safety Fix (Unicode/Hex Chars):

The explicit check for \u and \x in the CHAR case prevents the unsafe cast behavior. Returning a Wildcard here is a safe fallback that prevents ICEs (Internal Compiler Errors) while acknowledging (via the FIXME) that full Unicode support is a future task.

Logic Logic:

The split_constructors update correctly distinguishes BOOL (finite) from other types (wildcard required), ensuring standard match blocks behave as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

non-exhaustive pattern matching should give an error

1 participant