swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.39k stars 10.35k forks source link

Passing parameter pack results in ICE #66392

Open keith opened 1 year ago

keith commented 1 year ago

With this code:

class Store<State> {
    var currentState: State { fatalError() }
}

class CompositeStore<CompositeState, each State, OriginalState>: Store<CompositeState> {
    let store: (repeat Store<each State>)
    let combine: ((repeat (each State)) -> CompositeState)

    override var currentState: CompositeState {
        return self.combine(repeat (each store).currentState)
    }

    func foo(_ all: (repeat Store<each State>)) {}

    init(store1: (repeat Store<each State>),
         combine: @escaping (repeat (each State)) -> CompositeState)
    {
        self.store = store1
        self.combine = combine

        foo(store1)
   }
}

The attempted call to foo(store1) results in a crash:

error: compile command failed due to signal 6 (use -v to see invocation)
Assertion failed: (!tupleTy.containsPackExpansionType() && "can't extract elements from tuples containing pack expansions " "right now"), function extractElements, file RValue.cpp, line 709.
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.      Program arguments: /Users/ksmiley/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-06-05-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /tmp/foo.swift -target arm64-apple-macosx13.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode-15.0.0-beta1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -color-diagnostics -new-driver-path /Users/ksmiley/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-06-05-a.xctoolchain/usr/bin/swift-driver -disable-availability-checking -empty-abi-descriptor -plugin-path /Users/ksmiley/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-06-05-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Users/ksmiley/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-06-05-a.xctoolchain/usr/local/lib/swift/host/plugins -resource-dir /Users/ksmiley/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-06-05-a.xctoolchain/usr/lib/swift -module-name foo -target-sdk-version 14.0 -target-sdk-name macosx14.0 -o /var/folders/gj/wf3swl0x215b2sq1qy84kzkm0000gn/T/TemporaryDirectory.03bCcE/foo-1.o
1.      Apple Swift version 5.9-dev (LLVM 4a3b38183d7bb09, Swift 44a40979e52be8e)
2.      Compiling with the current language version
3.      While evaluating request ASTLoweringRequest(Lowering AST to SIL for file "/tmp/foo.swift")
4.      While silgen constructor initializer SIL function "@$s3foo14CompositeStoreC6store17combineACyxq_q_Qp_QPq0_GAA0C0Cyq_Gq_Qp_t_xq_q_Qpctcfc".
 for 'init(store1:combine:)' (at /tmp/foo.swift:15:5)
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           0x00000001097ddf30 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001097dd2d4 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x00000001097de570 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x00000001a84eaa24 _sigtramp + 56
4  libsystem_pthread.dylib  0x00000001a84bbc28 pthread_kill + 288
5  libsystem_c.dylib        0x00000001a83c9ae8 abort + 180
6  libsystem_c.dylib        0x00000001a83c8e44 err + 0
7  swift-frontend           0x00000001098b4738 swift::Lowering::RValue::extractElements(llvm::SmallVectorImpl<swift::Lowering::RValue>&) && (.cold.3) + 0
8  swift-frontend           0x000000010503a528 swift::Lowering::RValue::extractElements(llvm::SmallVectorImpl<swift::Lowering::RValue>&) && + 436
9  swift-frontend           0x00000001050604e4 (anonymous namespace)::ArgEmitter::emitExpanded(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 284
10 swift-frontend           0x00000001050607ec (anonymous namespace)::ArgEmitter::emitExpanded(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 1060
11 swift-frontend           0x000000010505ee70 (anonymous namespace)::ArgEmitter::emit(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 160
12 swift-frontend           0x0000000105051a10 (anonymous namespace)::ArgEmitter::emitSingleArg(swift::Lowering::ArgumentSource&&, swift::Lowering::AbstractionPattern) + 400
13 swift-frontend           0x000000010505e720 (anonymous namespace)::ArgEmitter::emitPreparedArgs(swift::Lowering::PreparedArguments&&, swift::Lowering::AbstractionPattern) + 160
14 swift-frontend           0x0000000105068928 (anonymous namespace)::CallSite::emit(swift::Lowering::SILGenFunction&, swift::Lowering::AbstractionPattern, swift::CanTypeWrapper<swift::SILFunctionType>, (anonymous namespace)::ParamLowering&, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, llvm::SmallVectorImpl<(anonymous namespace)::DelayedArgument>&, swift::ForeignInfo const&) && + 536
15 swift-frontend           0x00000001050682a8 (anonymous namespace)::CallEmission::emitArgumentsForNormalApply(swift::Lowering::AbstractionPattern, swift::CanTypeWrapper<swift::SILFunctionType>, swift::ForeignInfo const&, llvm::SmallVectorImpl<swift::Lowering::ManagedValue>&, llvm::Optional<swift::SILLocation>&) + 1112
16 swift-frontend           0x0000000105055098 (anonymous namespace)::CallEmission::apply(swift::Lowering::SGFContext) + 2288
17 swift-frontend           0x00000001050534c8 swift::Lowering::SILGenFunction::emitApplyExpr(swift::ApplyExpr*, swift::Lowering::SGFContext) + 1728
18 swift-frontend           0x00000001050a2690 swift::Lowering::SILGenFunction::emitIgnoredExpr(swift::Expr*) + 944
19 swift-frontend           0x000000010510dd8c swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 4156
20 swift-frontend           0x000000010510cd44 swift::Lowering::SILGenFunction::emitStmt(swift::Stmt*) + 24
21 swift-frontend           0x0000000105084cec swift::Lowering::SILGenFunction::emitClassConstructorInitializer(swift::ConstructorDecl*) + 2656
22 swift-frontend           0x0000000105043094 swift::Lowering::SILGenModule::emitFunctionDefinition(swift::SILDeclRef, swift::SILFunction*) + 3348
23 swift-frontend           0x0000000105045940 emitOrDelayFunction(swift::Lowering::SILGenModule&, swift::SILDeclRef) + 200
24 swift-frontend           0x0000000105045c78 swift::Lowering::SILGenModule::emitConstructor(swift::ConstructorDecl*) + 372
25 swift-frontend           0x000000010511ae58 swift::ASTVisitor<(anonymous namespace)::SILGenType, void, void, void, void, void, void>::visit(swift::Decl*) + 356
26 swift-frontend           0x000000010511810c (anonymous namespace)::SILGenType::emitType() + 156
27 swift-frontend           0x0000000105118064 swift::Lowering::SILGenModule::visitNominalTypeDecl(swift::NominalTypeDecl*) + 24
28 swift-frontend           0x00000001050478e0 swift::ASTLoweringRequest::evaluate(swift::Evaluator&, swift::ASTLoweringDescriptor) const + 1000
29 swift-frontend           0x000000010510c7e0 swift::SimpleRequest<swift::ASTLoweringRequest, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>> (swift::ASTLoweringDescriptor), (swift::RequestFlags)9>::evaluateRequest(swift::ASTLoweringRequest const&, swift::Evaluator&) + 148
30 swift-frontend           0x000000010504b60c llvm::Expected<swift::ASTLoweringRequest::OutputType> swift::Evaluator::getResultUncached<swift::ASTLoweringRequest>(swift::ASTLoweringRequest const&) + 396
31 swift-frontend           0x0000000105048b94 swift::performASTLowering(swift::FileUnit&, swift::Lowering::TypeConverter&, swift::SILOptions const&, swift::IRGenOptions const*) + 100
32 swift-frontend           0x0000000104b21350 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 524
33 swift-frontend           0x0000000104b3056c withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
34 swift-frontend           0x0000000104b23e5c performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 724
35 swift-frontend           0x0000000104b22df0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2456
36 swift-frontend           0x000000010496d524 swift::mainEntry(int, char const**) + 2144
37 dyld                     0x00000001a8163f28 start + 2236

Steps to reproduce

xcrun --toolchain org.swift.59202306051a swiftc /tmp/foo.swift -Xfrontend -disable-availability-checking

Environment

simanerush commented 10 months ago

This doesn't crash anymore:

error: 'each' cannot be applied to non-pack type 'repeat each State'
        return self.combine(repeat (each store).currentState)
                            ^
error: pack expansion requires that 'repeat each State' and 'each State' have the same shape
        return self.combine(repeat (each store).currentState)
                            ^
error: type of expression is ambiguous without a type annotation
        self.combine = combine
        ~~~~~~~~~~~~~^~~~~~~~~
AnthonyLatsis commented 10 months ago

With the crash out of the way this looks very much like a manifestation of #68369.

struct CompositeStore<each State> {
  let combine: (repeat each State) -> Void

  func foo(store: repeat each State) {
    _ = self.combine(repeat each store) //  error: type of expression is ambiguous without a type annotation [type_of_expression_is_ambiguous]
  }

  init() {}
}
AnthonyLatsis commented 7 months ago

Fixing the Sema error exposed the crash again.

AnthonyLatsis commented 7 months ago

FYI this seems like the minimal test case that triggers this assertion:

func test1<each T>(ts: (repeat each T)) {}
func test2<each T>(ts: (repeat each T)) {
  test1(ts: ts)
}
vanvoorden commented 6 months ago
func test1<each T>(ts: (repeat each T)) {}
func test2<each T>(ts: (repeat each T)) {
  test1(ts: ts)
}

@AnthonyLatsis Hmm… this is blocking me (for now). Can you think of any legit workarounds to build that example on 5.10?

func test1<each T>(ts: (repeat each T)) {}
func test2<each T>(ts: (repeat each T)) {
  test1(ts: (repeat each ts))
}

This unblocks me on compiling… but then I get a Pack expansion count type should be a pack fatal error when I run that code in a similar function in my app.

AnthonyLatsis commented 5 months ago

Can you think of any legit workarounds to build that example on 5.10?

You could try to avoid passing around abstract tuples:

func test1<each T>(ts: repeat each T) {}
func test2<each T>(ts: (repeat each T)) {
  test1(ts: repeat each ts)
}
vanvoorden commented 5 months ago

You could try to avoid passing around abstract tuples:

@AnthonyLatsis Hmm… I try this workaround and I see another Pack expansion count type should be a pack fatal error at runtime.

AnthonyLatsis commented 5 months ago

Did you get rid of all abstract tuple parameters? If so, and your code still hits this runtime fatal error, please report it.

vanvoorden commented 5 months ago

@AnthonyLatsis I can try to take a closer look. This repro isn't super clean because I have a few different places that tuple is being passed around from. FWIW… my runtime error is firing from the Observation stack of all places (I have an Observable class instance that is generic across a parameter pack).

vanvoorden commented 5 months ago
import Observation

@Observable final class Repeater<each Parameter, Output> {
  let parameter: (repeat each Parameter)
  var output: Output

  init(
    parameter: (repeat each Parameter),
    output: Output
  ) {
    self.parameter = parameter
    self.output = output
  }
}

let repeater = Repeater(parameter: (1, 2, 3), output: 4)
repeater.output = 5

/*
#0  0x00000001a0e4b52c in (anonymous namespace)::DecodedMetadataBuilder::beginPackExpansion(swift::MetadataOrPack) ()
#1  0x00000001a0e41c04 in swift::Demangle::__runtime::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::__runtime::Node*, unsigned int, bool) ()
#2  0x00000001a0e45c3c in swift::Demangle::__runtime::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeGenericArgs(swift::Demangle::__runtime::Node*, unsigned int, __swift::__runtime::llvm::SmallVectorImpl<swift::MetadataOrPack>&) ()
#3  0x00000001a0e41da4 in swift::Demangle::__runtime::TypeDecoder<(anonymous namespace)::DecodedMetadataBuilder>::decodeMangledType(swift::Demangle::__runtime::Node*, unsigned int, bool) ()
#4  0x00000001a0e3e55c in swift_getTypeByMangledNodeImpl(swift::MetadataRequest, swift::Demangle::__runtime::Demangler&, swift::Demangle::__runtime::Node*, void const* const*, std::__1::function<void const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) ()
#5  0x00000001a0e3e100 in swift_getTypeByMangledNode ()
#6  0x00000001a0e3ebb0 in swift_getTypeByMangledNameImpl(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function<void const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) ()
#7  0x00000001a0e38a84 in swift_getTypeByMangledName ()
#8  0x00000001a0e38578 in swift_getTypeByMangledNameInEnvironment ()
#9  0x00000001a0bc6e1c in _resolveKeyPathGenericArgReference(_:genericEnvironment:arguments:) ()
#10  0x00000001a0bc74f4 in specialized _walkKeyPathPattern<τ_0_0>(_:walker:) ()
#11  0x00000001a0bc6928 in _getKeyPathClassAndInstanceSizeFromPattern(_:_:) ()
#12  0x00000001a0bc66d4 in _swift_getKeyPath(pattern:arguments:) ()
#13  0x00000001000025b8 in Repeater.output.setter at /var/folders/1j/0r1s_v0n4bn200kt9nkm9j5w0000gn/T/swift-generated-sources/@__swiftmacro_12RepeaterDemo0A0C6output18ObservationTrackedfMa_.swift:11
#14  0x000000010000242c in main at /Users/rick/Desktop/RepeaterDemo/Sources/main.swift:17
#15  0x0000000190a1a0e0 in start ()
*/

@AnthonyLatsis This seems to be triggering a runtime error for me coming from 5.10 in a simple executable target. I am unable to build that for 6.0 because of a compiler crash.

In my case I needed to retain an abstract tuple because I was saving it as a stored variable and I wasn't able to compile without those round braces.

vanvoorden commented 4 months ago

@AnthonyLatsis I opened https://github.com/apple/swift/issues/73690 for tracking the Observation crash.

stephencelis commented 3 months ago

@AnthonyLatsis Hmm… I try this workaround and I see another Pack expansion count type should be a pack fatal error at runtime.

I just got this same fatal error and this issue is the only instance of it I could find :)

I'm having a hard time reducing a case, but it's related to returning a parameter pack generic type (e.g. MyType<each Value>) as an opaque some type from a function.

vanvoorden commented 3 months ago

I'm having a hard time reducing a case, but it's related to returning a parameter pack generic type (e.g. MyType) as an opaque some type from a function.

@stephencelis Hmm… if it's a 5.10 runtime crash it might be another version of https://github.com/swiftlang/swift/issues/73690 (which is from pairing variadic types with KeyPaths). That one is actually a compiler crash for me on 6.0.

The other possibility is this is another version of https://github.com/swiftlang/swift/issues/61357.

stephencelis commented 3 months ago

@vanvoorden This crash was on the Xcode 16 beta, and I don't think key paths are involved, just a result builder that was using a parameter pack for a variadic buildBlock and returning a parameter packed type as a some type. Simple cases built and ran fine, but more complex cases would lead to the above fatal error. #61357 also doesn't seem parameter pack-related. Let me know if I can help, though!

stephencelis commented 3 months ago

(FWIW I can probably share a complex code sample with the issue by reverting our workaround of not using some types, but I find a lot of the non-reduced cases I share here sit around.)