Skip to content

Commit 5b4218c

Browse files
committed
Revert "Sema: Remove ConstraintKind::OneWayEqual"
This reverts commit 385d66f.
1 parent fa73be2 commit 5b4218c

File tree

6 files changed

+109
-1
lines changed

6 files changed

+109
-1
lines changed

include/swift/Sema/Constraint.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ enum class ConstraintKind : char {
150150
/// The key path type is chosen based on the selection of overloads for the
151151
/// member references along the path.
152152
KeyPath,
153+
/// The first type will be equal to the second type, but only when the
154+
/// second type has been fully determined (and mapped down to a concrete
155+
/// type). At that point, this constraint will be treated like an `Equal`
156+
/// constraint.
157+
OneWayEqual,
153158
/// If there is no contextual info e.g. `_ = { 42 }` default first type
154159
/// to a second type. This is effectively a `Defaultable` constraint
155160
/// which one significant difference:
@@ -675,6 +680,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
675680
case ConstraintKind::DynamicCallableApplicableFunction:
676681
case ConstraintKind::BindOverload:
677682
case ConstraintKind::OptionalObject:
683+
case ConstraintKind::OneWayEqual:
678684
case ConstraintKind::FallbackType:
679685
case ConstraintKind::UnresolvedMemberChainBase:
680686
case ConstraintKind::PackElementOf:
@@ -822,7 +828,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
822828

823829
/// Whether this is a one-way constraint.
824830
bool isOneWayConstraint() const {
825-
return false;
831+
return Kind == ConstraintKind::OneWayEqual;
826832
}
827833

828834
/// Retrieve the overload choice for an overload-binding constraint.

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5022,6 +5022,12 @@ class ConstraintSystem {
50225022
TypeMatchOptions flags,
50235023
ConstraintLocatorBuilder locator);
50245024

5025+
/// Attempt to simplify a one-way constraint.
5026+
SolutionKind simplifyOneWayConstraint(ConstraintKind kind,
5027+
Type first, Type second,
5028+
TypeMatchOptions flags,
5029+
ConstraintLocatorBuilder locator);
5030+
50255031
/// Simplify an equality constraint between result and base types of
50265032
/// an unresolved member chain.
50275033
SolutionKind simplifyUnresolvedMemberChainBaseConstraint(

lib/Sema/CSBindings.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,20 @@ void PotentialBindings::infer(ConstraintSystem &CS,
20392039

20402040
break;
20412041
}
2042+
2043+
case ConstraintKind::OneWayEqual:{
2044+
// Don't produce any bindings if this type variable is on the left-hand
2045+
// side of a one-way binding.
2046+
auto firstType = constraint->getFirstType();
2047+
if (auto *tv = firstType->getAs<TypeVariableType>()) {
2048+
if (tv->getImpl().getRepresentative(nullptr) == TypeVar) {
2049+
DelayedBy.push_back(constraint);
2050+
break;
2051+
}
2052+
}
2053+
2054+
break;
2055+
}
20422056
}
20432057
}
20442058

