Compiler crash in Swift 5.2, 5.2.4

The following code compiles and runs fin in Swift 5.1, but it crashes the compiler in Swift 5.2 and 5.2.4:


@propertyWrapper
public class Provide<Value> {
    public var override: Value?
    
    public static subscript<I: Provide, R>(
        _enclosingInstance instance: R,
        wrapped kp: WritableKeyPath<R, Value>,
        storage storageKeyPath: WritableKeyPath<R, I>
    ) -> Value {
        get {
            let wrapper = instance[keyPath: storageKeyPath]
            return wrapper.value(instance: instance, keyPath: kp)
        }
        set {
            let wrapper = instance[keyPath: storageKeyPath]
            wrapper.override = newValue
        }
    }
    
    public func value<R>(instance: Any, keyPath kp: WritableKeyPath<R, Value>) -> Value {
        return override!
    }
    
    @available(*, unavailable)
    public var wrappedValue: Value {
        get { fatalError("called wrappedValue getter") }
        set { fatalError("called wrappedValue setter") }
    }
    
    public init(wrappedValue: Value) {
        self.override = wrappedValue
    }
}

struct Foo {
}

class Bar {
    @Provide var myFoo: Foo = Foo()
    init() {}
}

class Baz {
    @Provide var myBar: Bar = Bar()
    init() {}
}

var text: String {
    let baz = Baz()
    return "\(baz.myBar)"
}

print(text)

The error message says:

(load_expr implicit type='Foo'
  (subscript_expr implicit type='@lvalue Foo' decl=Shot.(file).Provide.subscript(_enclosingInstance:wrapped:storage:)@/Users/mememe/code/research/Shot/Shot/Source/Inject.swift:16:19 [with (substitution_map generic_signature=<Value, I, R where I : Provide<Value>> (substitution Value -> Foo) (substitution I -> Provide<Foo>) (substitution R -> Bar))] arg_labels=_enclosingInstance:wrapped:storage:
    (type_expr implicit type='Provide<Foo>.Type' typerepr='<<NULL>>')
    (tuple_expr implicit type='(_enclosingInstance: Bar, wrapped: WritableKeyPath<Bar, Foo>, storage: WritableKeyPath<Bar, Provide<Foo>>)' names=_enclosingInstance,wrapped,storage
      (declref_expr implicit type='Bar' decl=BugRepro.(file).Bar.<anonymous>.self@/Users/mememe/code/research/Shot/BugRepro/BugRepro/BugRepro.swift:8:18 function_ref=unapplied)
      (keypath_expr type='WritableKeyPath<Bar, Foo>'
        (components          
          (property decl=BugRepro.(file).Bar.myFoo@/Users/mememe/code/research/Shot/BugRepro/BugRepro/BugRepro.swift:8:18 type='@lvalue Foo'))
        (parsed_path
          (unresolved_dot_expr implicit type='<null>' field 'myFoo' function_ref=unapplied
            (key_path_dot_expr implicit type='<null>'))))
      (keypath_expr type='WritableKeyPath<Bar, Provide<Foo>>'
        (components          
          (property decl=BugRepro.(file).Bar._myFoo@/Users/mememe/code/research/Shot/BugRepro/BugRepro/BugRepro.swift:8:18 type='@lvalue Provide<Foo>'))
        (parsed_path
          (unresolved_dot_expr implicit type='<null>' field '_myFoo' function_ref=unapplied
            (key_path_dot_expr implicit type='<null>')))))))

The stacktrace is:

1.	Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
2.	While emitting SIL for setter for myFoo (at /Users/mememe/code/research/Shot/BugRepro/BugRepro/BugRepro.swift:8:18)
3.	While silgen emitFunction SIL function "@$s8BugRepro3BarC5myFooAA0E0Vvs".
 for setter for myFoo (at /Users/mememe/code/research/Shot/BugRepro/BugRepro/BugRepro.swift:8:18)
0  swift                    0x00000001062d64ea PrintStackTraceSignalHandler(void*) + 42
1  swift                    0x00000001062d5cc0 SignalHandler(int) + 352
2  libsystem_platform.dylib 0x00007fff6edba5fd _sigtramp + 29
3  libsystem_malloc.dylib   0x00007fff6ed7b385 szone_size + 45
4  swift                    0x00000001024f25ce swift::ASTVisitor<SILGenLValue, swift::Lowering::LValue, void, void, void, void, void, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions>::visit(swift::Expr*, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions) + 13006
5  swift                    0x00000001024ef1f2 swift::Lowering::SILGenFunction::emitLValue(swift::Expr*, swift::Lowering::SGFAccessKind, swift::Lowering::LValueOptions) + 34
6  swift                    0x00000001024b2273 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 46787
7  swift                    0x00000001024c0a37 swift::Lowering::SILGenFunction::emitIgnoredExpr(swift::Expr*) + 823
8  swift                    0x0000000102523aee swift::ASTVisitor<(anonymous namespace)::StmtEmitter, void, void, void, void, void, void>::visit(swift::Stmt*) + 382
9  swift                    0x00000001024d677f swift::Lowering::SILGenFunction::emitFunction(swift::FuncDecl*) + 799
10 swift                    0x000000010243c959 swift::Lowering::SILGenModule::emitFunction(swift::FuncDecl*) + 953
11 swift                    0x00000001025381b8 void llvm::function_ref<void (swift::AccessorDecl*)>::callback_fn<(anonymous namespace)::SILGenType::visitAccessors(swift::AbstractStorageDecl*)::'lambda'(swift::AccessorDecl*)>(long, swift::AccessorDecl*) + 24
12 swift                    0x0000000103042f95 swift::AbstractStorageDecl::visitExpectedOpaqueAccessors(llvm::function_ref<void (swift::AccessorKind)>) const + 741
13 swift                    0x0000000102538166 (anonymous namespace)::SILGenType::visitVarDecl(swift::VarDecl*) + 2022
14 swift                    0x0000000102534bfb (anonymous namespace)::SILGenType::emitType() + 939
15 swift                    0x0000000102446d82 swift::ASTVisitor<swift::Lowering::SILGenModule, void, void, void, void, void, void>::visit(swift::Decl*) + 82
16 swift                    0x0000000102445f4c swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*) + 1356
17 swift                    0x0000000102447fce swift::SILModule::constructSIL(swift::ModuleDecl*, swift::Lowering::TypeConverter&, swift::SILOptions&, swift::FileUnit*) + 1438
18 swift                    0x0000000102027d51 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 48065
19 swift                    0x0000000101f9fb73 main + 1283
20 libdyld.dylib            0x00007fff6ebc1cc9 start + 1
21 libdyld.dylib            0x0000000000000050 start + 2437145480

That's a compiler bug. Mind filing this on bugs.swift.org ?

OK I will.

BTW, thanks to another post elsewhere on these forums, I was able to fix this by converting the property wrapper from a class into a struct.

To make that work, I had to make a protocol that the struct adopts, since I use the type Provide as a generic constraint here public static subscript<I: Provide, R>. So my protocol ended up looking like:

protocol Provider {
    associatedtype Value
    var override: Value { get set }
    func value<R>(instance: R, keyPath: kp: WritableKeyPath<R< Value>) -> Value
}

then:

@propertyWrapper
struct Provide<Value>: Provider { ... }

Etc.