Skip to content

Conversation

hborla
Copy link
Member

@hborla hborla commented Oct 11, 2020

Implementation of SE-0293: Extend property wrappers to function and closure parameters.

Approach:

  • Functions with property wrapper parameters use the backing property type in the function signature everywhere except the constraint system. When a function is resolved and its type is opened, the property wrapper type is "unwrapped" and replaced with the wrapped-value type or the projected-value type, depending on the argument label.
  • When the property wrapper type is replaced, the property wrapper is "applied" by generating the appropriate constraints between the backing wrapper type and the wrapped or projected value type. The wrapper type and init kind (between wrapped-value and projected-value) are recorded in the constraint system.
  • CSApply will wrap functions with wrapper parameters in an autoclosure that accepts the wrapped-value or projected-value type, which initializes the property wrapper and calls the underlying function. Other arguments that don't have property wrappers are simply forwarded.
    • Note: a lot of the code that builds the "forwarding" parameter list is duplicated in buildCurryThunk. I intend to clean this up.
    • If the function is immediately applied, no autoclosure is necessary and instead the property wrapper initialization expression is injected around the appropriate argument in coerceCallArguments.
    • Instead of injecting the initializer expression directly in CSApply, an AppliedPropertyWrapperExpr is used. When SILGen sees this expression, it will emit an application of the appropriate property wrapper generator function.
  • When a function is emitted in SILGen, property-wrapped parameters are replaced with the backing property wrapper (which is synthesized as a ParamDecl). The local computed properties are emitted the same way as local property wrappers - by visiting the "auxiliary decls" during SILGen.
  • When visiting parameter decls, SILGen will also emit both property wrapper generator functions if the parameter has them. If the enclosing function is public, property wrapper generator functions are serialized and given public non-ABI linkage.

A few things that are still a WIP:

  • Unapplied references to functions with effects (e.g. throws, async)
  • Diagnostics for invalid wrapper attributes in overrides and protocol witnesses
  • "Implementation detail" property wrappers from the latest revision
  • Closure parameter type inference
  • Testing!

Not implemented in this PR:

  • Nonmutating setter synthesis for inferred property wrappers (e.g. $ closure parameters with no attribute)
  • Property wrapper parameters in subscript declarations

Resolves: rdar://66866426, rdar://71902161

@hborla hborla force-pushed the property-wrapper-parameters branch 2 times, most recently from 4b1430f to dbd53bf Compare October 11, 2020 23:59
@hborla
Copy link
Member Author

hborla commented Oct 12, 2020

@swift-ci please build toolchain

@hborla hborla added the swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review label Oct 12, 2020
@hborla
Copy link
Member Author

hborla commented Oct 12, 2020

@swift-ci please build toolchain macOS platform

@hborla
Copy link
Member Author

hborla commented Oct 12, 2020

@swift-ci please build toolchain

@swift-ci

This comment has been minimized.

@swiftlang swiftlang deleted a comment from swift-ci Oct 13, 2020
@swiftlang swiftlang deleted a comment from swift-ci Oct 13, 2020
@swift-ci

This comment has been minimized.

@hborla hborla force-pushed the property-wrapper-parameters branch 2 times, most recently from db5aeaf to ede2ea8 Compare November 8, 2020 19:31
@hborla
Copy link
Member Author

hborla commented Nov 9, 2020

@swift-ci please build toolchain

@swift-ci

This comment has been minimized.

@swift-ci

This comment has been minimized.

@hborla
Copy link
Member Author

hborla commented Dec 3, 2020

@swift-ci please build toolchain

@swift-ci

This comment has been minimized.

@swift-ci

This comment has been minimized.

@hborla hborla force-pushed the property-wrapper-parameters branch from 101fcbc to 10bcee5 Compare January 12, 2021 04:08
@hborla hborla force-pushed the property-wrapper-parameters branch 6 times, most recently from 83fe02f to 4941843 Compare January 27, 2021 05:09
@hborla
Copy link
Member Author

hborla commented Jan 27, 2021

@swift-ci please build toolchain

3 similar comments
@hborla
Copy link
Member Author

hborla commented Jan 27, 2021

@swift-ci please build toolchain

@hborla
Copy link
Member Author

hborla commented Jan 28, 2021

@swift-ci please build toolchain

@hborla
Copy link
Member Author

hborla commented Jan 29, 2021

@swift-ci please build toolchain

@hborla
Copy link
Member Author

hborla commented Jan 29, 2021

@swift-ci please smoke test

where the programmer tries to pass a projection argument to a wrapped
parameter without 'var projectedValue'.
closure is resolved. This can't be diagnosed earlier because a property
wrapper attribute may be inferred in the constraint system.
wrapper projection argument to a wrapped parameter with arguments in the
wrapper attribute.
property wrapper in the property wrapper requests.
position in CSGen. This effectively reverts 6caca26014.
…ressions

in PropertyWrapperBackingPropertyInfo.
dedicated initializer context for this expressions.
initialization expressions for parameters with attached property wrappers.
around arguments to property wrapper parameters.
generator functions for parameters of public functions.
… use

the correct substitution map when emitting the property wrapper generator
application in SILGen.
the parameter has an attached property wrapper.
@hborla hborla force-pushed the property-wrapper-parameters branch from 7f34a8b to b3d54b6 Compare February 26, 2021 02:35
@hborla
Copy link
Member Author

hborla commented Feb 26, 2021

@swift-ci please test

@hborla
Copy link
Member Author

hborla commented Feb 26, 2021

@swift-ci please test source compatibility

@hborla
Copy link
Member Author

hborla commented Feb 26, 2021

@swift-ci please smoke test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - b3d54b6

@hborla
Copy link
Member Author

hborla commented Feb 26, 2021

@swift-ci please smoke test macOS platform

1 similar comment
@hborla
Copy link
Member Author

hborla commented Feb 26, 2021

@swift-ci please smoke test macOS platform

@hborla hborla merged commit eedbb9d into swiftlang:main Feb 26, 2021
@hborla hborla deleted the property-wrapper-parameters branch February 27, 2021 04:49
auto *functionType = fullFunctionType->getResult()->getAs<FunctionType>();
functionType = unwrapPropertyWrapperParameterTypes(*this, funcDecl, functionRefKind,
functionType, locator);
openedType = FunctionType::get(fullFunctionType->getParams(), functionType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we're not doing any FunctionType::ExtInfo propagation/preservation here? In other words, are the default ExtInfo flags the goal or do they just happen to work?

And as a general observation that long predates your pull request, it's kind of frustrating that the FunctionType constructor let's one elide (and therefore default) the ExtInfo state. This wouldn't ordinarily be a problem for most constructors but Swift is constantly unpacking and rebuilding function types and I find that the ExtInfo preservation/management to be haphazard. I've been tempted to propose something but I don't know what people think/feel about ExtInfo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think you're right that dropping them just happens to work here. Thanks for catching - I'll fix this in a followup PR.

Agreed that the default ExtInfo() makes it too easy to accidentally drop existing ExtInfo when transforming a function type like this. I actually had to fix the same mistake in the body of unwrapPropertyWrapperParameterTypes as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying. A link to the followup PR would be appreciated. I just posted to the forum about making ExtInfo preservation/propagation more explicit:

https://forums.swift.org/t/rfc-make-extinfo-param-to-functiontype-construction-always-explicit/45182

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to close the loop, I merged #36234 (but GitHub thinks the merge failed, weird). Thanks for helping me better understand the intent here and now that #36234 is merged, hopefully intent will be a little more clear in the future. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants