diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index 84e59155fe2..bb837ef983f 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -104,6 +104,17 @@ AddAddressOf *AddAddressOf::create(ConstraintSystem &cs, return new (cs.getAllocator()) AddAddressOf(locator); } +bool TreatRValueAsLValue::diagnose(Expr *root, const Solution &solution) const { + RValueTreatedAsLValueFailure failure(solution, getLocator()); + return failure.diagnose(); +} + +TreatRValueAsLValue *TreatRValueAsLValue::create(ConstraintSystem &cs, + ConstraintLocator *locator) { + return new (cs.getAllocator()) TreatRValueAsLValue(locator); +} + + bool CoerceToCheckedCast::diagnose(Expr *root, const Solution &solution) const { MissingForcedDowncastFailure failure(root, solution, getLocator()); return failure.diagnose(); diff --git a/lib/Sema/CSFix.h b/lib/Sema/CSFix.h index 155396bb297..84ecc8f1ce0 100644 --- a/lib/Sema/CSFix.h +++ b/lib/Sema/CSFix.h @@ -68,6 +68,9 @@ enum class FixKind : uint8_t { /// Add a new conformance to the type to satisfy a requirement. AddConformance, + + /// Treat rvalue as lvalue + TreatRValueAsLValue, }; class ConstraintFix { @@ -168,6 +171,20 @@ public: static AddAddressOf *create(ConstraintSystem &cs, ConstraintLocator *locator); }; +// Treat rvalue as if it was an lvalue +class TreatRValueAsLValue final : public ConstraintFix { + TreatRValueAsLValue(ConstraintLocator *locator) + : ConstraintFix(FixKind::TreatRValueAsLValue, locator) {} + +public: + std::string getName() const override { return "treat rvalue as lvalue"; } + + bool diagnose(Expr *root, const Solution &solution) const override; + + static TreatRValueAsLValue *create(ConstraintSystem &cs, ConstraintLocator *locator); +}; + + /// Replace a coercion ('as') with a forced checked cast ('as!'). class CoerceToCheckedCast final : public ConstraintFix { CoerceToCheckedCast(ConstraintLocator *locator) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 773cc958f64..e3bacbfe6fd 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2446,7 +2446,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, AddAddressOf::create(*this, getConstraintLocator(locator))); } else if (!isTypeVarOrMember1) { // If we have a concrete type that's an rvalue, "fix" it. - conversionsOrFixes.push_back(FixKind::TreatRValueAsLValue); + conversionsOrFixes.push_back( + TreatRValueAsLValue::create(*this, getConstraintLocator(locator))); } } } @@ -4990,7 +4991,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint( auto result = matchTypes(LValueType::get(type1), type2, matchKind, subflags, locator); if (result == SolutionKind::Solved) - if (recordFix(fix, locator)) + if (recordFix(fix)) return SolutionKind::Error; return result;