Skip to content

Compiler assertion failure when importing identically-named classes into a unit test. #67799

@fibrechannelscsi

Description

@fibrechannelscsi

Description
This reproducer requires seven files, including a main Package.swift file, and two Package.swift files for internal packages.

Steps to reproduce
The following code crashes the compiler with an assertion failure when an attempt is made to compile a unit test. The assertion failure is:
Assertion failed: (false && "locator could not be simplified to anchor"), function diagnoseAmbiguity, file ConstraintSystem.cpp, line 5549.

Note that, for the unit test, we are attempting to import class S from one package with a @testable directive, and class S from another package without a @testable directive.

The file listing looks like this:

./Package.swift ./Sources/InternalPackageA/Package.swift ./Sources/InternalPackageA/Sources/User.swift ./Sources/InternalPackageB/Package.swift ./Sources/InternalPackageB/Sources/User.swift ./Sources/ReproducerServer/A.swift ./Tests/unitTests/unitTests.swift 

Note that ./Sources/ReproducerServer/A.swift is intentionally left blank.

Listing for ./Package.swift:

// swift-tools-version: 5.6 import PackageDescription let package = Package( name: "Reproducer", products: [.library(name: "Reproducer", targets: ["ReproducerServer"])], dependencies: [.package(name: "InternalPackageA", path: "./Sources/InternalPackageA"), .package(name: "InternalPackageB", path: "./Sources/InternalPackageB")], targets: [.target(name: "ReproducerServer", dependencies: [.product(name: "InternalPackageA", package: "InternalPackageA"), .product(name: "InternalPackageB", package: "InternalPackageB")]), .testTarget(name: "unitTests",dependencies: [])] )

Listing for ./Sources/InternalPackageA/Package.swift:

// swift-tools-version: 5.6 import PackageDescription; let package = Package(name: "InternalPackageA", products: [.library(name: "InternalPackageA",targets: ["InternalPackageA"])], targets: [.target(name: "InternalPackageA", path: "Sources")])

Listing for ./Sources/InternalPackageB/Package.swift:

// swift-tools-version: 5.6 import PackageDescription; let package = Package(name: "InternalPackageB", products: [.library(name: "InternalPackageB",targets: ["InternalPackageB"])], targets: [.target(name: "InternalPackageB", path: "Sources")])

Listing for ./Sources/InternalPackageA/Sources/User.swift and ./Sources/InternalPackageB/Sources/User.swift (these are identical):

import Foundation; public final class S<T> {private var t: T!; public init(t: T) {self.t = t}}

Listing for ./Tests/unitTests/unitTests.swift:

import XCTest; import InternalPackageA; @testable import InternalPackageB; final class A: XCTestCase{func t() throws{_ = S<Int>(t: 0)}}

Expected behavior
The compiler should provide an error message indicating that there is an ambiguous use of the class S. (If, instead, the compiler ought to prefer a @testable import inside a unit test over a non-@testable import, then a corresponding warning message should be provided).

Environment

  • Swift compiler version info: Toolchain 2023-07-23a
  • Xcode version info: 14.2
  • Deployment target: M1

Additional context
The standard Xcode 14.2 toolchain will generate a different error message:

./Tests/unitTests/unitTests.swift:1:122: error: cannot specialize a non-generic definition import XCTest; import InternalPackageA; @testable import InternalPackageB; final class A: XCTestCase{func t() throws{_ = S<Int>(t: 0)}} ^ ./Tests/unitTests/unitTests.swift:1:123: note: while parsing this '<' as a type parameter bracket import XCTest; import InternalPackageA; @testable import InternalPackageB; final class A: XCTestCase{func t() throws{_ = S<Int>(t: 0)}} 

If opening this project in Xcode for the first time, and an attempt is made to build or run the unit test, it is possible that the following error message will be generated:

./Tests/unitTests/unitTests.swift:1:23: error: no such module 'InternalPackageA' import XCTest; import InternalPackageA; @testable import InternalPackageB; final class A: XCTestCase{func t() throws{_ = S<Int>(t: 0)}} 

Try to build or run the unit test again to generate the initial error message.

Full stack trace:

