Sema: Fix local property wrappers on constructor

Fixes rdar://problem/142443421.
This commit is contained in:
Slava Pestov
2025-01-07 13:41:04 -05:00
parent cc2048764a
commit c17044381e
5 changed files with 37 additions and 9 deletions

View File

@@ -5148,7 +5148,8 @@ public:
/// 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.

View File

@@ -4301,11 +4301,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());
auto recordPropertyWrapperFix = [&](ConstraintFix *fix) -> TypeMatchResult {
if (!shouldAttemptFixes())

View File

@@ -1850,7 +1850,9 @@ static ConstraintSystem::TypeMatchResult matchCallArguments(
assert(param);
if (cs.applyPropertyWrapperToParameter(paramTy, argTy,
const_cast<ParamDecl *>(param),
wrapperArgLabel, subKind, loc)
wrapperArgLabel, subKind,
cs.getConstraintLocator(loc),
calleeLocator)
.isFailure()) {
return cs.getTypeMatchFailure(loc);
}
@@ -11912,6 +11914,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;

View File

@@ -750,14 +750,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(),

View File

@@ -223,3 +223,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)
}