Skip to content

Commit 1ed2f62

Browse files
committed
[unittests/Sema] NFC: Add tests for literal requirement inference/coverage
Test that literal requirements are: - inferred correctly (both direct and transitive); - covered by direct/transtiive bindings.
1 parent b79b875 commit 1ed2f62

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

unittests/Sema/BindingInferenceTests.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "SemaFixture.h"
1414
#include "swift/AST/Expr.h"
1515
#include "swift/Sema/ConstraintSystem.h"
16+
#include "llvm/ADT/DenseMap.h"
1617
#include "llvm/ADT/SmallPtrSet.h"
1718

1819
using namespace swift;
@@ -49,6 +50,97 @@ TEST_F(SemaTest, TestIntLiteralBindingInference) {
4950
ASSERT_TRUE(literal.getDefaultType()->isEqual(intTy));
5051
ASSERT_FALSE(literal.isCovered());
5152
}
53+
54+
// Make sure that coverage by direct bindings works as expected.
55+
56+
// First, let's attempt a binding which would match default type
57+
// of the literal.
58+
59+
cs.addConstraint(ConstraintKind::Conversion, literalTy, intTy,
60+
cs.getConstraintLocator(intLiteral));
61+
62+
{
63+
auto bindings = cs.inferBindingsFor(literalTy);
64+
65+
ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);
66+
ASSERT_EQ(bindings.Literals.size(), (unsigned)1);
67+
68+
ASSERT_TRUE(bindings.Bindings[0].BindingType->isEqual(intTy));
69+
70+
const auto &literal = bindings.Literals.front().second;
71+
ASSERT_TRUE(literal.isCovered());
72+
ASSERT_TRUE(literal.isDirectRequirement());
73+
ASSERT_TRUE(literal.getDefaultType()->isEqual(intTy));
74+
}
75+
76+
// Now let's use non-default type that conforms to
77+
// `ExpressibleByIntegerLiteral` protocol.
78+
79+
auto *floatLiteralTy =
80+
cs.createTypeVariable(cs.getConstraintLocator(intLiteral),
81+
/*options=*/0);
82+
83+
auto floatTy = getStdlibType("Float");
84+
85+
// $T_float <conforms to> ExpressibleByIntegerLiteral
86+
cs.addConstraint(
87+
ConstraintKind::LiteralConformsTo, floatLiteralTy,
88+
Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral)
89+
->getDeclaredInterfaceType(),
90+
cs.getConstraintLocator(intLiteral));
91+
92+
// Float <covertible> $T_float
93+
cs.addConstraint(ConstraintKind::Conversion, floatTy, floatLiteralTy,
94+
cs.getConstraintLocator(intLiteral));
95+
96+
{
97+
auto bindings = cs.inferBindingsFor(floatLiteralTy);
98+
99+
ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);
100+
ASSERT_EQ(bindings.Literals.size(), (unsigned)1);
101+
102+
ASSERT_TRUE(bindings.Bindings[0].BindingType->isEqual(floatTy));
103+
104+
const auto &literal = bindings.Literals.front().second;
105+
ASSERT_TRUE(literal.isCovered());
106+
ASSERT_TRUE(literal.isDirectRequirement());
107+
ASSERT_FALSE(literal.getDefaultType()->isEqual(floatTy));
108+
}
109+
110+
// Let's test transitive literal requirement coverage,
111+
// literal requirements are prepagated up the subtype chain.
112+
113+
auto *otherTy = cs.createTypeVariable(cs.getConstraintLocator({}),
114+
/*options=*/0);
115+
116+
cs.addConstraint(ConstraintKind::Subtype, floatLiteralTy, otherTy,
117+
cs.getConstraintLocator({}));
118+
119+
{
120+
auto bindings = cs.inferBindingsFor(otherTy, /*finalize=*/false);
121+
122+
// Make sure that there are no direct bindings or protocol requirements.
123+
124+
ASSERT_EQ(bindings.Bindings.size(), (unsigned)0);
125+
ASSERT_EQ(bindings.Literals.size(), (unsigned)0);
126+
127+
llvm::SmallDenseMap<TypeVariableType *, ConstraintSystem::PotentialBindings>
128+
env;
129+
env.insert({floatLiteralTy, cs.inferBindingsFor(floatLiteralTy)});
130+
131+
bindings.finalize(cs, env);
132+
133+
// Inferred a single transitive binding through `$T_float`.
134+
ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);
135+
// Inferred literal requirement through `$T_float` as well.
136+
ASSERT_EQ(bindings.Literals.size(), (unsigned)1);
137+
138+
const auto &literal = bindings.Literals.front().second;
139+
140+
ASSERT_TRUE(literal.isCovered());
141+
ASSERT_FALSE(literal.isDirectRequirement());
142+
ASSERT_FALSE(literal.getDefaultType()->isEqual(floatTy));
143+
}
52144
}
53145

54146
// Given a set of inferred protocol requirements, make sure that

0 commit comments

Comments
 (0)