lib/Sema/CSSimplify.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,6 +2183,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
21832183
case ConstraintKind::ValueMember:
21842184
case ConstraintKind::ValueWitness:
21852185
case ConstraintKind::BridgingConversion:
2186+
case ConstraintKind::OneWayEqual:
21862187
case ConstraintKind::FallbackType:
21872188
case ConstraintKind::UnresolvedMemberChainBase:
21882189
case ConstraintKind::PropertyWrapper:
@@ -2544,6 +2545,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
25442545
case ConstraintKind::UnresolvedValueMember:
25452546
case ConstraintKind::ValueMember:
25462547
case ConstraintKind::ValueWitness:
2548+
case ConstraintKind::OneWayEqual:
25472549
case ConstraintKind::FallbackType:
25482550
case ConstraintKind::UnresolvedMemberChainBase:
25492551
case ConstraintKind::PropertyWrapper:
@@ -3187,6 +3189,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
31873189
case ConstraintKind::ValueMember:
31883190
case ConstraintKind::ValueWitness:
31893191
case ConstraintKind::BridgingConversion:
3192+
case ConstraintKind::OneWayEqual:
31903193
case ConstraintKind::FallbackType:
31913194
case ConstraintKind::UnresolvedMemberChainBase:
31923195
case ConstraintKind::PropertyWrapper:
@@ -7128,6 +7131,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
71287131
case ConstraintKind::UnresolvedValueMember:
71297132
case ConstraintKind::ValueMember:
71307133
case ConstraintKind::ValueWitness:
7134+
case ConstraintKind::OneWayEqual:
71317135
case ConstraintKind::FallbackType:
71327136
case ConstraintKind::UnresolvedMemberChainBase:
71337137
case ConstraintKind::PropertyWrapper:
@@ -11608,6 +11612,38 @@ ConstraintSystem::simplifyPropertyWrapperConstraint(
1160811612
return SolutionKind::Solved;
1160911613
}
1161011614

