| | |
|------------------|-----------------|…
|Previous ID | SR-3321 |
|Radar | None |
|Original Reporter | benasher44 (JIRA User) |
|Type | Bug |
|Status | Closed |
|Resolution | Done |
<details>
<summary>Environment</summary>
Swift 3 DEVELOPMENT-SNAPSHOT-2016-11-29-a, macOS Sierra
</details>
<details>
<summary>Additional Detail from JIRA</summary>
| | |
|------------------|-----------------|
|Votes | 0 |
|Component/s | Compiler |
|Labels | Bug, 3.1Regression |
|Assignee | @slavapestov |
|Priority | Medium |
md5: 9e3bc44408cf380367cfb1c037073330
</details>
**Issue Description:**
I recently tried out Swift 3 DEVELOPMENT-SNAPSHOT-2016-11-29-a, and the following code crashes but works fine in Xcode 8.1 and Xcode 8.2 beta 2:
``` java
import Foundation
protocol ControllerA: Equatable {
}
protocol ControllerB {
associatedtype T: Controller
}
protocol Controller {
associatedtype T: ControllerA
var selected: T { get }
func shouldSelect<S: ControllerB>(_ a: T, in b: S) -> Bool where S.T == Self
}
extension Controller {
func didSelect<S: ControllerB>(_ a: T, in b: S) where S.T == Self {
guard a != selected else { return }
if !shouldSelect(a, in: b) {
return
}
}
}
```
I took this code from our codebase and pulled it apart a bit, so I apologize for the terse naming. Here's the output when running `swift` on this file using this snapshot:
> SIL verification failed: method's Self parameter should be constrained by protocol: selfRequirement.getKind() == RequirementKind::Conformance && selfRequirement.getFirstType()~~\>isEqual(selfGenericParam) && selfRequirement.getSecondType()~~\>getAs\<ProtocolType\>() -\>getDecl() == protocol
> Verifying instruction:
> -\> %25 = witness_method $Self, \#Controller.shouldSelect!1 : $@convention(witness_method) \<τ_0\_0\>\<τ_1\_0 where τ_1\_0 : ControllerB, τ_0\_0 == τ_1\_0.T\> (@in τ_0\_0.T, @in τ_1\_0, @in_guaranteed τ_0\_0) -\> Bool, loc "test.swift":21:13, scope 0 // user: %30
> %30 = apply %25\<Self, S\>(%26, %28, %2) : $@convention(witness_method) \<τ_0\_0\>\<τ_1\_0 where τ_1\_0 : ControllerB, τ_0\_0 == τ_1\_0.T\> (@in τ_0\_0.T, @in τ_1\_0, @in_guaranteed τ_0\_0) -\> Bool, loc "test.swift":21:34, scope 0 // user: %31
> In function:
> sil_scope 1 { loc "test.swift":19:10 parent @*TFE4testPS_10Controller9didSelectuRdS_11ControllerBxzwd1TrfTwx1T2inqd*\_*T* : $@convention(method) \<τ_0\_0\>\<τ_1\_0 where τ_1\_0 : ControllerB, τ_0\_0 == τ_1\_0.T\> (@in τ_0\_0.T, @in τ_1\_0, @in_guaranteed τ_0\_0) -\> () }
> sil_scope 2 { loc "test.swift":24:5 parent 1 }
> sil_scope 3 { loc "test.swift":23:9 parent 2 }
> sil_scope 4 { loc "test.swift":23:9 parent 3 }
> sil_scope 5 { loc "test.swift":20:43 parent 2 }
>
> // Controller.didSelect\<A where ...\> (A.T, in : A1) -\> ()
> sil hidden @*TFE4testPS_10Controller9didSelectuRdS_11ControllerBxzwd1TrfTwx1T2inqd*\_*T* : $@convention(method) \<Self\>\<S where S : ControllerB, Self == S.T\> (@in Self.T, @in S, @in_guaranteed Self) -\> () {
> // %0 // users: %40, %27, %9, %3
> // %1 // users: %39, %29, %4
> // %2 // users: %30, %11, %5
> bb0(%0 : $\*Self.T, %1 : $\*S, %2 : $\*Self):
> debug_value_addr %0 : $\*Self.T, let, name "a", argno 1, loc "test.swift":19:38, scope 1 // id: %3
> debug_value_addr %1 : $\*S, let, name "b", argno 2, loc "test.swift":19:47, scope 1 // id: %4
> debug_value_addr %2 : $\*Self, let, name "self", argno 3, loc "test.swift":19:10, scope 1 // id: %5
> // function_ref Bool.\_getBuiltinLogicValue() -\> Builtin.Int1
> %6 = function_ref @*TFSb21_getBuiltinLogicValuefT_Bi1* : $@convention(method) (Bool) -\> Builtin.Int1, loc "test.swift":20:17, scope 2 // user: %17
> // function_ref != infix\<A where ...\> (A, A) -\> Bool
> %7 = function_ref @\_TFsoi2neuRxs9EquatablerFTxx_Sb : $@convention(thin) \<τ_0\_0 where τ_0\_0 : Equatable\> (@in τ_0\_0, @in τ_0\_0) -\> Bool, loc "test.swift":20:17, scope 2 // user: %16
> %8 = alloc_stack $Self.T, loc "test.swift":20:15, scope 2 // users: %20, %16, %9
> copy_addr %0 to \[initialization\] %8 : $\*Self.T, loc "test.swift":20:15, scope 2 // id: %9
> %10 = alloc_stack $Self, loc "test.swift":20:20, scope 2 // users: %19, %15, %14, %11
> copy_addr %2 to \[initialization\] %10 : $\*Self, loc "test.swift":20:20, scope 2 // id: %11
> %12 = witness_method $Self, \#Controller.selected!getter.1 : $@convention(witness_method) \<τ_0\_0 where τ_0\_0 : Controller\> (@in_guaranteed τ_0\_0) -\> @out τ_0\_0.T, loc "test.swift":20:20, scope 2 // user: %14
> %13 = alloc_stack $Self.T, loc "test.swift":20:20, scope 2 // users: %18, %16, %14
> %14 = apply %12\<Self\>(%13, %10) : $@convention(witness_method) \<τ_0\_0 where τ_0\_0 : Controller\> (@in_guaranteed τ_0\_0) -\> @out τ_0\_0.T, loc "test.swift":20:20, scope 2
> destroy_addr %10 : $\*Self, loc "test.swift":20:20, scope 2 // id: %15
> %16 = apply %7\<Self.T\>(%8, %13) : $@convention(thin) \<τ_0\_0 where τ_0\_0 : Equatable\> (@in τ_0\_0, @in τ_0\_0) -\> Bool, loc "test.swift":20:17, scope 2 // user: %17
> %17 = apply %6(%16) : $@convention(method) (Bool) -\> Builtin.Int1, loc "test.swift":20:20, scope 2 // user: %21
> dealloc_stack %13 : $\*Self.T, loc "test.swift":20:20, scope 2 // id: %18
> dealloc_stack %10 : $\*Self, loc "test.swift":20:20, scope 2 // id: %19
> dealloc_stack %8 : $\*Self.T, loc "test.swift":20:20, scope 2 // id: %20
> cond_br %17, bb1, bb4, loc "test.swift":20:20, scope 2 // id: %21
>
> bb1: // Preds: bb0
> // function_ref Bool.\_getBuiltinLogicValue() -\> Builtin.Int1
> %22 = function_ref @*TFSb21_getBuiltinLogicValuefT_Bi1* : $@convention(method) (Bool) -\> Builtin.Int1, loc "test.swift":21:12, scope 3 // user: %32
> // function_ref static Bool.! prefix(Bool) -\> Bool
> %23 = function_ref @\_TZFSbop1nfSbSb : $@convention(method) (Bool, @thin Bool.Type) -\> Bool, loc "test.swift":21:12, scope 3 // user: %31
> %24 = metatype $@thin Bool.Type, loc "test.swift":21:12, scope 3 // user: %31
> %25 = witness_method $Self, \#Controller.shouldSelect!1 : $@convention(witness_method) \<τ_0\_0\>\<τ_1\_0 where τ_1\_0 : ControllerB, τ_0\_0 == τ_1\_0.T\> (@in τ_0\_0.T, @in τ_1\_0, @in_guaranteed τ_0\_0) -\> Bool, loc "test.swift":21:13, scope 3 // user: %30
> %26 = alloc_stack $Self.T, loc "test.swift":21:26, scope 3 // users: %34, %30, %27
> copy_addr %0 to \[initialization\] %26 : $\*Self.T, loc "test.swift":21:26, scope 3 // id: %27
> %28 = alloc_stack $S, loc "test.swift":21:33, scope 3 // users: %33, %30, %29
> copy_addr %1 to \[initialization\] %28 : $\*S, loc "test.swift":21:33, scope 3 // id: %29
> %30 = apply %25\<Self, S\>(%26, %28, %2) : $@convention(witness_method) \<τ_0\_0\>\<τ_1\_0 where τ_1\_0 : ControllerB, τ_0\_0 == τ_1\_0.T\> (@in τ_0\_0.T, @in τ_1\_0, @in_guaranteed τ_0\_0) -\> Bool, loc "test.swift":21:34, scope 3 // user: %31
> %31 = apply %23(%30, %24) : $@convention(method) (Bool, @thin Bool.Type) -\> Bool, loc "test.swift":21:12, scope 3 // user: %32
> %32 = apply %22(%31) : $@convention(method) (Bool) -\> Builtin.Int1, loc "test.swift":21:34, scope 3 // user: %35
> dealloc_stack %28 : $\*S, loc "test.swift":21:34, scope 3 // id: %33
> dealloc_stack %26 : $\*Self.T, loc "test.swift":21:34, scope 3 // id: %34
> cond_br %32, bb2, bb3, loc "test.swift":21:34, scope 3 // id: %35
>
> bb2: // Preds: bb1
> br bb5, loc "test.swift":22:11, scope 4 // id: %36
>
> bb3: // Preds: bb1
> br bb5, loc "test.swift":24:5, scope 2 // id: %37
>
> bb4: // Preds: bb0
> br bb5, loc "test.swift":20:36, scope 5 // id: %38
>
> bb5: // Preds: bb3 bb2 bb4
> destroy_addr %1 : $\*S, loc "test.swift":24:5, scope 2 // id: %39
> destroy_addr %0 : $\*Self.T, loc "test.swift":24:5, scope 2 // id: %40
> %41 = tuple (), loc "test.swift":24:5, scope 2 // user: %42
> return %41 : $(), loc "test.swift":24:5, scope 2 // id: %42
> } // end sil function '*TFE4testPS_10Controller9didSelectuRdS_11ControllerBxzwd1TrfTwx1T2inqd*\_*T*'
>
> 0 swift 0x0000000107934476 llvm::sys::RunSignalHandlers() + 86
> 1 swift 0x0000000107935b29 SignalHandler(int) + 361
> 2 libsystem_platform.dylib 0x00007fffbf32abba \_sigtramp + 26
> Stack dump:
> 0. Program arguments: /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2016-11-29-a.xctoolchain/usr/bin/swift -frontend -interpret test.swift -target x86_64-apple-macosx10.9 -enable-objc-interop -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -color-diagnostics -module-name test
> 1. While emitting SIL for 'didSelect' at test.swift:19:5
> 2. While verifying SIL function @*TFE4testPS_10Controller9didSelectuRdS_11ControllerBxzwd1TrfTwx1T2inqd*\_*T* for 'didSelect' at test.swift:19:5
> Abort trap: 6
Please feel free to rename this ticket. I'm not familiar with this kind of failure, so the current name is vague. I'm sure someone with more knowledge in this area could pick a better name.