Skip to content

[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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

itaiferber
Copy link
Contributor

@itaiferber itaiferber commented Apr 28, 2025

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.

Main changes:

  1. Allows SubscriptDecls to satisfy @dynamicMemberLookup requirements as long as dynamicMember: remains the first explicitly-labeled argument, and all following arguments are either isDefaultArgument() or isVariadic()
  2. Caches the result of checking for eligibility in SubscriptDecl.Bits; this was being checked multiple times per decl and it seems prudent to just store the info since we have the bits
  3. Updates ExprRewriter to produce ArgumentLists for these subscripts by filling in DefaultArgumentExprs as needed
  4. Adds unit tests

Changes needed:

  • Parameter packs are not currently handled properly
  • Isolated parameters are not currently handled properly

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 {
Copy link
Contributor Author

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!

Comment on lines +7578 to +7579
DynamicMemberLookupSubscriptEligibility
getDynamicMemberLookupSubscriptEligibility();
Copy link
Contributor Author

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.

Comment on lines +3667 to +3679
// 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);
Copy link
Contributor Author

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,
Copy link
Contributor Author

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

@itaiferber
Copy link
Contributor Author

@swift-ci please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant