Skip to content

Commit 0e07fc5

Browse files
authored
Merge pull request #1456 from RalfJung/const-pattern
update patterns.md for const pattern RFC
2 parents 1bf2cdc + 2f63507 commit 0e07fc5

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

src/patterns.md

+23-12
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,6 @@ Since negative numbers are not [literals], literal patterns also accept an optio
144144

145145
<div class="warning">
146146

147-
Floating-point literals are currently accepted, but due to the complexity of comparing them, they are going to be forbidden on literal patterns in a future version of Rust (see [issue #41620](https://github.com/rust-lang/rust/issues/41620)).
148-
149-
</div>
150-
151-
<div class="warning">
152-
153147
C string and raw C string literals are accepted in literal patterns, but `&CStr`
154148
doesn't implement structural equality (`#[derive(Eq, PartialEq)]`) and therefore
155149
any such `match` on a `&CStr` will be rejected with a type error.
@@ -455,6 +449,7 @@ If the bounds is written as a path, after macro resolution, the path must resolv
455449

456450
The type and value of the bounds is dependent upon how it is written out.
457451
If the bounds is a [path], the pattern has the type and value of the [constant] the path resolves to.
452+
For float range patterns, the constant may not be a `NaN`.
458453
If it is a literal, it has the type and value of the corresponding [literal expression].
459454
If is a literal preceded by a `-`, it has the same type as the corresponding [literal expression] and the value of [negating] the value of the corresponding literal expression.
460455

@@ -538,9 +533,6 @@ For example, `0u8..=255u8` is irrefutable.
538533
The range of values for an integer type is the closed range from its minimum to maximum value.
539534
The range of values for a `char` type are precisely those ranges containing all Unicode Scalar Values: `'\u{0000}'..='\u{D7FF}'` and `'\u{E000}'..='\u{10FFFF}'`.
540535

541-
Floating point range patterns are deprecated and may be removed in a future Rust release.
542-
See [issue #41620](https://github.com/rust-lang/rust/issues/41620) for more information.
543-
544536
> **Edition Differences**: Before the 2021 edition, range patterns with both a lower and upper bound may also be written using `...` in place of `..=`, with the same meaning.
545537
546538
## Reference patterns
@@ -791,12 +783,31 @@ Unqualified path patterns can refer to:
791783

792784
Qualified path patterns can only refer to associated constants.
793785

794-
Constants cannot be a union type.
795-
Struct and enum constants must have `#[derive(PartialEq, Eq)]` (not merely implemented).
796-
797786
Path patterns are irrefutable when they refer to structs or an enum variant when the enum has only one variant or a constant whose type is irrefutable.
798787
They are refutable when they refer to refutable constants or enum variants for enums with multiple variants.
799788

789+
### Constant patterns
790+
791+
When a constant `C` of type `T` is used as a pattern, we first check that `T: PartialEq`.
792+
Furthermore we require that the value of `C` *has (recursive) structural equality*, which is defined recursively as follows:
793+
794+
- Integers as well as `str`, `bool` and `char` values always have structural equality.
795+
- Tuples, arrays, and slices have structural equality if all their fields/elements have structural equality.
796+
(In particular, `()` and `[]` always have structural equality.)
797+
- References have structural equality if the value they point to has structural equality.
798+
- A value of `struct` or `enum` type has structural equality if its `PartialEq` instance is derived via `#[derive(PartialEq)]`,
799+
and all fields (for enums: of the active variant) have structural equality.
800+
- A raw pointer has structural equality if it was defined as a constant integer (and then cast/transmuted).
801+
- A float value has structural equality if it is not a `NaN`.
802+
- Nothing else has structural equality.
803+
804+
In particular, the value of `C` must be known at pattern-building time (which is pre-monomorphization).
805+
This means that associated consts that involve generic parameters cannot be used as patterns.
806+
807+
After ensuring all conditions are met, the constant value is translated into a pattern, and now behaves exactly as-if that pattern had been written directly.
808+
In particular, it fully participates in exhaustiveness checking.
809+
(For raw pointers, constants are the only way to write such patterns. Only `_` is ever considered exhaustive for these types.)
810+
800811
## Or-patterns
801812

802813
_Or-patterns_ are patterns that match on one of two or more sub-patterns (for example `A | B | C`).

0 commit comments

Comments
 (0)