Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when accessing generic property wrapper's some type-using wrappedValue #78405

Open
lukaskollmer opened this issue Jan 2, 2025 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels

Comments

@lukaskollmer
Copy link

lukaskollmer commented Jan 2, 2025

Description

The program below crashes the compiler.

Changing the type of wrappedValue to a non-some type, or removing the where T: P constraint from the property wrapper type makes it work fine.

Additionally, it seems like the crash is caused by the fact that the program is accessing a property on the wrappedValue. If we change hmmm to return elements instead of elements.count (and adjust its type accordingly), the program compiles without issues.

Alternatively, removing the where Self: Base constraint from the P protocol also makes it compile.

Reproduction

class Base {}
class Derived: Base {}

protocol P: Base {}
extension Derived: P {}


@propertyWrapper
struct Query<T: P> {
    var wrappedValue: some RandomAccessCollection<T> {
        Array<T>()
    }
}


struct S {
    @Query<Derived>
    private var elements
    
    var hmmm: Int {
        elements.count
    }
}

Stack dump

1.	Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
2.	Compiling with the current language version
3.	While evaluating request ASTLoweringRequest(Lowering AST to SIL for module test_2025_01_02)
4.	While silgen emitFunction SIL function "@$s15test_2025_01_021SV5countSivg".
 for getter for count (at /Users/lukas/Developer/test/test_2025-01-02/test_2025-01-02/main.swift:30:9)
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           0x0000000105e26a9c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000105e24cf0 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105e27068 SignalHandler(int) + 292
3  libsystem_platform.dylib 0x000000019179a584 _sigtramp + 56
4  libsystem_pthread.dylib  0x0000000191769c20 pthread_kill + 288
5  libsystem_c.dylib        0x0000000191676a30 abort + 180
6  swift-frontend           0x0000000100b87ce8 createDispatchingDiagnosticConsumerIfNeeded(swift::FrontendInputsAndOutputs const&, llvm::function_ref<std::__1::unique_ptr<swift::DiagnosticConsumer, std::__1::default_delete<swift::DiagnosticConsumer>> (swift::InputFile const&)>) + 0
7  swift-frontend           0x0000000105d96820 llvm::report_fatal_error(llvm::Twine const&, bool) + 280
8  swift-frontend           0x0000000105d96708 llvm::report_fatal_error(llvm::Twine const&, bool) + 0
9  swift-frontend           0x00000001012a8094 std::__1::deque<llvm::Function*, std::__1::allocator<llvm::Function*>>::push_back(llvm::Function* const&) + 0
10 swift-frontend           0x00000001012a7ef0 swift::Lowering::SILGenModule::useConformance(swift::ProtocolConformanceRef) + 244
11 swift-frontend           0x00000001011eb1d8 swift::Lowering::SILGenModule::postEmitFunction(swift::SILDeclRef, swift::SILFunction*) + 96
12 swift-frontend           0x00000001011eab44 swift::Lowering::SILGenModule::emitFunctionDefinition(swift::SILDeclRef, swift::SILFunction*) + 8460
13 swift-frontend           0x00000001011eb3bc swift::Lowering::SILGenModule::emitOrDelayFunction(swift::SILDeclRef) + 216
14 swift-frontend           0x00000001011e89ec swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 364
15 swift-frontend           0x000000010133ec8c (anonymous namespace)::SILGenType::visitFuncDecl(swift::FuncDecl*) + 32
16 swift-frontend           0x000000010133ee78 (anonymous namespace)::SILGenType::visitAbstractStorageDecl(swift::AbstractStorageDecl*) + 248
17 swift-frontend           0x000000010133ec08 (anonymous namespace)::SILGenType::visitVarDecl(swift::VarDecl*) + 456
18 swift-frontend           0x000000010133b290 (anonymous namespace)::SILGenType::emitType() + 516
19 swift-frontend           0x00000001011e8624 swift::ASTVisitor<swift::Lowering::SILGenModule, void, void, void, void, void, void>::visit(swift::Decl*) + 104
20 swift-frontend           0x00000001011ef038 swift::ASTLoweringRequest::evaluate(swift::Evaluator&, swift::ASTLoweringDescriptor) const + 1804
21 swift-frontend           0x000000010132592c 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&) + 196
22 swift-frontend           0x00000001011f3f14 swift::ASTLoweringRequest::OutputType swift::Evaluator::getResultUncached<swift::ASTLoweringRequest, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()>(swift::ASTLoweringRequest const&, swift::ASTLoweringRequest::OutputType swift::evaluateOrFatal<swift::ASTLoweringRequest>(swift::Evaluator&, swift::ASTLoweringRequest)::'lambda'()) + 528
23 swift-frontend           0x00000001007ce304 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 2828
24 swift-frontend           0x00000001007d0e88 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1684
25 swift-frontend           0x00000001007cfbb4 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3572
26 swift-frontend           0x0000000100756a5c swift::mainEntry(int, char const**) + 3680
27 dyld                     0x00000001913df154 start + 2476

Expected behavior

the code should compile

Environment

swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx14.0

Additional information

No response

@lukaskollmer lukaskollmer added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels labels Jan 2, 2025
@Rajveer100
Copy link
Contributor

Rajveer100 commented Jan 5, 2025

@eeckstein
I tried to debug this issue:

void SILGenModule::useConformance(ProtocolConformanceRef conformanceRef) {
  // If the conformance is invalid, crash deterministically even in noassert
  // builds.
  if (conformanceRef.isInvalid()) {
    // When lazy type checking is enabled, a conformance may only be diagnosed
    // as invalid during SILGen. Ignore it instead of asserting.
    auto &ctx = getASTContext();
    if (ctx.TypeCheckerOpts.EnableLazyTypecheck && ctx.hadError())
      return;

    llvm::report_fatal_error("Invalid conformance in type-checked AST");
  }

Seems like the underlying structure is a union with this form:

typedef llvm::PointerUnion<ProtocolDecl *, ProtocolConformance *, PackConformance *> UnionType;

In the Xcode debugger, this seems to be empty (char[8] = ""). Also, if I remove the condition from the protocol:

protocol P {}

Even though the code compiles as mentioned in the description of the issue, this debug statement shows there is an invalid conformance:

bool PackConformance::isInvalid() const {
  return llvm::any_of(getPatternConformances(),
                      [&](const auto ref) {
    if (ref.isInvalid())
      llvm::errs() << "An invalid conformance exists." << "\n";
    return ref.isInvalid();
  });
}
../build/Ninja-RelWithDebInfoAssert/swift-macosx-arm64/bin/swiftc -sdk /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk debug.swift
An invalid conformance exists.
An invalid conformance exists.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

2 participants