1.	Apple Swift version 5.9-dev (LLVM 9b562f55c38e378, Swift b4ee68bd37c4f7d) 2.	Compiling with the current language version 3.	While evaluating request TypeCheckSourceFileRequest(source_file "/Users/user/a/600/Tests/unitTests/unitTests.swift") 4.	While evaluating request TypeCheckFunctionBodyRequest(unitTests.(file).A.t()@/Users/user/a/600/Tests/unitTests/unitTests.swift:1:107) 5.	While type-checking statement at [/Users/user/a/600/Tests/unitTests/unitTests.swift:1:117 - line:1:134] RangeText="{_ = S<Int>(t: 0)" 6.	While type-checking expression at [/Users/user/a/600/Tests/unitTests/unitTests.swift:1:118 - line:1:133] RangeText="_ = S<Int>(t: 0" 7.	While type-checking-target starting at /Users/user/a/600/Tests/unitTests/unitTests.swift:1:118 Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): 0 swift-frontend 0x0000000105e270bc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56 1 swift-frontend 0x0000000105e26460 llvm::sys::RunSignalHandlers() + 112 2 swift-frontend 0x0000000105e276fc SignalHandler(int) + 304 3 libsystem_platform.dylib 0x0000000183166a24 _sigtramp + 56 4 libsystem_pthread.dylib 0x0000000183137c28 pthread_kill + 288 5 libsystem_c.dylib 0x0000000183045ae8 abort + 180 6 libsystem_c.dylib 0x0000000183044e44 err + 0 7 swift-frontend 0x00000001061dd234 swift::constraints::ConstraintSystem::diagnoseAmbiguity(llvm::ArrayRef<swift::constraints::Solution>) (.cold.2) + 0 8 swift-frontend 0x0000000101fc30fc swift::constraints::ConstraintSystem::diagnoseAmbiguity(llvm::ArrayRef<swift::constraints::Solution>) + 2776 9 swift-frontend 0x0000000101fbd6a8 swift::constraints::ConstraintSystem::salvage() + 1388 10 swift-frontend 0x0000000101f23bd4 swift::constraints::ConstraintSystem::solve(swift::constraints::SyntacticElementTarget&, swift::FreeTypeVariableBinding) + 704 11 swift-frontend 0x0000000102091764 swift::TypeChecker::typeCheckTarget(swift::constraints::SyntacticElementTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 320 12 swift-frontend 0x00000001020915cc swift::TypeChecker::typeCheckExpression(swift::constraints::SyntacticElementTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 184 13 swift-frontend 0x000000010209148c swift::TypeChecker::typeCheckExpression(swift::Expr*&, swift::DeclContext*, swift::constraints::ContextualTypeInfo, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 84 14 swift-frontend 0x000000010216c454 (anonymous namespace)::StmtChecker::typeCheckASTNode(swift::ASTNode&) + 268 15 swift-frontend 0x000000010216f2bc swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 328 16 swift-frontend 0x000000010216d978 bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::BraceStmt>(swift::BraceStmt*&) + 136 17 swift-frontend 0x000000010216d05c swift::TypeCheckFunctionBodyRequest::evaluate(swift::Evaluator&, swift::AbstractFunctionDecl*) const + 1028 18 swift-frontend 0x000000010251b184 llvm::Expected<swift::TypeCheckFunctionBodyRequest::OutputType> swift::Evaluator::getResultUncached<swift::TypeCheckFunctionBodyRequest>(swift::TypeCheckFunctionBodyRequest const&) + 392 19 swift-frontend 0x000000010251af20 llvm::Expected<swift::TypeCheckFunctionBodyRequest::OutputType> swift::Evaluator::getResultCached<swift::TypeCheckFunctionBodyRequest, (void*)0>(swift::TypeCheckFunctionBodyRequest const&) + 120 20 swift-frontend 0x0000000102462e8c swift::TypeCheckFunctionBodyRequest::OutputType swift::evaluateOrDefault<swift::TypeCheckFunctionBodyRequest>(swift::Evaluator&, swift::TypeCheckFunctionBodyRequest, swift::TypeCheckFunctionBodyRequest::OutputType) + 52 21 swift-frontend 0x00000001021a5eb4 swift::TypeCheckSourceFileRequest::evaluate(swift::Evaluator&, swift::SourceFile*) const + 340 22 swift-frontend 0x00000001021a81f4 llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultUncached<swift::TypeCheckSourceFileRequest>(swift::TypeCheckSourceFileRequest const&) + 388 23 swift-frontend 0x00000001021a7f84 llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultCached<swift::TypeCheckSourceFileRequest, (void*)0>(swift::TypeCheckSourceFileRequest const&) + 84 24 swift-frontend 0x00000001021a5c78 swift::TypeCheckSourceFileRequest::OutputType swift::evaluateOrDefault<swift::TypeCheckSourceFileRequest>(swift::Evaluator&, swift::TypeCheckSourceFileRequest, swift::TypeCheckSourceFileRequest::OutputType) + 44 25 swift-frontend 0x00000001012205b4 bool llvm::function_ref<bool (swift::SourceFile&)>::callback_fn<swift::CompilerInstance::performSema()::$_7>(long, swift::SourceFile&) + 16 26 swift-frontend 0x000000010121a440 swift::CompilerInstance::forEachFileToTypeCheck(llvm::function_ref<bool (swift::SourceFile&)>) + 76 27 swift-frontend 0x000000010121a3d4 swift::CompilerInstance::performSema() + 76 28 swift-frontend 0x0000000101058d98 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 60 29 swift-frontend 0x000000010104c5d0 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 740 30 swift-frontend 0x000000010104b530 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2504 31 swift-frontend 0x0000000100e92760 swift::mainEntry(int, char const**) + 2144 32 dyld 0x0000000182ddff28 start + 2236 

Metadata

Metadata

Assignees

No one assigned

    Labels

    assertion failureBug → crash: An assertion failurebugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselftype checkerArea → compiler: Semantic analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions