Skip to content

Compiler crash doing weird things with primary associated types #61934

Open
@tominsam

Description

@tominsam

Describe the bug
I was doing something weird with a protocol with a primary type - I'm not even clear on if what I'm doing should work or not, but clearly it should not crash the compiler.

Steps To Reproduce

protocol Foo<FooType> {
    associatedtype FooType
    var value: FooType { get }
}

class FooImpl: Foo {
    typealias FooType = String
    
    let value: FooType
    init(value: FooType) {
        self.value = value
    }
}

class Bar<BarType> {
    let value: BarType
    
    init(foo: some Foo<BarType>) {
        self.value = foo.value
    }
}

let fooImpl = FooImpl(value: "abcde")
print("fooImpl.value is \(fooImpl.value)")

// This works - I can implicitly convey the primary type from FooImpl to the generic on Bar.
let barImpl = Bar(foo: fooImpl)
print("barImpl.value is \(barImpl.value)")

// But sometimes I want to do that without actually having the real type of foo. (Which probably
// isn't going to work but worth a try)
if let erasedFoo = fooImpl as? any Foo {
    // this line crashes compiler
    let barImpl2 = Bar(foo: erasedFoo)
}

This in pat.swift, then swift pat.swift will crash the compiler:

pat.swift:30:28: warning: conditional cast from 'FooImpl' to 'any Foo' always succeeds

if let erasedFoo = fooImpl as? any Foo {
                           ^
Stack dump:
0.  Program arguments: /Applications/Xcode-14.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -interpret pat.swift -Xllvm -aarch64-use-tbi -enable-objc-interop -stack-check -sdk /Applications/Xcode-14.1.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.0.sdk -color-diagnostics -new-driver-path /Applications/Xcode-14.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-driver -empty-abi-descriptor -resource-dir /Applications/Xcode-14.1.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -module-name pat -disable-clang-spi -target-sdk-version 13.0
1.  Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)
2.  Compiling with the current language version
3.  While evaluating request TypeCheckSourceFileRequest(source_file "pat.swift")
4.  While type-checking statement at [pat.swift:30:1 - line:33:1] RangeText="if let erasedFoo = fooImpl as? any Foo {
    // this line crashes compiler
    let barImpl2 = Bar(foo: erasedFoo)
"
5.  While type-checking statement at [pat.swift:30:1 - line:33:1] RangeText="if let erasedFoo = fooImpl as? any Foo {
    // this line crashes compiler
    let barImpl2 = Bar(foo: erasedFoo)
"
6.  While type-checking statement at [pat.swift:30:40 - line:33:1] RangeText="{
    // this line crashes compiler
    let barImpl2 = Bar(foo: erasedFoo)
