swiftlang / swift

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

[SIL][verify] operand of 'apply' doesn't match function input type #76025

Open ellishg opened 3 weeks ago

ellishg commented 3 weeks ago

Description

SIL verification is failing with

operand of 'apply' doesn't match function input type

when using an associatedtype sometimes.

Reproduction

func foo(_ a: Encodable) { }

public protocol Goo {
  associatedtype A: Encodable
  var a: A { get }
}

public func bar(goo: any Goo) {
  foo(goo.a)
  foo(goo.a)
}

Stack dump

SIL verification failed: operand of 'apply' doesn't match function input type
  $*@opened("31CA26A4-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A
  $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A
Verifying instruction:
     %2 = open_existential_addr immutable_access %0 : $*any Goo to $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self // users: %14, %14, %8, %6, %6, %5, %4
     %2 = open_existential_addr immutable_access %0 : $*any Goo to $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self // users: %14, %14, %8, %6, %6, %5, %4
     %4 = witness_method $@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self, #Goo.a!getter : <Self where Self : Goo> (Self) -> () -> Self.A, %2 : $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self : $@convention(witness_method: Goo) <τ_0_0 where τ_0_0 : Goo> (@in_guaranteed τ_0_0) -> @out τ_0_0.A // type-defs: %2; users: %14, %6
     %13 = init_existential_addr %12 : $*any Encodable, $@opened("31CA26A4-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A // type-defs: %11; users: %14, %15
->   %14 = apply %4<@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self>(%13, %2) : $@convention(witness_method: Goo) <τ_0_0 where τ_0_0 : Goo> (@in_guaranteed τ_0_0) -> @out τ_0_0.A // type-defs: %2
In function:
// bar(goo:)
sil @$s5crash3bar3gooyAA3Goo_p_tF : $@convention(thin) (@in_guaranteed any Goo) -> () {
[%0: read x.v**, write x.v**, copy x.v**, destroy x.v**]
[global: read,write,copy,destroy,allocate,deinit_barrier]
// %0 "goo"                                       // users: %11, %2, %1
bb0(%0 : $*any Goo):
  debug_value %0 : $*any Goo, let, name "goo", argno 1, expr op_deref // id: %1
  %2 = open_existential_addr immutable_access %0 : $*any Goo to $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self // users: %14, %14, %8, %6, %6, %5, %4
  %3 = alloc_stack $any Encodable                 // users: %10, %9, %5
  %4 = witness_method $@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self, #Goo.a!getter : <Self where Self : Goo> (Self) -> () -> Self.A, %2 : $*@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self : $@convention(witness_method: Goo) <τ_0_0 where τ_0_0 : Goo> (@in_guaranteed τ_0_0) -> @out τ_0_0.A // type-defs: %2; users: %14, %6
  %5 = init_existential_addr %3 : $*any Encodable, $@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A // type-defs: %2; users: %8, %6
  %6 = apply %4<@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self>(%5, %2) : $@convention(witness_method: Goo) <τ_0_0 where τ_0_0 : Goo> (@in_guaranteed τ_0_0) -> @out τ_0_0.A // type-defs: %2
  // function_ref specialized foo(_:)
  %7 = function_ref @$s5crash3fooyySE_pFTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : Encodable> (@in_guaranteed τ_0_0) -> () // users: %15, %8
  %8 = apply %7<@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A>(%5) : $@convention(thin) <τ_0_0 where τ_0_0 : Encodable> (@in_guaranteed τ_0_0) -> () // type-defs: %2
  destroy_addr %3 : $*any Encodable               // id: %9
  dealloc_stack %3 : $*any Encodable              // id: %10
  %11 = open_existential_addr immutable_access %0 : $*any Goo to $*@opened("31CA26A4-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self // users: %15, %13
  %12 = alloc_stack $any Encodable                // users: %17, %16, %13
  %13 = init_existential_addr %12 : $*any Encodable, $@opened("31CA26A4-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A // type-defs: %11; users: %14, %15
  %14 = apply %4<@opened("31CA1BE6-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self>(%13, %2) : $@convention(witness_method: Goo) <τ_0_0 where τ_0_0 : Goo> (@in_guaranteed τ_0_0) -> @out τ_0_0.A // type-defs: %2
  %15 = apply %7<@opened("31CA26A4-5FF2-11EF-9BD7-05F35837A5D4", any Goo) Self.A>(%13) : $@convention(thin) <τ_0_0 where τ_0_0 : Encodable> (@in_guaranteed τ_0_0) -> () // type-defs: %11
  destroy_addr %12 : $*any Encodable              // id: %16
  dealloc_stack %12 : $*any Encodable             // id: %17
  %18 = tuple ()                                  // user: %19
  return %18 : $()                                // id: %19
} // end sil function '$s5crash3bar3gooyAA3Goo_p_tF'

Expected behavior

The compiler should not crash

Environment

I'm on branch close to release/6.0.

Additional information

I only observed the crash when -Osize was used.

swift-frontend -frontend -c crash.swift -Osize

The verification is failing here: https://github.com/swiftlang/swift/blob/b6a0162c6482473531418015deb98be90d48abd4/lib/SIL/Verifier/SILVerifier.cpp#L1982-L1985

This seems oddly similar to https://github.com/swiftlang/swift/issues/73896 (dup of https://github.com/swiftlang/swift/issues/64621 and https://github.com/swiftlang/swift/issues/60547). I'm filing a new issue because the stack trace is different.

ellishg commented 3 weeks ago

CC @slavapestov

ellishg commented 3 weeks ago

I've notice the error is suppressed if we first assign a to a local variable.

  local a = a
  foo(a)
  foo(a)
ellishg commented 1 week ago

Just confirmed that this is still failing after https://github.com/swiftlang/swift/pull/76238.