@@ -34,6 +34,20 @@ using namespace constraints;
34
34
35
35
namespace {
36
36
37
+ // TODO: both `isIntegerType` and `isFloatType` should be available on Type
38
+ // as `isStdlib{Integer, Float}Type`.
39
+
40
+ static bool isIntegerType (Type type) {
41
+ return type->isInt () || type->isInt8 () || type->isInt16 () ||
42
+ type->isInt32 () || type->isInt64 () || type->isUInt () ||
43
+ type->isUInt8 () || type->isUInt16 () || type->isUInt32 () ||
44
+ type->isUInt64 ();
45
+ }
46
+
47
+ static bool isFloatType (Type type) {
48
+ return type->isFloat () || type->isDouble () || type->isFloat80 ();
49
+ }
50
+
37
51
static bool isSupportedOperator (Constraint *disjunction) {
38
52
if (!isOperatorDisjunction (disjunction))
39
53
return false ;
@@ -57,6 +71,16 @@ static bool isSupportedOperator(Constraint *disjunction) {
57
71
return false ;
58
72
}
59
73
74
+ static bool isSupportedSpecialConstructor (ConstructorDecl *ctor) {
75
+ if (auto *selfDecl = ctor->getImplicitSelfDecl ()) {
76
+ auto selfTy = selfDecl->getInterfaceType ();
77
+ // / Support `Int*`, `Float*` and `Double` initializers since their generic
78
+ // / overloads are not too complicated.
79
+ return selfTy && (isIntegerType (selfTy) || isFloatType (selfTy));
80
+ }
81
+ return false ;
82
+ }
83
+
60
84
static bool isStandardComparisonOperator (ValueDecl *decl) {
61
85
return decl->isOperator () &&
62
86
decl->getBaseIdentifier ().isStandardComparisonOperator ();
@@ -72,6 +96,12 @@ static bool isSupportedDisjunction(Constraint *disjunction) {
72
96
if (isSupportedOperator (disjunction))
73
97
return true ;
74
98
99
+ if (auto *ctor = dyn_cast_or_null<ConstructorDecl>(
100
+ getOverloadChoiceDecl (choices.front ()))) {
101
+ if (isSupportedSpecialConstructor (ctor))
102
+ return true ;
103
+ }
104
+
75
105
// Non-operator disjunctions are supported only if they don't
76
106
// have any generic choices.
77
107
return llvm::all_of (choices, [&](Constraint *choice) {
0 commit comments