diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index bf0b921eac731..0642dedac73ba 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -4942,6 +4942,7 @@ class ConstraintSystem { Optional checkTypeOfBinding(TypeVariableType *typeVar, Type type) const; Optional determineBestBindings(); +public: /// Infer bindings for the given type variable based on current /// state of the constraint system. PotentialBindings inferBindingsFor(TypeVariableType *typeVar, diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 5c6daa804cff8..ca552a07b4d15 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -12,6 +12,7 @@ if(SWIFT_INCLUDE_TOOLS) add_subdirectory(Localization) add_subdirectory(IDE) add_subdirectory(Parse) + add_subdirectory(Sema) add_subdirectory(SwiftDemangle) add_subdirectory(Syntax) if(SWIFT_BUILD_SYNTAXPARSERLIB) diff --git a/unittests/Sema/BindingInferenceTests.cpp b/unittests/Sema/BindingInferenceTests.cpp new file mode 100644 index 0000000000000..f4b71d921a28c --- /dev/null +++ b/unittests/Sema/BindingInferenceTests.cpp @@ -0,0 +1,46 @@ +//===--- BindingInferenceTests.cpp ----------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "SemaFixture.h" +#include "swift/AST/Expr.h" +#include "swift/Sema/ConstraintSystem.h" + +using namespace swift; +using namespace swift::unittest; +using namespace swift::constraints; + +TEST_F(SemaTest, TestIntLiteralBindingInference) { + ConstraintSystemOptions options; + options |= ConstraintSystemFlags::AllowUnresolvedTypeVariables; + + ConstraintSystem cs(DC, options); + + auto *intLiteral = IntegerLiteralExpr::createFromUnsigned(Context, 42); + + auto *literalTy = cs.createTypeVariable(cs.getConstraintLocator(intLiteral), + /*options=*/0); + + cs.addConstraint( + ConstraintKind::LiteralConformsTo, literalTy, + Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral) + ->getDeclaredInterfaceType(), + cs.getConstraintLocator(intLiteral)); + + auto bindings = cs.inferBindingsFor(literalTy); + + ASSERT_EQ(bindings.Bindings.size(), (unsigned)1); + + const auto &binding = bindings.Bindings.front(); + + ASSERT_TRUE(binding.BindingType->isEqual(getStdlibType("Int"))); + ASSERT_TRUE(binding.hasDefaultedLiteralProtocol()); +} diff --git a/unittests/Sema/CMakeLists.txt b/unittests/Sema/CMakeLists.txt new file mode 100644 index 0000000000000..1257490d9183e --- /dev/null +++ b/unittests/Sema/CMakeLists.txt @@ -0,0 +1,13 @@ + +add_swift_unittest(swiftSemaTests + SemaFixture.cpp + BindingInferenceTests.cpp) + +target_link_libraries(swiftSemaTests + PRIVATE + swiftAST + swiftSema + swiftSerialization) + +target_compile_definitions(swiftSemaTests PRIVATE + SWIFTLIB_DIR=\"${SWIFTLIB_DIR}\") diff --git a/unittests/Sema/SemaFixture.cpp b/unittests/Sema/SemaFixture.cpp new file mode 100644 index 0000000000000..d260b1227ca73 --- /dev/null +++ b/unittests/Sema/SemaFixture.cpp @@ -0,0 +1,76 @@ +//===--- SemaFixture.cpp - Helper for setting up Sema context --------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "SemaFixture.h" +#include "swift/AST/Decl.h" +#include "swift/AST/Import.h" +#include "swift/AST/Module.h" +#include "swift/AST/ParseRequests.h" +#include "swift/AST/SourceFile.h" +#include "swift/AST/Type.h" +#include "swift/AST/Types.h" +#include "swift/Basic/LLVMInitialize.h" +#include "swift/ClangImporter/ClangImporter.h" +#include "swift/Serialization/SerializedModuleLoader.h" +#include "swift/Subsystems.h" + +using namespace swift; +using namespace swift::unittest; + +SemaTest::SemaTest() + : Context(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, + ClangImporterOpts, SourceMgr, Diags)) { + INITIALIZE_LLVM(); + + registerParseRequestFunctions(Context.evaluator); + registerTypeCheckerRequestFunctions(Context.evaluator); + + Context.addModuleLoader(ImplicitSerializedModuleLoader::create(Context)); + Context.addModuleLoader(ClangImporter::create(Context), /*isClang=*/true); + + auto *stdlib = Context.getStdlibModule(/*loadIfAbsent=*/true); + assert(stdlib && "Failed to load standard library"); + + auto *module = + ModuleDecl::create(Context.getIdentifier("SemaTests"), Context); + + MainFile = new (Context) SourceFile(*module, SourceFileKind::Main, + /*buffer=*/None); + + AttributedImport stdlibImport{{ImportPath::Access(), stdlib}, + /*options=*/{}}; + + MainFile->setImports(stdlibImport); + module->addFile(*MainFile); + + DC = module; +} + +Type SemaTest::getStdlibType(StringRef name) const { + auto typeName = Context.getIdentifier(name); + + auto *stdlib = Context.getStdlibModule(); + + llvm::SmallVector results; + stdlib->lookupValue(typeName, NLKind::UnqualifiedLookup, results); + + if (results.size() != 1) + return Type(); + + if (auto *decl = dyn_cast(results.front())) { + if (auto *NTD = dyn_cast(decl)) + return NTD->getDeclaredType(); + return decl->getDeclaredInterfaceType(); + } + + return Type(); +} diff --git a/unittests/Sema/SemaFixture.h b/unittests/Sema/SemaFixture.h new file mode 100644 index 0000000000000..adb0ab40d5039 --- /dev/null +++ b/unittests/Sema/SemaFixture.h @@ -0,0 +1,68 @@ +//===--- SemaFixture.h - Helper for setting up Sema context -----*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/AST/ASTContext.h" +#include "swift/AST/DiagnosticEngine.h" +#include "swift/AST/Module.h" +#include "swift/AST/SourceFile.h" +#include "swift/AST/Type.h" +#include "swift/Basic/LangOptions.h" +#include "swift/Basic/Platform.h" +#include "swift/Basic/SourceManager.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Path.h" +#include "gtest/gtest.h" +#include + +namespace swift { +namespace unittest { + +class SemaTestBase : public ::testing::Test { +public: + LangOptions LangOpts; + TypeCheckerOptions TypeCheckerOpts; + SearchPathOptions SearchPathOpts; + ClangImporterOptions ClangImporterOpts; + SourceManager SourceMgr; + DiagnosticEngine Diags; + + SemaTestBase() : Diags(SourceMgr) { + LangOpts.Target = llvm::Triple(llvm::sys::getDefaultTargetTriple()); + + llvm::SmallString<128> libDir(SWIFTLIB_DIR); + llvm::sys::path::append(libDir, getPlatformNameForTriple(LangOpts.Target)); + + SearchPathOpts.RuntimeResourcePath = SWIFTLIB_DIR; + SearchPathOpts.RuntimeLibraryPaths.push_back(std::string(libDir.str())); + SearchPathOpts.RuntimeLibraryImportPaths.push_back( + std::string(libDir.str())); + } +}; + +/// Owns an ASTContext and the associated types. +class SemaTest : public SemaTestBase { + SourceFile *MainFile; + +public: + ASTContext &Context; + DeclContext *DC; + + SemaTest(); + +protected: + Type getStdlibType(StringRef name) const; +}; + +} // end namespace unittest +} // end namespace swift