Skip to content

Commit 19d3987

Browse files
authored
Merge pull request swiftlang#79105 from slavapestov/revert-one-way-removal
Partial revert of swiftlang#78301
2 parents 8127c83 + 0882a07 commit 19d3987

20 files changed

+915
-138
lines changed

include/swift/Sema/Constraint.h

+11
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:
@@ -820,6 +826,11 @@ class Constraint final : public llvm::ilist_node<Constraint>,
820826
/// from the rest of the constraint system.
821827
bool isIsolated() const { return IsIsolated; }
822828

829+
/// Whether this is a one-way constraint.
830+
bool isOneWayConstraint() const {
831+
return Kind == ConstraintKind::OneWayEqual;
832+
}
833+
823834
/// Retrieve the overload choice for an overload-binding constraint.
824835
OverloadChoice getOverloadChoice() const {
825836
assert(Kind == ConstraintKind::BindOverload);

include/swift/Sema/ConstraintGraph.h

+28-10
Original file line numberDiff line numberDiff line change
@@ -300,18 +300,25 @@ class ConstraintGraph {
300300
/// to a type variable.
301301
void introduceToInference(TypeVariableType *typeVar, Type fixedType);
302302

303-
/// Gather constraints associated with all of the variables within the
304-
/// same equivalence class as the given type variable, as well as its
305-
/// immediate fixed bindings.
306-
llvm::TinyPtrVector<Constraint *>
307-
gatherAllConstraints(TypeVariableType *typeVar);
303+
/// Describes which constraints \c gatherConstraints should gather.
304+
enum class GatheringKind {
305+
/// Gather constraints associated with all of the variables within the
306+
/// same equivalence class as the given type variable, as well as its
307+
/// immediate fixed bindings.
308+
EquivalenceClass,
309+
/// Gather all constraints that mention this type variable or type variables
310+
/// that it is a fixed binding of. Unlike EquivalenceClass, this looks
311+
/// through transitive fixed bindings. This can be used to find all the
312+
/// constraints that may be affected when binding a type variable.
313+
AllMentions,
314+
};
308315

309-
/// Gather all constraints that mention this type variable or type variables
310-
/// that it is a fixed binding of. Unlike EquivalenceClass, this looks
311-
/// through transitive fixed bindings. This can be used to find all the
312-
/// constraints that may be affected when binding a type variable.
316+
/// Gather the set of constraints that involve the given type variable,
317+
/// i.e., those constraints that will be affected when the type variable
318+
/// gets merged or bound to a fixed type.
313319
llvm::TinyPtrVector<Constraint *>
314-
gatherNearbyConstraints(TypeVariableType *typeVar,
320+
gatherConstraints(TypeVariableType *typeVar,
321+
GatheringKind kind,
315322
llvm::function_ref<bool(Constraint *)> acceptConstraint =
316323
[](Constraint *constraint) { return true; });
317324

@@ -336,6 +343,12 @@ class ConstraintGraph {
336343
/// The constraints in this component.
337344
TinyPtrVector<Constraint *> constraints;
338345

346+
/// The set of components that this component depends on, such that
347+
/// the partial solutions of the those components need to be available
348+
/// before this component can be solved.
349+
///
350+
SmallVector<unsigned, 2> dependencies;
351+
339352
public:
340353
Component(unsigned solutionIndex) : solutionIndex(solutionIndex) { }
341354

@@ -351,6 +364,11 @@ class ConstraintGraph {
351364
return constraints;
352365
}
353366

367+
/// Records a component which this component depends on.
368+
void recordDependency(const Component &component);
369+
370+
ArrayRef<unsigned> getDependencies() const { return dependencies; }
371+
354372
unsigned getNumDisjunctions() const { return numDisjunctions; }
355373
};
356374

include/swift/Sema/ConstraintSystem.h

+7
Original file line numberDiff line numberDiff line change
@@ -4516,6 +4516,7 @@ class ConstraintSystem {
45164516
/// \returns a possibly-sanitized initializer, or null if an error occurred.
45174517
[[nodiscard]]
45184518
Type generateConstraints(Pattern *P, ConstraintLocatorBuilder locator,
4519+
bool bindPatternVarsOneWay,
45194520
PatternBindingDecl *patternBinding,
45204521
unsigned patternIndex);
45214522

@@ -5022,6 +5023,12 @@ class ConstraintSystem {
50225023
TypeMatchOptions flags,
50235024
ConstraintLocatorBuilder locator);
50245025

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

include/swift/Sema/SyntacticElementTarget.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ class SyntacticElementTarget {
114114
/// Whether the expression result will be discarded at the end.
115115
bool isDiscarded;
116116

117+
/// Whether to bind the variables encountered within the pattern to
118+
/// fresh type variables via one-way constraints.
119+
bool bindPatternVarsOneWay;
120+
117121
union {
118122
struct {
119123
/// The pattern binding declaration for an initialization, if any.
@@ -251,14 +255,14 @@ class SyntacticElementTarget {
251255
/// Form a target for the initialization of a pattern from an expression.
252256
static SyntacticElementTarget
253257
forInitialization(Expr *initializer, DeclContext *dc, Type patternType,
254-
Pattern *pattern);
258+
Pattern *pattern, bool bindPatternVarsOneWay);
255259

256260
/// Form a target for the initialization of a pattern binding entry from
257261
/// an expression.
258262
static SyntacticElementTarget
259263
forInitialization(Expr *initializer, Type patternType,
260264
PatternBindingDecl *patternBinding,
261-
unsigned patternBindingIndex);
265+
unsigned patternBindingIndex, bool bindPatternVarsOneWay);
262266

263267
/// Form an expression target for a ReturnStmt.
264268
static SyntacticElementTarget
@@ -493,6 +497,14 @@ class SyntacticElementTarget {
493497
return false;
494498
}
495499

500+
/// Whether to bind the types of any variables within the pattern via
501+
/// one-way constraints.
502+
bool shouldBindPatternVarsOneWay() const {
503+
if (kind == Kind::expression)
504+
return expression.bindPatternVarsOneWay;
505+
return false;
506+
}
507+
496508
/// Whether or not an opaque value placeholder should be injected into the
497509
/// first \c wrappedValue argument of an apply expression so the initializer
498510
/// expression can be turned into a property wrapper generator function.

lib/Sema/CSBindings.cpp

+14
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

0 commit comments

Comments
 (0)