Skip to content

Commit 0000448

Browse files
committed
Add unit tests for placeholder type inference
1 parent 4dff94a commit 0000448

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

unittests/Sema/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ add_swift_unittest(swiftSemaTests
33
SemaFixture.cpp
44
BindingInferenceTests.cpp
55
ConstraintSimplificationTests.cpp
6-
UnresolvedMemberLookupTests.cpp)
6+
UnresolvedMemberLookupTests.cpp
7+
PlaceholderTypeInferenceTests.cpp)
78

89
target_link_libraries(swiftSemaTests
910
PRIVATE
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===--- PlaceholderTypeInferenceTests.cpp --------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "SemaFixture.h"
14+
#include "swift/Sema/ConstraintSystem.h"
15+
16+
using namespace swift;
17+
using namespace swift::unittest;
18+
using namespace swift::constraints;
19+
20+
TEST_F(SemaTest, TestPlaceholderInferenceForArrayLiteral) {
21+
auto *intTypeDecl = getStdlibNominalTypeDecl("Int");
22+
23+
auto *intLiteral = new (Context) IntegerLiteralExpr("0", SourceLoc(), true);
24+
auto *arrayExpr = ArrayExpr::create(Context, SourceLoc(), {intLiteral}, {}, SourceLoc());
25+
26+
auto *placeholderRepr = new (Context) PlaceholderTypeRepr(SourceLoc());
27+
auto *arrayRepr = new (Context) ArrayTypeRepr(placeholderRepr, SourceRange());
28+
auto placeholderTy = PlaceholderType::get(Context, placeholderRepr);
29+
auto *arrayTy = ArraySliceType::get(placeholderTy);
30+
31+
auto *varDecl = new (Context) VarDecl(false, VarDecl::Introducer::Let, SourceLoc(), Context.getIdentifier("x"), DC);
32+
auto *namedPattern = new (Context) NamedPattern(varDecl);
33+
auto *typedPattern = new (Context) TypedPattern(namedPattern, arrayRepr);
34+
35+
auto target = SolutionApplicationTarget::forInitialization(arrayExpr, DC, arrayTy, typedPattern, /*bindPatternVarsOneWay=*/false);
36+
37+
ConstraintSystem cs(DC, ConstraintSystemOptions());
38+
cs.setContextualType(arrayExpr, {arrayRepr, arrayTy}, CTP_Initialization);
39+
cs.generateConstraints(target, FreeTypeVariableBinding::Disallow);
40+
SmallVector<Solution, 2> solutions;
41+
cs.solve(solutions);
42+
43+
// We should have a solution.
44+
ASSERT_EQ(solutions.size(), 1u);
45+
46+
auto &solution = solutions[0];
47+
48+
auto eltTy = ConstraintSystem::isArrayType(solution.simplifyType(solution.getType(arrayExpr)));
49+
ASSERT_TRUE(eltTy.hasValue());
50+
ASSERT_TRUE((*eltTy)->is<StructType>());
51+
ASSERT_EQ((*eltTy)->getAs<StructType>()->getDecl(), intTypeDecl);
52+
}
53+
54+
TEST_F(SemaTest, TestPlaceholderInferenceForDictionaryLiteral) {
55+
auto *intTypeDecl = getStdlibNominalTypeDecl("Int");
56+
auto *stringTypeDecl = getStdlibNominalTypeDecl("String");
57+
58+
auto *intLiteral = new (Context) IntegerLiteralExpr("0", SourceLoc(), true);
59+
auto *stringLiteral = new (Context) StringLiteralExpr("test", SourceRange(), true);
60+
auto *kvTupleExpr = TupleExpr::create(Context, SourceLoc(), {stringLiteral, intLiteral}, {}, {}, SourceLoc(), true);
61+
auto *dictExpr = DictionaryExpr::create(Context, SourceLoc(), {kvTupleExpr}, {}, SourceLoc());
62+
63+
auto *keyPlaceholderRepr = new (Context) PlaceholderTypeRepr(SourceLoc());
64+
auto *valPlaceholderRepr = new (Context) PlaceholderTypeRepr(SourceLoc());
65+
auto *dictRepr = new (Context) DictionaryTypeRepr(keyPlaceholderRepr, valPlaceholderRepr, SourceLoc(), SourceRange());
66+
auto keyPlaceholderTy = PlaceholderType::get(Context, keyPlaceholderRepr);
67+
auto valPlaceholderTy = PlaceholderType::get(Context, valPlaceholderRepr);
68+
auto *dictTy = DictionaryType::get(keyPlaceholderTy, valPlaceholderTy);
69+
70+
auto *varDecl = new (Context) VarDecl(false, VarDecl::Introducer::Let, SourceLoc(), Context.getIdentifier("x"), DC);
71+
auto *namedPattern = new (Context) NamedPattern(varDecl);
72+
auto *typedPattern = new (Context) TypedPattern(namedPattern, dictRepr);
73+
74+
auto target = SolutionApplicationTarget::forInitialization(dictExpr, DC, dictTy, typedPattern, /*bindPatternVarsOneWay=*/false);
75+
76+
ConstraintSystem cs(DC, ConstraintSystemOptions());
77+
cs.setContextualType(dictExpr, {dictRepr, dictTy}, CTP_Initialization);
78+
cs.generateConstraints(target, FreeTypeVariableBinding::Disallow);
79+
SmallVector<Solution, 2> solutions;
80+
cs.solve(solutions);
81+
82+
// We should have a solution.
83+
ASSERT_EQ(solutions.size(), 1u);
84+
85+
auto &solution = solutions[0];
86+
87+
auto keyValTys = ConstraintSystem::isDictionaryType(solution.simplifyType(solution.getType(dictExpr)));
88+
ASSERT_TRUE(keyValTys.hasValue());
89+
90+
Type keyTy;
91+
Type valTy;
92+
std::tie(keyTy, valTy) = *keyValTys;
93+
ASSERT_TRUE(keyTy->is<StructType>());
94+
ASSERT_EQ(keyTy->getAs<StructType>()->getDecl(), stringTypeDecl);
95+
96+
ASSERT_TRUE(valTy->is<StructType>());
97+
ASSERT_EQ(valTy->getAs<StructType>()->getDecl(), intTypeDecl);
98+
}

0 commit comments

Comments
 (0)