1818#ifndef SWIFT_SEMA_CONSTRAINT_H
1919#define SWIFT_SEMA_CONSTRAINT_H
2020
21+ #include " swift/AST/ASTNode.h"
2122#include " swift/AST/FunctionRefKind.h"
2223#include " swift/AST/Identifier.h"
2324#include " swift/AST/Type.h"
25+ #include " swift/AST/TypeLoc.h"
2426#include " swift/Basic/Debug.h"
27+ #include " swift/Sema/ConstraintLocator.h"
2528#include " swift/Sema/OverloadChoice.h"
2629#include " llvm/ADT/ArrayRef.h"
2730#include " llvm/ADT/ilist.h"
@@ -47,6 +50,23 @@ class ConstraintLocator;
4750class ConstraintSystem ;
4851enum class TrailingClosureMatching ;
4952
53+ // / Describes contextual type information about a particular element
54+ // / (expression, statement etc.) within a constraint system.
55+ struct ContextualTypeInfo {
56+ TypeLoc typeLoc;
57+ ContextualTypePurpose purpose;
58+
59+ ContextualTypeInfo () : typeLoc(TypeLoc()), purpose(CTP_Unused) {}
60+
61+ ContextualTypeInfo (Type contextualTy, ContextualTypePurpose purpose)
62+ : typeLoc(TypeLoc::withoutLoc(contextualTy)), purpose(purpose) {}
63+
64+ ContextualTypeInfo (TypeLoc typeLoc, ContextualTypePurpose purpose)
65+ : typeLoc(typeLoc), purpose(purpose) {}
66+
67+ Type getType () const { return typeLoc.getType (); }
68+ };
69+
5070// / Describes the kind of constraint placed on one or more types.
5171enum class ConstraintKind : char {
5272 // / The two types must be bound to the same type. This is the only
@@ -129,6 +149,9 @@ enum class ConstraintKind : char {
129149 // / A disjunction constraint that specifies that one or more of the
130150 // / stored constraints must hold.
131151 Disjunction,
152+ // / A conjunction constraint that specifies that all of the stored
153+ // / constraints must hold.
154+ Conjunction,
132155 // / The first type is an optional type whose object type is the second
133156 // / type, preserving lvalue-ness.
134157 OptionalObject,
@@ -192,6 +215,10 @@ enum class ConstraintKind : char {
192215 // / inferred from a conversion, so the check is more relax comparing to
193216 // / `ConformsTo`.
194217 TransitivelyConformsTo,
218+ // / Represents an AST node contained in a body of a closure. It has only
219+ // / one type - type variable representing type of a node, other side is
220+ // / the AST node to infer the type for.
221+ ClosureBodyElement,
195222};
196223
197224// / Classification of the different kinds of constraints.
@@ -208,7 +235,13 @@ enum class ConstraintClassification : char {
208235 TypeProperty,
209236
210237 // / A disjunction constraint.
211- Disjunction
238+ Disjunction,
239+
240+ // / A conjunction constraint.
241+ Conjunction,
242+
243+ // / An element of a closure body.
244+ ClosureElement,
212245};
213246
214247// / Specifies a restriction on the kind of conversion that should be
@@ -338,6 +371,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
338371 // / in its disjunction.
339372 unsigned IsFavored : 1 ;
340373
374+ // / Whether or not this constraint should be solved in isolation from
375+ // / the rest of the constraint system. Currently only applies to conjunctions.
376+ unsigned IsIsolated : 1 ;
377+
341378 // / The number of type variables referenced by this constraint.
342379 // /
343380 // / The type variables themselves are tail-allocated.
@@ -399,6 +436,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
399436 // / The DC in which the use appears.
400437 DeclContext *UseDC;
401438 } Overload;
439+
440+ struct {
441+ // / The node itself.
442+ ASTNode Element;
443+ // / Contextual information associated with the element (if any).
444+ ContextualTypeInfo Context;
445+ } ClosureElement;
402446 };
403447
404448 // / The locator that describes where in the expression this
@@ -410,7 +454,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
410454 void *operator new (size_t ) = delete ;
411455
412456 Constraint (ConstraintKind kind, ArrayRef<Constraint *> constraints,
413- ConstraintLocator *locator,
457+ bool isIsolated, ConstraintLocator *locator,
414458 SmallPtrSetImpl<TypeVariableType *> &typeVars);
415459
416460 // / Construct a new constraint.
@@ -450,6 +494,11 @@ class Constraint final : public llvm::ilist_node<Constraint>,
450494 ConstraintLocator *locator,
451495 SmallPtrSetImpl<TypeVariableType *> &typeVars);
452496
497+ // / Construct a closure body element constraint.
498+ Constraint (ASTNode node, ContextualTypeInfo context,
499+ ConstraintLocator *locator,
500+ SmallPtrSetImpl<TypeVariableType *> &typeVars);
501+
453502 // / Retrieve the type variables buffer, for internal mutation.
454503 MutableArrayRef<TypeVariableType *> getTypeVariablesBuffer () {
455504 return { getTrailingObjects<TypeVariableType *>(), NumTypeVariables };
@@ -518,12 +567,31 @@ class Constraint final : public llvm::ilist_node<Constraint>,
518567 RememberChoice_t shouldRememberChoice
519568 = ForgetChoice);
520569
570+ // / Create a new conjunction constraint.
571+ // /
572+ // / \param isIsolated - Indicates whether given constraint should be
573+ // / solved in isolation from the rest of the constraint system i.e.
574+ // / by removing all of the unrelated type variables and constraints.
575+ static Constraint *
576+ createConjunction (ConstraintSystem &cs, ArrayRef<Constraint *> constraints,
577+ bool isIsolated, ConstraintLocator *locator,
578+ ArrayRef<TypeVariableType *> referencedVars = {});
579+
521580 // / Create a new Applicable Function constraint.
522581 static Constraint *createApplicableFunction (
523582 ConstraintSystem &cs, Type argumentFnType, Type calleeType,
524583 Optional<TrailingClosureMatching> trailingClosureMatching,
525584 ConstraintLocator *locator);
526585
586+ static Constraint *createClosureBodyElement (ConstraintSystem &cs,
587+ ASTNode node,
588+ ConstraintLocator *locator);
589+
590+ static Constraint *createClosureBodyElement (ConstraintSystem &cs,
591+ ASTNode node,
592+ ContextualTypeInfo context,
593+ ConstraintLocator *locator);
594+
527595 // / Determine the kind of constraint.
528596 ConstraintKind getKind () const { return Kind; }
529597
@@ -629,6 +697,12 @@ class Constraint final : public llvm::ilist_node<Constraint>,
629697
630698 case ConstraintKind::Disjunction:
631699 return ConstraintClassification::Disjunction;
700+
701+ case ConstraintKind::Conjunction:
702+ return ConstraintClassification::Conjunction;
703+
704+ case ConstraintKind::ClosureBodyElement:
705+ return ConstraintClassification::ClosureElement;
632706 }
633707
634708 llvm_unreachable (" Unhandled ConstraintKind in switch." );
@@ -640,6 +714,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
640714 case ConstraintKind::Disjunction:
641715 llvm_unreachable (" disjunction constraints have no type operands" );
642716
717+ case ConstraintKind::Conjunction:
718+ llvm_unreachable (" conjunction constraints have no type operands" );
719+
643720 case ConstraintKind::BindOverload:
644721 return Overload.First ;
645722
@@ -648,6 +725,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
648725 case ConstraintKind::ValueWitness:
649726 return Member.First ;
650727
728+ case ConstraintKind::ClosureBodyElement:
729+ llvm_unreachable (" closure body element constraint has no type operands" );
730+
651731 default :
652732 return Types.First ;
653733 }
@@ -657,7 +737,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
657737 Type getSecondType () const {
658738 switch (getKind ()) {
659739 case ConstraintKind::Disjunction:
740+ case ConstraintKind::Conjunction:
660741 case ConstraintKind::BindOverload:
742+ case ConstraintKind::ClosureBodyElement:
661743 llvm_unreachable (" constraint has no second type" );
662744
663745 case ConstraintKind::ValueMember:
@@ -710,7 +792,8 @@ class Constraint final : public llvm::ilist_node<Constraint>,
710792
711793 // / Retrieve the set of constraints in a disjunction.
712794 ArrayRef<Constraint *> getNestedConstraints () const {
713- assert (Kind == ConstraintKind::Disjunction);
795+ assert (Kind == ConstraintKind::Disjunction ||
796+ Kind == ConstraintKind::Conjunction);
714797 return Nested;
715798 }
716799
@@ -735,6 +818,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
735818 // / e.g. coercion constraint "as X" which forms a disjunction.
736819 bool isExplicitConversion () const ;
737820
821+ // / Determine whether this constraint should be solved in isolation
822+ // / from the rest of the constraint system.
823+ bool isIsolated () const { return IsIsolated; }
824+
738825 // / Whether this is a one-way constraint.
739826 bool isOneWayConstraint () const {
740827 return Kind == ConstraintKind::OneWayEqual ||
@@ -761,6 +848,16 @@ class Constraint final : public llvm::ilist_node<Constraint>,
761848 return Member.UseDC ;
762849 }
763850
851+ ASTNode getClosureElement () const {
852+ assert (Kind == ConstraintKind::ClosureBodyElement);
853+ return ClosureElement.Element ;
854+ }
855+
856+ ContextualTypeInfo getElementContext () const {
857+ assert (Kind == ConstraintKind::ClosureBodyElement);
858+ return ClosureElement.Context ;
859+ }
860+
764861 // / For an applicable function constraint, retrieve the trailing closure
765862 // / matching rule.
766863 Optional<TrailingClosureMatching> getTrailingClosureMatching () const ;
0 commit comments