Skip to content

Commit

Permalink
Merge pull request swiftlang#78528 from slavapestov/fix-rdar141961300…
Browse files Browse the repository at this point in the history
…-6.1

Sema: Fix local property wrappers on constructor [6.1]
  • Loading branch information
slavapestov authored Jan 11, 2025
2 parents 5c6128f + 7e0e0ec commit f2da113
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
10 changes: 9 additions & 1 deletion include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -1613,6 +1613,13 @@ class Solution {
/// A map from argument expressions to their applied property wrapper expressions.
llvm::DenseMap<ASTNode, SmallVector<AppliedPropertyWrapper, 2>> appliedPropertyWrappers;

ArrayRef<AppliedPropertyWrapper> getAppliedPropertyWrappers(ASTNode anchor) {
auto found = appliedPropertyWrappers.find(anchor);
if (found != appliedPropertyWrappers.end())
return found->second;
return ArrayRef<AppliedPropertyWrapper>();
}

/// A mapping from the constraint locators for references to various
/// names (e.g., member references, normal name references, possible
/// constructions) to the argument lists for the call to that locator.
Expand Down Expand Up @@ -5214,7 +5221,8 @@ class ConstraintSystem {
/// property wrapper type by applying the property wrapper.
TypeMatchResult applyPropertyWrapperToParameter(
Type wrapperType, Type paramType, ParamDecl *param, Identifier argLabel,
ConstraintKind matchKind, ConstraintLocatorBuilder locator);
ConstraintKind matchKind, ConstraintLocator *locator,
ConstraintLocator *calleeLocator);

/// Used by applyPropertyWrapperToParameter() to update appliedPropertyWrappers
/// and record a change in the trail.
Expand Down
16 changes: 10 additions & 6 deletions lib/Sema/CSApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,8 +1189,8 @@ namespace {
calleeFnTy = calleeFnTy->getResult()->castTo<FunctionType>();
}

const auto &appliedPropertyWrappers =
solution.appliedPropertyWrappers[locator.getAnchor()];
auto appliedPropertyWrappers =
solution.getAppliedPropertyWrappers(locator.getAnchor());
const auto calleeDeclRef = resolveConcreteDeclRef(
dyn_cast<AbstractFunctionDecl>(declOrClosure), locator);

Expand Down Expand Up @@ -2334,8 +2334,8 @@ namespace {
->castTo<FunctionType>();
auto fullSubscriptTy = openedFullFnType->getResult()
->castTo<FunctionType>();
auto &appliedWrappers =
solution.appliedPropertyWrappers[memberLoc->getAnchor()];
auto appliedWrappers =
solution.getAppliedPropertyWrappers(memberLoc->getAnchor());
args = coerceCallArguments(
args, fullSubscriptTy, subscriptRef, nullptr,
locator.withPathElement(ConstraintLocator::ApplyArgument),
Expand Down Expand Up @@ -6338,6 +6338,7 @@ ArgumentList *ExprRewriter::coerceCallArguments(
auto *paramDecl = getParameterAt(callee, paramIdx);
assert(paramDecl);

ASSERT(appliedWrapperIndex < appliedPropertyWrappers.size());
auto appliedWrapper = appliedPropertyWrappers[appliedWrapperIndex++];
auto wrapperType = solution.simplifyType(appliedWrapper.wrapperType);
auto initKind = appliedWrapper.initKind;
Expand Down Expand Up @@ -8240,7 +8241,8 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
// Resolve into a DynamicTypeExpr.
auto args = apply->getArgs();

auto &appliedWrappers = solution.appliedPropertyWrappers[calleeLocator.getAnchor()];
auto appliedWrappers = solution.getAppliedPropertyWrappers(
calleeLocator.getAnchor());
auto fnType = cs.getType(fn)->getAs<FunctionType>();
args = coerceCallArguments(
args, fnType, declRef, apply,
Expand Down Expand Up @@ -8436,7 +8438,9 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
// For function application, convert the argument to the input type of
// the function.
if (auto fnType = cs.getType(fn)->getAs<FunctionType>()) {
auto &appliedWrappers = solution.appliedPropertyWrappers[calleeLocator.getAnchor()];
auto appliedWrappers = solution.getAppliedPropertyWrappers(
calleeLocator.getAnchor());

args = coerceCallArguments(
args, fnType, callee, apply,
locator.withPathElement(ConstraintLocator::ApplyArgument),
Expand Down
8 changes: 3 additions & 5 deletions lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5057,11 +5057,9 @@ void ConstraintSystem::removePropertyWrapper(Expr *anchor) {
ConstraintSystem::TypeMatchResult
ConstraintSystem::applyPropertyWrapperToParameter(
Type wrapperType, Type paramType, ParamDecl *param, Identifier argLabel,
ConstraintKind matchKind, ConstraintLocatorBuilder locator) {
Expr *anchor = getAsExpr(locator.getAnchor());
if (auto *apply = dyn_cast<ApplyExpr>(anchor)) {
anchor = apply->getFn();
}
ConstraintKind matchKind, ConstraintLocator *locator,
ConstraintLocator *calleeLocator) {
Expr *anchor = getAsExpr(calleeLocator->getAnchor());

if (argLabel.hasDollarPrefix() && (!param || !param->hasExternalPropertyWrapper())) {
if (!shouldAttemptFixes())
Expand Down
5 changes: 4 additions & 1 deletion lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1820,7 +1820,9 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
assert(param);
if (cs.applyPropertyWrapperToParameter(paramTy, argTy,
const_cast<ParamDecl *>(param),
argLabel, subKind, loc)
argLabel, subKind,
cs.getConstraintLocator(loc),
calleeLocator)
.isFailure()) {
return cs.getTypeMatchFailure(loc);
}
Expand Down Expand Up @@ -11920,6 +11922,7 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
auto result = applyPropertyWrapperToParameter(backingType, param.getParameterType(),
paramDecl, paramDecl->getName(),
ConstraintKind::Equal,
getConstraintLocator(closure),
getConstraintLocator(closure));
if (result.isFailure())
return false;
Expand Down
5 changes: 3 additions & 2 deletions lib/Sema/TypeOfReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,14 +741,15 @@ unwrapPropertyWrapperParameterTypes(ConstraintSystem &cs, AbstractFunctionDecl *
continue;
}

auto *wrappedType = cs.createTypeVariable(cs.getConstraintLocator(locator), 0);
auto *loc = cs.getConstraintLocator(locator);
auto *wrappedType = cs.createTypeVariable(loc, 0);
auto paramType = paramTypes[i].getParameterType();
auto paramLabel = paramTypes[i].getLabel();
auto paramInternalLabel = paramTypes[i].getInternalLabel();
adjustedParamTypes.push_back(AnyFunctionType::Param(
wrappedType, paramLabel, ParameterTypeFlags(), paramInternalLabel));
cs.applyPropertyWrapperToParameter(paramType, wrappedType, paramDecl, argLabel,
ConstraintKind::Equal, locator);
ConstraintKind::Equal, loc, loc);
}

return FunctionType::get(adjustedParamTypes, functionType->getResult(),
Expand Down
25 changes: 25 additions & 0 deletions test/Sema/property_wrapper_parameter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,28 @@ func takesWrapperClosure<T>(_: ProjectionWrapper<[S<T>]>, closure: (ProjectionWr
func testGenericPropertyWrapper<U>(@ProjectionWrapper wrappers: [S<U>]) {
takesWrapperClosure($wrappers) { $wrapper in }
}

@propertyWrapper
struct Binding<Value> {
var wrappedValue: Value

init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}

public var projectedValue: Binding<Value> {
return self
}

public init(projectedValue: Binding<Value>) {
self = projectedValue
}
}

struct Widget {
init(@ProjectionWrapper w: Int) {}
}

func buildWidget(_ w: ProjectionWrapper<Int>) -> Widget {
Widget($w: w)
}

0 comments on commit f2da113

Please sign in to comment.