"
7.  While type-checking declaration 0x13393a3b0 (at pat.swift:32:5)
8.  While evaluating request PatternBindingEntryRequest((unknown decl), 0, 0)
9.  While type-checking expression at [pat.swift:32:20 - line:32:38] RangeText="Bar(foo: erasedFoo"
10. While type-checking-target starting at pat.swift:32:20
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           0x00000001093635b0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001093625b4 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000109363c34 SignalHandler(int) + 344
3  libsystem_platform.dylib 0x000000018607f4a4 _sigtramp + 56
4  swift-frontend           0x0000000105489b38 (anonymous namespace)::ExprRewriter::coerceToType(swift::Expr*, swift::Type, swift::constraints::ConstraintLocatorBuilder, llvm::Optional<swift::Pattern*>) + 16868
5  swift-frontend           0x00000001054ac5e8 (anonymous namespace)::ExprRewriter::closeExistential(swift::Expr*&, swift::constraints::ConstraintLocatorBuilder, bool) + 340
6  swift-frontend           0x00000001054ac054 (anonymous namespace)::ExprRewriter::finishApply(swift::ApplyExpr*, swift::Type, swift::constraints::ConstraintLocatorBuilder, swift::constraints::ConstraintLocatorBuilder) + 14300
7  swift-frontend           0x00000001054aaef8 (anonymous namespace)::ExprRewriter::finishApply(swift::ApplyExpr*, swift::Type, swift::constraints::ConstraintLocatorBuilder, swift::constraints::ConstraintLocatorBuilder) + 9856
8  swift-frontend           0x00000001054b1784 (anonymous namespace)::ExprRewriter::visitApplyExpr(swift::ApplyExpr*) + 452
9  swift-frontend           0x000000010548cd58 (anonymous namespace)::ExprWalker::walkToExprPost(swift::Expr*) + 24
10 swift-frontend           0x0000000105482a98 (anonymous namespace)::ExprWalker::rewriteTarget(swift::constraints::SolutionApplicationTarget) + 408
11 swift-frontend           0x00000001054825ec swift::constraints::ConstraintSystem::applySolution(swift::constraints::Solution&, swift::constraints::SolutionApplicationTarget) + 5852
12 swift-frontend           0x00000001056ea104 swift::TypeChecker::typeCheckTarget(swift::constraints::SolutionApplicationTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 688
13 swift-frontend           0x00000001056e9de4 swift::TypeChecker::typeCheckExpression(swift::constraints::SolutionApplicationTarget&, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 400
14 swift-frontend           0x00000001056eb3dc swift::TypeChecker::typeCheckBinding(swift::Pattern*&, swift::Expr*&, swift::DeclContext*, swift::Type, swift::PatternBindingDecl*, unsigned int, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 452
15 swift-frontend           0x00000001056eb630 swift::TypeChecker::typeCheckPatternBinding(swift::PatternBindingDecl*, unsigned int, swift::Type, swift::OptionSet<swift::TypeCheckExprFlags, unsigned int>) + 340
16 swift-frontend           0x00000001057ccfcc swift::PatternBindingEntryRequest::evaluate(swift::Evaluator&, swift::PatternBindingDecl*, unsigned int, bool) const + 2152
17 swift-frontend           0x0000000105711e64 llvm::Expected<swift::PatternBindingEntryRequest::OutputType> swift::Evaluator::getResultUncached<swift::PatternBindingEntryRequest>(swift::PatternBindingEntryRequest const&) + 608
18 swift-frontend           0x0000000105701a88 swift::PatternBindingEntryRequest::OutputType swift::evaluateOrDefault<swift::PatternBindingEntryRequest>(swift::Evaluator&, swift::PatternBindingEntryRequest, swift::PatternBindingEntryRequest::OutputType) + 60
19 swift-frontend           0x000000010573ca74 swift::ASTVisitor<(anonymous namespace)::DeclChecker, void, void, void, void, void, void>::visit(swift::Decl*) + 6832
20 swift-frontend           0x0000000105737f50 (anonymous namespace)::DeclChecker::visit(swift::Decl*) + 400
21 swift-frontend           0x0000000105737db4 swift::TypeChecker::typeCheckDecl(swift::Decl*, bool) + 204
22 swift-frontend           0x00000001057c7a64 swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 328
23 swift-frontend           0x00000001057c7890 bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::Stmt>(swift::Stmt*&) + 300
24 swift-frontend           0x00000001057c80f4 swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 2008
25 swift-frontend           0x00000001057c7890 bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::Stmt>(swift::Stmt*&) + 300
26 swift-frontend           0x00000001057c4488 (anonymous namespace)::StmtChecker::typeCheckASTNode(swift::ASTNode&) + 80
27 swift-frontend           0x00000001057c7a64 swift::ASTVisitor<(anonymous namespace)::StmtChecker, void, swift::Stmt*, void, void, void, void>::visit(swift::Stmt*) + 328
28 swift-frontend           0x00000001057c6540 bool (anonymous namespace)::StmtChecker::typeCheckStmt<swift::BraceStmt>(swift::BraceStmt*&) + 300
29 swift-frontend           0x00000001057c6640 swift::TypeChecker::typeCheckTopLevelCodeDecl(swift::TopLevelCodeDecl*) + 100
30 swift-frontend           0x0000000105801ce0 swift::TypeCheckSourceFileRequest::evaluate(swift::Evaluator&, swift::SourceFile*) const + 584
31 swift-frontend           0x0000000105804960 llvm::Expected<swift::TypeCheckSourceFileRequest::OutputType> swift::Evaluator::getResultUncached<swift::TypeCheckSourceFileRequest>(swift::TypeCheckSourceFileRequest const&) + 576
32 swift-frontend           0x0000000105801a44 swift::performTypeChecking(swift::SourceFile&) + 120
33 swift-frontend           0x0000000104a22b8c bool llvm::function_ref<bool (swift::SourceFile&)>::callback_fn<swift::CompilerInstance::performSema()::$_6>(long, swift::SourceFile&) + 16
34 swift-frontend           0x0000000104a1d300 swift::CompilerInstance::forEachFileToTypeCheck(llvm::function_ref<bool (swift::SourceFile&)>) + 288
35 swift-frontend           0x0000000104a1d1a4 swift::CompilerInstance::performSema() + 148
36 swift-frontend           0x00000001049b02ac swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4364
37 swift-frontend           0x00000001049513c0 swift::mainEntry(int, char const**) + 3940
38 dyld                     0x000000010be1908c start + 520
Segmentation fault: 11

Expected behavior
Compiler shouldn't crash

Environment (please fill out the following information)
Darwin XW017K2PM4 21.6.0 Darwin Kernel Version 21.6.0: Thu Sep 29 20:13:56 PDT 2022; root:xnu-8020.240.7~1/RELEASE_ARM64_T6000 arm64
swift-driver version: 1.62.15 Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)

Metadata

Metadata

Labels

assertion failureBug → crash: An assertion failurebugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwareexistentialsFeature: values of types like `any Collection`, `Any` and `AnyObject`; type-erased valuesexpressionsFeature: expressionsgeneric constraintsFeature → generics: generic constraintsgenericsFeature: generic declarations and typesimplicit existential openingFeature → existentials: implicit opening of existentials when passed to parameters of generic typeswift 6.1type checkerArea → compiler: Semantic analysistypesFeature: types

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions