Skip to content

Combination of ~Copyable + optional chaining + assignment crashes the compiler. #80261

Open
@YOCKOW

Description

@YOCKOW

Description

The compiler crashes when you try to assign a value to a property of optional-chained non-copyable type.

Reproduction

struct NonCopyable: ~Copyable {
  var value: Int = 0
}

var nc: NonCopyable? = NonCopyable()
nc?.value = 1

Stack dump

SIL verification failed: instruction isn't dominated by its operand: properlyDominates(valueI, I)
Verifying instruction:
     %18 = unchecked_take_enum_data_addr %9 : $*Optional<NonCopyable>, #Optional.some!enumelt // users: %17, %21
->   destroy_addr %18 : $*NonCopyable             // id: %17
In function:
// main
// Isolation: unspecified
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
  alloc_global @$s4main2ncAA11NonCopyableVSgvp    // id: %2
  %3 = global_addr @$s4main2ncAA11NonCopyableVSgvp : $*Optional<NonCopyable> // users: %9, %8
  %4 = metatype $@thin NonCopyable.Type           // user: %6
  // function_ref NonCopyable.init()
  %5 = function_ref @$s4main11NonCopyableVACycfC : $@convention(method) (@thin NonCopyable.Type) -> @owned NonCopyable // user: %6
  %6 = apply %5(%4) : $@convention(method) (@thin NonCopyable.Type) -> @owned NonCopyable // user: %7
  %7 = enum $Optional<NonCopyable>, #Optional.some!enumelt, %6 // user: %8
  store %7 to [init] %3                           // id: %8
  %9 = begin_access [modify] [dynamic] %3         // users: %12, %18, %23, %14
  %10 = integer_literal $Builtin.Int1, -1         // user: %12
  %11 = integer_literal $Builtin.Int1, 0          // user: %12
  %12 = select_enum_addr %9, case #Optional.some!enumelt: %10, default %11 : $Builtin.Int1 // user: %13
  cond_br %12, bb2, bb1                           // id: %13

bb1:                                              // Preds: bb0
  end_access %9                                   // id: %14
  %15 = enum $Optional<()>, #Optional.none!enumelt // user: %16
  br bb3(%15)                                     // id: %16

bb2:                                              // Preds: bb0
  destroy_addr %18                                // id: %17
  %18 = unchecked_take_enum_data_addr %9, #Optional.some!enumelt // users: %17, %21
  %19 = integer_literal $Builtin.Int64, 1         // user: %20
  %20 = struct $Int (%19)                         // user: %22
  %21 = struct_element_addr %18, #NonCopyable.value // user: %22
  store %20 to [trivial] %21                      // id: %22
  end_access %9                                   // id: %23
  %24 = tuple ()                                  // user: %25
  %25 = enum $Optional<()>, #Optional.some!enumelt, %24 // user: %26
  br bb3(%25)                                     // id: %26

bb3(%27 : $Optional<()>):                         // Preds: bb1 bb2
  %28 = integer_literal $Builtin.Int32, 0         // user: %29
  %29 = struct $Int32 (%28)                       // user: %30
  return %29                                      // id: %30
} // end sil function 'main'

Stack dump:
0.	Program arguments: /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a.xctoolchain/usr/bin/swift-frontend -frontend -interpret _noncopyable-optional_chaining-assignment_.swift -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -color-diagnostics -empty-abi-descriptor -resource-dir /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a.xctoolchain/usr/lib/swift -no-auto-bridging-header-chaining -module-name main -in-process-plugin-server-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a.xctoolchain/usr/lib/swift/host/libSwiftInProcPluginServer.dylib -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2025-03-17-a.xctoolchain/usr/local/lib/swift/host/plugins -target-sdk-version 15.2 -target-sdk-name macosx15.2 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server
1.	Apple Swift version 6.2-dev (LLVM 21406e90d7382d7, Swift 90340a069a706c3)
2.	Compiling with effective version 5.10
3.	While verifying SIL function "@main".
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           0x000000010a1ac184 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x000000010a1aa8b0 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x000000010a1ac7cc SignalHandler(int, __siginfo*, void*) + 296
3  libsystem_platform.dylib 0x000000018f996de4 _sigtramp + 56
4  libsystem_pthread.dylib  0x000000018f95ff70 pthread_kill + 288
5  libsystem_c.dylib        0x000000018f86c908 abort + 128
6  swift-frontend           0x000000010595b828 swift::SILModule::print(llvm::raw_ostream&, swift::ModuleDecl*, swift::SILOptions const&, bool) const + 0
7  swift-frontend           0x000000010597d87c (anonymous namespace)::SILVerifier::visitSILInstruction(swift::SILInstruction*) + 1584
8  swift-frontend           0x0000000105968568 swift::SILVisitorBase<(anonymous namespace)::SILVerifier, void>::visitSILBasicBlock(swift::SILBasicBlock*) + 22648
9  swift-frontend           0x0000000105962c30 (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 24
10 swift-frontend           0x0000000105961590 (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) + 10464
11 swift-frontend           0x000000010595b9e0 swift::SILFunction::verify(swift::CalleeCache*, bool, bool, bool) const + 224
12 swift-frontend           0x000000010595e6f4 swift::SILModule::verify(swift::CalleeCache*, bool, bool) const + 192
13 swift-frontend           0x000000010595e5cc swift::SILModule::verify(bool, bool) const + 140
14 swift-frontend           0x0000000104d0f228 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 148
15 swift-frontend           0x0000000104ad6340 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 820
16 swift-frontend           0x0000000104ad5cf8 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1320
17 swift-frontend           0x0000000104ae1f48 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 164
18 swift-frontend           0x0000000104ad76f4 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 716
19 swift-frontend           0x0000000104ad6f10 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2244
20 swift-frontend           0x000000010488ec8c swift::mainEntry(int, char const**) + 3060
21 dyld                     0x000000018f5e0274 start + 2840

Expected behavior

The compiler doesn't crash.

Environment

Apple Swift version 6.2-dev (LLVM 21406e90d7382d7, Swift 90340a069a706c3)
Target: arm64-apple-macosx15.0
Build config: +assertions

Additional information

This may be related to #75999, but this issue occurs even if you use ! instead of ?.

(Related post: https://forums.swift.org/t/how-can-i-borrow-with-conditional-binding/78759/11)

Metadata

Metadata

Assignees

No one assigned

    Labels

    assignmentsFeature → expressions: assignmentsbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwareexpressionsFeature: expressionsnoncopyable struct/enumFeature → declarations: Noncopyable value type declarationsoptional chainingFeature → expressions: optional chaining

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions