18
18
#ifndef SWIFT_SEMA_CONSTRAINT_H
19
19
#define SWIFT_SEMA_CONSTRAINT_H
20
20
21
+ #include " swift/AST/ASTNode.h"
21
22
#include " swift/AST/FunctionRefKind.h"
22
23
#include " swift/AST/Identifier.h"
23
24
#include " swift/AST/Type.h"
25
+ #include " swift/AST/TypeLoc.h"
24
26
#include " swift/Basic/Debug.h"
27
+ #include " swift/Sema/ConstraintLocator.h"
25
28
#include " swift/Sema/OverloadChoice.h"
26
29
#include " llvm/ADT/ArrayRef.h"
27
30
#include " llvm/ADT/ilist.h"
@@ -47,6 +50,23 @@ class ConstraintLocator;
47
50
class ConstraintSystem ;
48
51
enum class TrailingClosureMatching ;
49
52
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
+
50
70
// / Describes the kind of constraint placed on one or more types.
51
71
enum class ConstraintKind : char {
52
72
// / The two types must be bound to the same type. This is the only
@@ -129,6 +149,9 @@ enum class ConstraintKind : char {
129
149
// / A disjunction constraint that specifies that one or more of the
130
150
// / stored constraints must hold.
131
151
Disjunction,
152
+ // / A conjunction constraint that specifies that all of the stored
153
+ // / constraints must hold.
154
+ Conjunction,
132
155
// / The first type is an optional type whose object type is the second
133
156
// / type, preserving lvalue-ness.
134
157
OptionalObject,
@@ -192,6 +215,10 @@ enum class ConstraintKind : char {
192
215
// / inferred from a conversion, so the check is more relax comparing to
193
216
// / `ConformsTo`.
194
217
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,
195
222
};
196
223
197
224
// / Classification of the different kinds of constraints.
@@ -208,7 +235,13 @@ enum class ConstraintClassification : char {
208
235
TypeProperty,
209
236
210
237
// / A disjunction constraint.
211
- Disjunction
238
+ Disjunction,
239
+
240
+ // / A conjunction constraint.
241
+ Conjunction,
242
+
243
+ // / An element of a closure body.
244
+ ClosureElement,
212
245
};
213
246
214
247
// / Specifies a restriction on the kind of conversion that should be
@@ -338,6 +371,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
338
371
// / in its disjunction.
339
372
unsigned IsFavored : 1 ;
340
373
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
+
341
378
// / The number of type variables referenced by this constraint.
342
379
// /
343
380
// / The type variables themselves are tail-allocated.
@@ -399,6 +436,13 @@ class Constraint final : public llvm::ilist_node<Constraint>,
399
436
// / The DC in which the use appears.
400
437
DeclContext *UseDC;
401
438
} 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;
402
446
};
403
447
404
448
// / The locator that describes where in the expression this
@@ -410,7 +454,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
410
454
void *operator new (size_t ) = delete ;
411
455
412
456
Constraint (ConstraintKind kind, ArrayRef<Constraint *> constraints,
413
- ConstraintLocator *locator,
457
+ bool isIsolated, ConstraintLocator *locator,
414
458
SmallPtrSetImpl<TypeVariableType *> &typeVars);
415
459
416
460
// / Construct a new constraint.
@@ -450,6 +494,11 @@ class Constraint final : public llvm::ilist_node<Constraint>,
450
494
ConstraintLocator *locator,
451
495
SmallPtrSetImpl<TypeVariableType *> &typeVars);
452
496
497
+ // / Construct a closure body element constraint.
498
+ Constraint (ASTNode node, ContextualTypeInfo context,
499
+ ConstraintLocator *locator,
500
+ SmallPtrSetImpl<TypeVariableType *> &typeVars);
501
+
453
502
// / Retrieve the type variables buffer, for internal mutation.
454
503
MutableArrayRef<TypeVariableType *> getTypeVariablesBuffer () {
455
504
return { getTrailingObjects<TypeVariableType *>(), NumTypeVariables };
@@ -518,12 +567,31 @@ class Constraint final : public llvm::ilist_node<Constraint>,
518
567
RememberChoice_t shouldRememberChoice
519
568
= ForgetChoice);
520
569
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
+
521
580
// / Create a new Applicable Function constraint.
522
581
static Constraint *createApplicableFunction (
523
582
ConstraintSystem &cs, Type argumentFnType, Type calleeType,
524
583
Optional<TrailingClosureMatching> trailingClosureMatching,
525
584
ConstraintLocator *locator);
526
585
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
+
527
595
// / Determine the kind of constraint.
528
596
ConstraintKind getKind () const { return Kind; }
529
597
@@ -629,6 +697,12 @@ class Constraint final : public llvm::ilist_node<Constraint>,
629
697
630
698
case ConstraintKind::Disjunction:
631
699
return ConstraintClassification::Disjunction;
700
+
701
+ case ConstraintKind::Conjunction:
702
+ return ConstraintClassification::Conjunction;
703
+
704
+ case ConstraintKind::ClosureBodyElement:
705
+ return ConstraintClassification::ClosureElement;
632
706
}
633
707
634
708
llvm_unreachable (" Unhandled ConstraintKind in switch." );
@@ -640,6 +714,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
640
714
case ConstraintKind::Disjunction:
641
715
llvm_unreachable (" disjunction constraints have no type operands" );
642
716
717
+ case ConstraintKind::Conjunction:
718
+ llvm_unreachable (" conjunction constraints have no type operands" );
719
+
643
720
case ConstraintKind::BindOverload:
644
721
return Overload.First ;
645
722
@@ -648,6 +725,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
648
725
case ConstraintKind::ValueWitness:
649
726
return Member.First ;
650
727
728
+ case ConstraintKind::ClosureBodyElement:
729
+ llvm_unreachable (" closure body element constraint has no type operands" );
730
+
651
731
default :
652
732
return Types.First ;
653
733
}
@@ -657,7 +737,9 @@ class Constraint final : public llvm::ilist_node<Constraint>,
657
737
Type getSecondType () const {
658
738
switch (getKind ()) {
659
739
case ConstraintKind::Disjunction:
740
+ case ConstraintKind::Conjunction:
660
741
case ConstraintKind::BindOverload:
742
+ case ConstraintKind::ClosureBodyElement:
661
743
llvm_unreachable (" constraint has no second type" );
662
744
663
745
case ConstraintKind::ValueMember:
@@ -710,7 +792,8 @@ class Constraint final : public llvm::ilist_node<Constraint>,
710
792
711
793
// / Retrieve the set of constraints in a disjunction.
712
794
ArrayRef<Constraint *> getNestedConstraints () const {
713
- assert (Kind == ConstraintKind::Disjunction);
795
+ assert (Kind == ConstraintKind::Disjunction ||
796
+ Kind == ConstraintKind::Conjunction);
714
797
return Nested;
715
798
}
716
799
@@ -735,6 +818,10 @@ class Constraint final : public llvm::ilist_node<Constraint>,
735
818
// / e.g. coercion constraint "as X" which forms a disjunction.
736
819
bool isExplicitConversion () const ;
737
820
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
+
738
825
// / Whether this is a one-way constraint.
739
826
bool isOneWayConstraint () const {
740
827
return Kind == ConstraintKind::OneWayEqual ||
@@ -761,6 +848,16 @@ class Constraint final : public llvm::ilist_node<Constraint>,
761
848
return Member.UseDC ;
762
849
}
763
850
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
+
764
861
// / For an applicable function constraint, retrieve the trailing closure
765
862
// / matching rule.
766
863
Optional<TrailingClosureMatching> getTrailingClosureMatching () const ;
0 commit comments