Help debugging equal-but-unequal archetypes in SILGen/emitMemberInitializers


(Jacob Bandes-Storch) #1

I started taking a look at SR-493 <https://bugs.swift.org/browse/SR-493>,
which is triggered with this code:

    struct Foo<G> { var l1: G? }
    extension Foo { init(x: Int) { } }

It turns out that for the init in the extension,
SILGenFunction::emitSemanticStore is being called with src & dest types
which *should* be the same, but aren't, so it goes down the wrong code path.

This is for the implicit initialization, which looks to be effectively
"self.l1 = { Optional<G>(nilLiteral: ()) }()"

(lldb) p *rvalue*
.getType().getSwiftType()->getInOutObjectType()->getOptionalObjectType()
(swift::Type) $191 = {
  Ptr = 0x000000010d0a28d8
}
(lldb) p *dest*
.getType().getSwiftType()->getInOutObjectType()->getOptionalObjectType()
(swift::Type) $192 = {
  Ptr = 0x000000010b00dd68
}

But these types "look" the same (they are both the archetype for G):

(lldb) p *rvalue*
.getType().getSwiftType()->getInOutObjectType()->getOptionalObjectType()->getString(PrintOptions::printEverything())
(std::__1::string) $201 = "G"
(lldb) p *dest*
.getType().getSwiftType()->getInOutObjectType()->getOptionalObjectType()->getString(PrintOptions::printEverything())
(std::__1::string) $202 = "G"

Now I'm stuck. This is my first attempt to understand anything in SILGen,
but I think the problem might trace back to Sema. Why would it end up with
different Archetypes? Perhaps because the generic params are cloned
<https://github.com/apple/swift/blob/c794609d29f85c76c7a6b1aba81b99cd213fd721/lib/Sema/TypeChecker.cpp#L333>
for
the extension decl?

Or a better question: is there a more correct way of comparing these types
for the purpose of emitSemanticStore than simply by pointer equality
<https://github.com/apple/swift/blob/c794609d29f85c76c7a6b1aba81b99cd213fd721/include/swift/SIL/SILType.h#L526>
?

Thanks,
Jacob