11615+
ConstraintSystem::SolutionKind
11616+
ConstraintSystem::simplifyOneWayConstraint(
11617+
ConstraintKind kind,
11618+
Type first, Type second, TypeMatchOptions flags,
11619+
ConstraintLocatorBuilder locator) {
11620+
// Determine whether the second type can be fully simplified. Only then
11621+
// will this constraint be resolved.
11622+
Type secondSimplified = simplifyType(second);
11623+
if (secondSimplified->hasTypeVariable()) {
11624+
if (flags.contains(TMF_GenerateConstraints)) {
11625+
addUnsolvedConstraint(
11626+
Constraint::create(*this, kind, first, second,
11627+
getConstraintLocator(locator)));
11628+
return SolutionKind::Solved;
11629+
}
11630+
11631+
return SolutionKind::Unsolved;
11632+
}
11633+
11634+
// Propagate holes through one-way constraints.
11635+
if (secondSimplified->isPlaceholder()) {
11636+
recordAnyTypeVarAsPotentialHole(first);
11637+
return SolutionKind::Solved;
11638+
}
11639+
11640+
// Translate this constraint into an equality or bind-parameter constraint,
11641+
// as appropriate.
11642+
ASSERT(kind == ConstraintKind::OneWayEqual);
11643+
return matchTypes(first, secondSimplified, ConstraintKind::Equal, flags,
11644+
locator);
11645+
}
11646+
1161111647
ConstraintSystem::SolutionKind
1161211648
ConstraintSystem::simplifyUnresolvedMemberChainBaseConstraint(
1161311649
Type first, Type second, TypeMatchOptions flags,
@@ -15685,6 +15721,9 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1568515721
case ConstraintKind::PropertyWrapper:
1568615722
return simplifyPropertyWrapperConstraint(first, second, subflags, locator);
1568715723

15724+
case ConstraintKind::OneWayEqual:
15725+
return simplifyOneWayConstraint(kind, first, second, subflags, locator);
15726+
1568815727
case ConstraintKind::UnresolvedMemberChainBase:
1568915728
return simplifyUnresolvedMemberChainBaseConstraint(first, second, subflags,
1569015729
locator);
@@ -16262,6 +16301,12 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1626216301
// See {Dis, Con}junctionStep class in CSStep.cpp for solving
1626316302
return SolutionKind::Unsolved;
1626416303

16304+
case ConstraintKind::OneWayEqual:
16305+
return simplifyOneWayConstraint(
16306+
constraint.getKind(), constraint.getFirstType(),
16307+
constraint.getSecondType(),
16308+
/*flags*/ std::nullopt, constraint.getLocator());
16309+
1626516310
case ConstraintKind::UnresolvedMemberChainBase:
1626616311
return simplifyUnresolvedMemberChainBaseConstraint(
1626716312
constraint.getFirstType(), constraint.getSecondType(),

lib/Sema/Constraint.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
7474
case ConstraintKind::EscapableFunctionOf:
7575
case ConstraintKind::OpenedExistentialOf:
7676
case ConstraintKind::OptionalObject:
77+
case ConstraintKind::OneWayEqual:
7778
case ConstraintKind::UnresolvedMemberChainBase:
7879
case ConstraintKind::PropertyWrapper:
7980
case ConstraintKind::BindTupleOfFunctionParams:
@@ -161,6 +162,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
161162
case ConstraintKind::BindOverload:
162163
case ConstraintKind::Disjunction:
163164
case ConstraintKind::Conjunction:
165+
case ConstraintKind::OneWayEqual:
164166
case ConstraintKind::FallbackType:
165167
case ConstraintKind::UnresolvedMemberChainBase:
166168
case ConstraintKind::PropertyWrapper:
@@ -393,6 +395,7 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm,
393395
case ConstraintKind::DynamicTypeOf: Out << " dynamicType type of "; break;
394396
case ConstraintKind::EscapableFunctionOf: Out << " @escaping type of "; break;
395397
case ConstraintKind::OpenedExistentialOf: Out << " opened archetype of "; break;
398+
case ConstraintKind::OneWayEqual: Out << " one-way bind to "; break;
396399
case ConstraintKind::FallbackType:
397400
Out << " can fallback to ";
398401
break;
@@ -668,6 +671,7 @@ gatherReferencedTypeVars(Constraint *constraint,
668671
case ConstraintKind::ConformsTo:
669672
case ConstraintKind::LiteralConformsTo:
670673
case ConstraintKind::TransitivelyConformsTo:
674+
case ConstraintKind::OneWayEqual:
671675
case ConstraintKind::FallbackType:
672676
case ConstraintKind::UnresolvedMemberChainBase:
673677
case ConstraintKind::PropertyWrapper:

lib/Sema/ConstraintSystem.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,6 +1867,39 @@ Type Solution::simplifyTypeForCodeCompletion(Type Ty) const {
18671867
return typeVar;
18681868
});
18691869

1870+
// Logic to determine the contextual type inside buildBlock result builders:
1871+
//
1872+
// When completing inside a result builder, the result builder
1873+
// @ViewBuilder var body: some View {
1874+
// Text("Foo")
1875+
// #^COMPLETE^#
1876+
// }
1877+
// gets rewritten to
1878+
// @ViewBuilder var body: some View {
1879+
// let $__builder2: Text
1880+
// let $__builder0 = Text("Foo")
1881+
// let $__builder1 = #^COMPLETE^#
1882+
// $__builder2 = ViewBuilder.buildBlock($__builder0, $__builder1)
1883+
// return $__builder2
1884+
// }
1885+
// Inside the constraint system
1886+
// let $__builder1 = #^COMPLETE^#
1887+
// gets type checked without context, so we can't know the contextual type for
1888+
// the code completion token. But we know that $__builder1 (and thus the type
1889+
// of #^COMPLETE^#) is used as the second argument to ViewBuilder.buildBlock,
1890+
// so we can extract the contextual type from that call. To do this, figure
1891+
// out the type variable that is used for $__builder1 in the buildBlock call.
1892+
// This type variable is connected to the type variable of $__builder1's
1893+
// definition by a one-way constraint.
1894+
if (auto TV = Ty->getAs<TypeVariableType>()) {
1895+
for (auto constraint : CS.getConstraintGraph()[TV].getConstraints()) {
1896+
if (constraint->getKind() == ConstraintKind::OneWayEqual &&
1897+
constraint->getSecondType()->isEqual(TV)) {
1898+
return simplifyTypeForCodeCompletion(constraint->getFirstType());
1899+
}
1900+
}
1901+
}
1902+
18701903
// Remove any remaining type variables and placeholders
18711904
Ty = simplifyType(Ty);
18721905

0 commit comments

Comments
 (0)