@@ -2319,6 +2319,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
2319
2319
case ConstraintKind::ExplicitGenericArguments:
2320
2320
case ConstraintKind::SameShape:
2321
2321
case ConstraintKind::MaterializePackExpansion:
2322
+ case ConstraintKind::LValueObject:
2322
2323
llvm_unreachable("Bad constraint kind in matchTupleTypes()");
2323
2324
}
2324
2325
@@ -2679,6 +2680,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
2679
2680
case ConstraintKind::ExplicitGenericArguments:
2680
2681
case ConstraintKind::SameShape:
2681
2682
case ConstraintKind::MaterializePackExpansion:
2683
+ case ConstraintKind::LValueObject:
2682
2684
return true;
2683
2685
}
2684
2686
@@ -3324,6 +3326,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
3324
3326
case ConstraintKind::ExplicitGenericArguments:
3325
3327
case ConstraintKind::SameShape:
3326
3328
case ConstraintKind::MaterializePackExpansion:
3329
+ case ConstraintKind::LValueObject:
3327
3330
llvm_unreachable("Not a relational constraint");
3328
3331
}
3329
3332
@@ -7185,6 +7188,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
7185
7188
case ConstraintKind::ExplicitGenericArguments:
7186
7189
case ConstraintKind::SameShape:
7187
7190
case ConstraintKind::MaterializePackExpansion:
7191
+ case ConstraintKind::LValueObject:
7188
7192
llvm_unreachable("Not a relational constraint");
7189
7193
}
7190
7194
}
@@ -14158,6 +14162,80 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
14158
14162
return SolutionKind::Solved;
14159
14163
}
14160
14164
14165
+ ConstraintSystem::SolutionKind
14166
+ ConstraintSystem::simplifyLValueObjectConstraint(
14167
+ Type type1, Type type2, TypeMatchOptions flags,
14168
+ ConstraintLocatorBuilder locator) {
14169
+ auto lvalueTy = simplifyType(type1);
14170
+
14171
+ auto formUnsolved = [&]() {
14172
+ // If we're supposed to generate constraints, do so.
14173
+ if (flags.contains(TMF_GenerateConstraints)) {
14174
+ auto *lvalueObject =
14175
+ Constraint::create(*this, ConstraintKind::LValueObject,
14176
+ type1, type2, getConstraintLocator(locator));
14177
+
14178
+ addUnsolvedConstraint(lvalueObject);
14179
+ return SolutionKind::Solved;
14180
+ }
14181
+
14182
+ return SolutionKind::Unsolved;
14183
+ };
14184
+
14185
+ auto isOrCanBeLValueType = [](Type type) {
14186
+ if (auto *typeVar = type->getAs<TypeVariableType>()) {
14187
+ return typeVar->getImpl().canBindToLValue();
14188
+ }
14189
+ return type->is<LValueType>();
14190
+ };
14191
+
14192
+ if (lvalueTy->isPlaceholder()) {
14193
+ if (!shouldAttemptFixes())
14194
+ return SolutionKind::Error;
14195
+
14196
+ recordAnyTypeVarAsPotentialHole(type2);
14197
+ return SolutionKind::Solved;
14198
+ }
14199
+
14200
+ if (!isOrCanBeLValueType(lvalueTy)) {
14201
+ if (!shouldAttemptFixes())
14202
+ return SolutionKind::Error;
14203
+
14204
+ auto assessImpact = [&]() -> unsigned {
14205
+ // If this is a projection of a member reference
14206
+ // let's check whether the member is unconditionally
14207
+ // settable, if so than it's a problem with its base.
14208
+ if (locator.directlyAt<UnresolvedDotExpr>()) {
14209
+ auto *memberLoc = getConstraintLocator(locator.getAnchor(),
14210
+ ConstraintLocator::Member);
14211
+ if (auto selected = findSelectedOverloadFor(memberLoc)) {
14212
+ if (auto *storage = dyn_cast_or_null<AbstractStorageDecl>(
14213
+ selected->choice.getDeclOrNull())) {
14214
+ return storage->isSettable(nullptr) ? 1 : 2;
14215
+ }
14216
+ }
14217
+ }
14218
+ return 2;
14219
+ };
14220
+
14221
+ if (recordFix(
14222
+ TreatRValueAsLValue::create(*this, getConstraintLocator(locator)),
14223
+ assessImpact()))
14224
+ return SolutionKind::Error;
14225
+
14226
+ lvalueTy = LValueType::get(lvalueTy);
14227
+ }
14228
+
14229
+ if (lvalueTy->isTypeVariableOrMember())
14230
+ return formUnsolved();
14231
+
14232
+ // TODO: This operation deserves its own locator just like OptionalObject.
14233
+ addConstraint(ConstraintKind::Equal,
14234
+ lvalueTy->castTo<LValueType>()->getObjectType(), type2,
14235
+ getConstraintLocator(locator));
14236
+ return SolutionKind::Solved;
14237
+ }
14238
+
14161
14239
static llvm::PointerIntPair<Type, 3, unsigned>
14162
14240
getBaseTypeForPointer(TypeBase *type) {
14163
14241
unsigned unwrapCount = 0;
@@ -15625,6 +15703,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
15625
15703
return simplifyMaterializePackExpansionConstraint(first, second, subflags,
15626
15704
locator);
15627
15705
15706
+ case ConstraintKind::LValueObject:
15707
+ return simplifyLValueObjectConstraint(first, second, subflags, locator);
15708
+
15628
15709
case ConstraintKind::ValueMember:
15629
15710
case ConstraintKind::UnresolvedValueMember:
15630
15711
case ConstraintKind::ValueWitness:
@@ -16220,6 +16301,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
16220
16301
return simplifyMaterializePackExpansionConstraint(
16221
16302
constraint.getFirstType(), constraint.getSecondType(),
16222
16303
/*flags*/ std::nullopt, constraint.getLocator());
16304
+
16305
+ case ConstraintKind::LValueObject:
16306
+ return simplifyLValueObjectConstraint(
16307
+ constraint.getFirstType(), constraint.getSecondType(),
16308
+ /*flags*/ std::nullopt, constraint.getLocator());
16223
16309
}
16224
16310
16225
16311
llvm_unreachable("Unhandled ConstraintKind in switch.");
0 commit comments