Repository navigation
Emitter: refuse an unresolved variant pattern that would render as a bare (catch-all) identifier - #12755
Merged
Conversation
…refuses instead of binding as a catch-all Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…2-pattern-refuse # Conflicts: # src/v1/stage0/src/compiler_tests.rs # src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs
Contributor
Author
|
On the non-blocking point raised in review 73104 and review 73114 ( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #12733, as the parent lane asked: turn the emitter's widening fallback into a refusal.
Defect (DESIGN §5, a failure arm that widens).
v1.compiler.emit_rustrust_variant_path_optanswered an unresolved parent enum with the bare variant name. In Rust, a bare identifier in pattern position that names nothing in scope is a fresh binding. SoAdd => …withoutBinOp::*in scope matches every value, and rustc only warns about it.Change
refuse_unresolved_bare_variant_patternnow wraps the three pattern producers:emit_variant_pattern,emit_variant_pattern_rc_awareandvariant_pattern_shape_for.{,(or::), the emitter writescompile_error!at the arm, naming the variant and the scrutinee.Some/Nonelowering.Census: the first cut was too broad, and that measurement is why the rule is keyed on the render. Refusing every unresolved parent broke both emitted crates.
v2.std.nodeEdgeLabelNamed { name: _ }, matched over unstamped scrutinees inv2.std.compilers.body_loweringandv2.compiler.emit_produced.Namedis also declared bystd.algebraandextdeps.formats.spice, so its parent never resolves.Named { .. }, a struct pattern that Rust resolves by path and never binds.With the narrowed rule, measured locally:
gunbc test //gunbc/instruments:v2-native-cli:exit_status=0 warning_count=0.gunbc test //gunbc/instruments:self-host:exit_status=0 warning_count=0.Discriminating red. The generated
--libtestunresolved_variant_pattern_refuses_instead_of_binding_bare(v1.compiler.compiler_tests_rustct_unresolved_variant_pattern_refuses_test):BinOp::Add, optionalAbsentrendersstd::option::Option::None, and a fieldedNamedstill rendersNamed { .. }.variant_pattern_parent_unresolvedforced tofalsein the mirror it fails on the unresolved assertion, so it is a real red.No accepted source program can produce this state: the typechecker refuses a variant name that is declared twice in one closure. So the red is authored at the unit boundary.
RFM:
gunbc.recurring_failure_modeunresolved_variant_pattern_renders_as_a_catch_all_binding.rust_unit_testsstep, which is still off the merge path (rust_unit_tests_off_the_merge_path).MatchPatternVariantPatterncarries a resolved parent identity.Follow-up, not in this PR: unstamped scrutinees with an ambiguous variant name. The census found
v2.std.nodeEdgeLabelNamedarms whose parent enum never resolves.Namedis declared in three modules (v2.std.node,std.algebra,extdeps.formats.spice), sounique_variant_parentanswers none.v2.std.compilers.body_loweringandv2.compiler.emit_producedcarries no type stamp, so the emitter can't pick the parent from it.Named { .. }resolves through the authored import. The emitter never establishes whichNamedit means.VariantPattern.parent_enum(or the scrutinee type) for every arm. When that lands, these arms render asEdgeLabel::Named { .. }and the unresolved-parent population for this site goes to zero.Regen: run locally (ulimit -v 24G,
-j4, private target dir) untilrebuild_packages=0. Only the installed mirrors are committed.🤖 Generated with Claude Code