-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Sema] Support additional args in @dynamicMemberLookup subscripts #81148
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?
[Sema] Support additional args in @dynamicMemberLookup subscripts #81148
Conversation
Adds support for satisfying `@dynamicMemberLookup` requirements using subscripts which have arguments following `dynamicMember:` so long as they are either variadic or have default arguments. This allows transforming member references into `x[dynamicMember:...]` calls which can pass in arguments such as `#function`, `#fileID`, `#line`, etc.
/// a default value | ||
/// | ||
/// Subscripts which don't meet these requirements strictly are not eligible. | ||
enum class DynamicMemberLookupSubscriptEligibility : uint8_t { |
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.
DynamicMemberLookupSubscriptEligibility
is... a mouthful — but it's the least-inaccurate name I could come up with. Happy to improve this with suggestions!
DynamicMemberLookupSubscriptEligibility | ||
getDynamicMemberLookupSubscriptEligibility(); |
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.
Instead of exposing this enum, I suppose it is also possible to restore isValidDynamicMemberLookupSubscript()
et. al., but I do think it's nicer to have a type-safe interface that's harder to typo.
// If bindings were substituted, we need to find the "original" (or | ||
// contextless) parameter index for the default argument. | ||
if (shouldSubstituteParameterBindings(subscript)) { | ||
auto *paramList = SD->getParameterList(); | ||
assert(paramList); | ||
paramIdx = paramList->getOrigParamIndex( | ||
subscript.getSubstitutions(), paramIdx); | ||
} | ||
|
||
auto owner = getDefaultArgOwner(subscript, paramIdx); | ||
auto paramTy = params[paramIdx].getParameterType(); | ||
argExpr = new (ctx) | ||
DefaultArgumentExpr(owner, paramIdx, componentLoc, paramTy, dc); |
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.
This is pretty much what happens in coerceCallArguments
, but trying to DRY this out didn't end up feeling worth it.
// to validate the conformance of the `dynamicMember:` argument to | ||
// `ExpressibleByStringLiteral`. | ||
static DynamicMemberLookupSubscriptEligibility | ||
evaluateDynamicMemberLookupEligibility(const SubscriptDecl *SD, |
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.
This is the core of what was previously isValidKeyPathDynamicMemberLookup
and isValidStringDynamicMemberLookup
, factored out
@swift-ci please smoke test |
Adds support for satisfying
@dynamicMemberLookup
requirements using subscripts which have arguments followingdynamicMember:
so long as they are either variadic or have default arguments. This allows transforming member references intox[dynamicMember:...]
calls which can pass in arguments such as#function
,#fileID
,#line
, etc.@dynamicMemberLookup
Subscripts swift-evolution#2814Main changes:
SubscriptDecl
s to satisfy@dynamicMemberLookup
requirements as long asdynamicMember:
remains the first explicitly-labeled argument, and all following arguments are eitherisDefaultArgument()
orisVariadic()
SubscriptDecl.Bits
; this was being checked multiple times per decl and it seems prudent to just store the info since we have the bitsExprRewriter
to produceArgumentList
s for these subscripts by filling inDefaultArgumentExpr
s as neededChanges needed: