@@ -2319,6 +2319,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
23192319 case ConstraintKind::ExplicitGenericArguments:
23202320 case ConstraintKind::SameShape:
23212321 case ConstraintKind::MaterializePackExpansion:
2322+ case ConstraintKind::LValueObject:
23222323 llvm_unreachable("Bad constraint kind in matchTupleTypes()");
23232324 }
23242325
@@ -2679,6 +2680,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
26792680 case ConstraintKind::ExplicitGenericArguments:
26802681 case ConstraintKind::SameShape:
26812682 case ConstraintKind::MaterializePackExpansion:
2683+ case ConstraintKind::LValueObject:
26822684 return true;
26832685 }
26842686
@@ -3324,6 +3326,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
33243326 case ConstraintKind::ExplicitGenericArguments:
33253327 case ConstraintKind::SameShape:
33263328 case ConstraintKind::MaterializePackExpansion:
3329+ case ConstraintKind::LValueObject:
33273330 llvm_unreachable("Not a relational constraint");
33283331 }
33293332
@@ -7185,6 +7188,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
71857188 case ConstraintKind::ExplicitGenericArguments:
71867189 case ConstraintKind::SameShape:
71877190 case ConstraintKind::MaterializePackExpansion:
7191+ case ConstraintKind::LValueObject:
71887192 llvm_unreachable("Not a relational constraint");
71897193 }
71907194 }
@@ -14158,6 +14162,80 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1415814162 return SolutionKind::Solved;
1415914163}
1416014164
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+
1416114239static llvm::PointerIntPair<Type, 3, unsigned>
1416214240getBaseTypeForPointer(TypeBase *type) {
1416314241 unsigned unwrapCount = 0;
@@ -15625,6 +15703,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1562515703 return simplifyMaterializePackExpansionConstraint(first, second, subflags,
1562615704 locator);
1562715705
15706+ case ConstraintKind::LValueObject:
15707+ return simplifyLValueObjectConstraint(first, second, subflags, locator);
15708+
1562815709 case ConstraintKind::ValueMember:
1562915710 case ConstraintKind::UnresolvedValueMember:
1563015711 case ConstraintKind::ValueWitness:
@@ -16220,6 +16301,11 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1622016301 return simplifyMaterializePackExpansionConstraint(
1622116302 constraint.getFirstType(), constraint.getSecondType(),
1622216303 /*flags*/ std::nullopt, constraint.getLocator());
16304+
16305+ case ConstraintKind::LValueObject:
16306+ return simplifyLValueObjectConstraint(
16307+ constraint.getFirstType(), constraint.getSecondType(),
16308+ /*flags*/ std::nullopt, constraint.getLocator());
1622316309 }
1622416310
1622516311 llvm_unreachable("Unhandled ConstraintKind in switch.");
0 commit comments