-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Sema: Support optional promotion of tuple patterns #63992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2888edc
236e88d
1b901a9
44b91a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2710,7 +2710,24 @@ namespace { | |
tupleTypeElts.push_back(TupleTypeElt(eltTy, tupleElt.getLabel())); | ||
} | ||
|
||
return setType(TupleType::get(tupleTypeElts, CS.getASTContext())); | ||
Type patternTy = TupleType::get(tupleTypeElts, CS.getASTContext()); | ||
|
||
// 1. Allow optional promotion only when the matching is conditional, | ||
// i.e., not in pattern binding declarations. | ||
// 2. A single-element tuple can only mean that we are matching the | ||
// payload of an enum case without splatting, in which case optional | ||
// promotion is irrelevant. | ||
if (!patternBinding && tupleTypeElts.size() > 1) { | ||
Type tyVar = CS.createTypeVariable(CS.getConstraintLocator(locator), | ||
TVO_CanBindToNoEscape); | ||
CS.addConstraint( | ||
ConstraintKind::EqualOrOptional, tyVar, patternTy, | ||
locator.withPathElement(LocatorPathElt::PatternMatch(pattern))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I understand this problem, what we really want is not to look through optionals but disregard the structure of the tuple pattern and let context impose it. So how about instead of this new constraint we actually model it this way:
This scheme should make it possible to infer tuple type from context and look through optionals in pattern matching context while resolving individual tuple elements. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the late reply here! I'm curious what the benefit of that approach would be, as wouldn't the new tuple member constraint need to handle the same optional unwrapping that the Or is the aim to have the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no new constraints and existing member already handles unwrapping of optional base type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see! Sorry, I totally missed that. I guess one worry with that approach is we don't want to allow e.g One other thing that we have to contend with is that we currently can use the tuple type of the pattern to introduce conversions, e.g this is currently allowed: if case (x: 0, y: 0) = (0, 0) {} Also just discovered that we currently allow duplicate labels in tuple patterns :( if case (x: 0, x: 0) = (0, 0) {} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t think it should be too hard to maintain the structural matching, we can even add additional information about index/label to member constraint to make sure that the base tuple does indeed match structurally. |
||
|
||
patternTy = tyVar; | ||
} | ||
|
||
return setType(patternTy); | ||
} | ||
|
||
case PatternKind::OptionalSome: { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't quite feel right to me to have
Equal
in the name since the constraint isn't doing rvalue conversions, it's just asserting that no lvalues are present. Additionally, I think if we did ever want to apply this constraint to something else that could have lvalues, I think it would probably make most sense to preserve lvalueness likeOptionalObject
, as lvalues are generally preserved through optional chains.How about something like
UnwrappingOptionals
? I think the plurality also helps make it clear it unwraps an arbitrary number of optionals.