Diagnostic and cause
LinkConstructor name used as a pattern binding
- Family
- topaz
- Phase
- check
- Code
TPZ5712
Cause and conditions
Write Name(patterns) in every pattern position. The payload list has the declared arity. A zero-payload constructor uses Name(), including None() and user enum variants such as Empty(). Nesting does not change this syntax. Parenthesized patterns with the wrong payload count retain the existing constructor-arity diagnostic.
Write Name(arguments) in every value position at every arity. Constructor calls use None(), Empty(), or Some(value). Qualified enum construction uses the same argument list, as in Choice.. The grammar rejects a bare prelude None value. User enum constructor names are resolved and checked after parsing.
A bare identifier in a pattern attempts to bind a new name. Its capitalization never selects a constructor role. A typed binding uses the same name rule.
The constructor namespace includes prelude constructors, visible declarations and imports, and variants obtained from the known expected type after resolving aliases. A pattern binder that has the same identifier as one of those constructors is rejected with TPZ5712. This check applies at every nested pattern, to typed binders, and to constructors of another visible type. A value binding does not hide a constructor for this check. Choose a fresh name to capture the value or use _ to ignore it.
None is already a reserved binding name. Without the constructor argument list it is rejected during parsing with TPZ2012. Other bare constructor names reach the namespace check. A removed bare enum pattern is never widened into a catch-all.
Response
Write the constructor argument list, including () at zero arity. To capture the matched value, choose a name absent from the constructor namespace.
Source evidence
- parseIdentifierPattern at
72a59a31125f· 537-585 - patternBindingTypeAt at
72a59a31125f· 1578-1648 - rejectReservedBinding at
72a59a31125f· 175-186 - bindConstructorPattern at
72a59a31125f· 1040-1248 - pull/45 at
72a59a31125f
Topaz 6.0.0 specifies this diagnostic during checking.
The target message is pattern binding Empty conflicts with a constructor.
The pinned SELF source does not emit this diagnostic.
Every constructor pattern uses an argument list. A bare identifier proposes a binding and cannot collide with a visible constructor. Typed bindings use the same rule. Value shadowing does not hide constructors. Report TPZ5712 at the binding name. Bare None retains its existing parse rejection. The constructor rule defines the constructor namespace and repair.
Constructor name used as a pattern binding
Every constructor pattern uses an argument list. A bare identifier proposes a binding and cannot collide with a visible constructor. Typed bindings use the same rule. Value shadowing does not hide constructors. Report TPZ5712 at the binding name. Bare None retains its existing parse rejection. The constructor rule defines the constructor namespace and repair.
Why
This applies the adopted constructor-parentheses.1 decision. The language chapter owns the rejection condition and source span.
Source evidence
- issues/31 at
151141d7bb44
Response
LinkWrite the constructor argument list, including () at zero arity. To capture the matched value, choose a name absent from the constructor namespace.
Reproduction and verification
LinkRejected program
Linkenum Choice { Empty, Filled(int) }function read(value: Choice) -> int {match (value) {case Empty => 0case Filled(number) => number}}
No stdout.
Expected result
Expected result
Rejection during check. Nonzero exit.
TPZ5712pattern-constructor-binding-collision atexample.tpz:4:14
The matcher describes a Topaz 6.0 target message. Public Topaz 5.21.3 does not implement this diagnostic producer.
Source evidence
- issues/31 at
151141d7bb44
Repaired program
Linkenum Choice { Empty, Filled(int), Pair(int, int) }function read(value: Choice) -> int {match (value) {case Empty() => 0case Filled(number) => numbercase Pair(left, right) => left + right}}function nested(value: Option<Choice>) -> int {match (value) {case None() => -1case Some(Empty()) => 0case Some(Filled(number)) => numbercase Some(Pair(left, right)) => left + right}}
Expected result
Expected result
Checking accepts the program. Exit code 0.
The matcher describes a Topaz 6.0 target message. Public Topaz 5.21.3 does not implement this diagnostic producer.
Source evidence
- issues/31 at
151141d7bb44