@@ -29,6 +29,8 @@ enum Optional<T> {
29
29
30
30
protocol Error {}
31
31
32
+ struct Bad: Error {}
33
+
32
34
struct I {}
33
35
34
36
class Klass {}
@@ -109,6 +111,8 @@ sil [ossa] @takeTuple : $@convention(thin) <τ_0_0> (@in_guaranteed (τ_0_0, C))
109
111
110
112
sil [ossa] @eraseToAny : $@convention(thin) <T> (@in_guaranteed T) -> @out Any
111
113
sil [ossa] @produceInt : $@convention(thin) () -> Int
114
+ sil [ossa] @produceBool : $@convention(thin) () -> Bool
115
+ sil [ossa] @produceBad : $@convention(thin) () -> Bad
112
116
113
117
sil [ossa] @takeIn : $@convention(thin) <T> (@in T) -> ()
114
118
sil [ossa] @takeInGuaranteed : $@convention(thin) <T> (@in_guaranteed T) -> ()
@@ -1454,6 +1458,142 @@ bad(%41 : @owned $any Error):
1454
1458
throw %41 : $any Error
1455
1459
}
1456
1460
1461
+ // While an '@error Error' turns into an '@error any Error', an '@error' of a concrete type remains as-is.
1462
+ // --------
1463
+ // CHECK-LABEL: sil [ossa] @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad) {
1464
+ // CHECK: bb0(%0 : $Bad):
1465
+ // CHECK: return %0 : $Bad
1466
+ // CHECK: throw %0 : $Bad
1467
+ // CHECK-LABEL: } // end sil function 'f270_typedThrows_throwConcrete'
1468
+ sil [ossa] @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad) {
1469
+ bb0(%0 : $Bad):
1470
+ %fn = function_ref @produceBool : $@convention(thin) () -> Bool
1471
+ %cond = apply %fn() : $@convention(thin) () -> Bool
1472
+ cond_br %cond, doThrow, doReturn
1473
+
1474
+ doThrow:
1475
+ throw %0
1476
+
1477
+ doReturn:
1478
+ return %0
1479
+ }
1480
+
1481
+ // CHECK-LABEL: sil [ossa] @f271_typedThrows_callConcrete : $@convention(thin) () -> () {
1482
+ // CHECK: try_apply {{.*}} : $@convention(thin) (Bad) -> (Bad, @error Bad), normal bb2, error bb1
1483
+ // CHECK: bb1({{.*}} : $Bad)
1484
+ // CHECK: bb2({{.*}} : $Bad)
1485
+ // CHECK-LABEL: } // end sil function 'f271_typedThrows_callConcrete'
1486
+ sil [ossa] @f271_typedThrows_callConcrete : $@convention(thin) () -> () {
1487
+ bb0:
1488
+ %fn = function_ref @produceBad : $@convention(thin) () -> Bad
1489
+ %arg = apply %fn() : $@convention(thin) () -> Bad
1490
+ %callee = function_ref @f270_typedThrows_throwConcrete : $@convention(thin) (Bad) -> (Bad, @error Bad)
1491
+ try_apply %callee(%arg) : $@convention(thin) (Bad) -> (Bad, @error Bad), normal normalBB, error errorBB
1492
+
1493
+ normalBB(%r : $Bad):
1494
+ ignored_use %r
1495
+ br exitBB
1496
+
1497
+ errorBB(%e : $Bad):
1498
+ ignored_use %e
1499
+ br exitBB
1500
+
1501
+ exitBB:
1502
+ %t = tuple ()
1503
+ return %t
1504
+ }
1505
+
1506
+ // Handle throwing a generic type conforming to Error via @error_indirect
1507
+ // --------
1508
+ // CHECK-LABEL: sil [ossa] @f272_typedThrows_throwGeneric : $@convention(thin) <GenBad, Result where GenBad : Error> (@in_guaranteed GenBad, @in_guaranteed Result) -> (@out Result, @error_indirect GenBad) {
1509
+ // CHECK: bb0(%0 : $*Result, %1 : $*GenBad, %2 : $*GenBad, %3 : $*Result):
1510
+ // CHECK: cond_br {{.*}}, bb2, bb1
1511
+ //
1512
+ // CHECK: bb1:
1513
+ // CHECK: copy_addr %3 to [init] %0 : $*Result
1514
+ // CHECK: return {{.*}} : $()
1515
+ //
1516
+ // CHECK: bb2:
1517
+ // CHECK: [[STACK:%[^,]+]] = alloc_stack $GenBad
1518
+ // CHECK: copy_addr %2 to [init] [[STACK]] : $*GenBad
1519
+ // CHECK: copy_addr [take] [[STACK]] to [init] %1 : $*GenBad
1520
+ // CHECK: dealloc_stack [[STACK]] : $*GenBad
1521
+ // CHECK: throw_addr
1522
+ // CHECK-LABEL: } // end sil function 'f272_typedThrows_throwGeneric'
1523
+ sil [ossa] @f272_typedThrows_throwGeneric : $@convention(thin) <GenBad, Result where GenBad : Error> (@in_guaranteed GenBad, @in_guaranteed Result) -> (@out Result, @error_indirect GenBad) {
1524
+ bb0(%e : @guaranteed $GenBad, %r : @guaranteed $Result):
1525
+ %fn = function_ref @produceBool : $@convention(thin) () -> Bool
1526
+ %cond = apply %fn() : $@convention(thin) () -> Bool
1527
+ cond_br %cond, doThrow, doReturn
1528
+
1529
+ doReturn:
1530
+ %rCopy = copy_value %r
1531
+ return %rCopy
1532
+
1533
+ doThrow:
1534
+ %eCopy = copy_value %e
1535
+ throw %eCopy
1536
+ }
1537
+
1538
+ // CHECK-LABEL: sil [ossa] @f273_typedThrows_callGeneric : $@convention(thin) () -> () {
1539
+ // CHECK: bb0:
1540
+ // CHECK: // function_ref produceBad
1541
+ // CHECK: [[PROD:%[^,]+]] = function_ref @produceBad : $@convention(thin) () -> Bad
1542
+ // CHECK: [[ARG1:%[^,]+]] = apply [[PROD]]() : $@convention(thin) () -> Bad
1543
+ // CHECK: [[ARG2:%[^,]+]] = apply [[PROD]]() : $@convention(thin) () -> Bad
1544
+ // CHECK: [[ARG1_IN:%[^,]+]] = alloc_stack $Bad
1545
+ // CHECK: store [[ARG1]] to [trivial] [[ARG1_IN]] : $*Bad
1546
+ // CHECK: [[ARG2_IN:%[^,]+]] = alloc_stack $Bad
1547
+ // CHECK: store [[ARG2]] to [trivial] [[ARG2_IN]] : $*Bad
1548
+ // CHECK: [[RESULT_OUT:%[^,]+]] = alloc_stack $Bad
1549
+ // CHECK: [[ERR_OUT:%[^,]+]] = alloc_stack $Bad
1550
+ // CHECK: try_apply {{.*}}<Bad, Bad>([[RESULT_OUT]], [[ERR_OUT]], [[ARG1_IN]], [[ARG2_IN]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0), normal bb2, error bb1
1551
+
1552
+ // CHECK: bb1:
1553
+ // CHECK: [[ERR:%[^,]+]] = load [trivial] [[ERR_OUT]] : $*Bad
1554
+ // CHECK: dealloc_stack [[ERR_OUT]] : $*Bad
1555
+ // CHECK: dealloc_stack [[RESULT_OUT]] : $*Bad
1556
+ // CHECK: dealloc_stack [[ARG2_IN]] : $*Bad
1557
+ // CHECK: dealloc_stack [[ARG1_IN]] : $*Bad
1558
+ // CHECK: ignored_use [[ERR]] : $Bad
1559
+ // CHECK: ignored_use [[ERR]] : $Bad
1560
+ // CHECK: br bb3
1561
+
1562
+ // CHECK: bb2(%11 : $()):
1563
+ // CHECK: dealloc_stack [[ERR_OUT]] : $*Bad
1564
+ // CHECK: [[RESULT:%[^,]+]] = load [trivial] [[RESULT_OUT]] : $*Bad
1565
+ // CHECK: dealloc_stack [[RESULT_OUT]] : $*Bad
1566
+ // CHECK: dealloc_stack [[ARG2_IN]] : $*Bad
1567
+ // CHECK: dealloc_stack [[ARG1_IN]] : $*Bad
1568
+ // CHECK: ignored_use [[RESULT]] : $Bad
1569
+ // CHECK: br bb3
1570
+
1571
+ // CHECK: bb3:
1572
+ // CHECK: return {{.*}} : $()
1573
+ // CHECK-LABEL: } // end sil function 'f273_typedThrows_callGeneric'
1574
+ sil [ossa] @f273_typedThrows_callGeneric : $@convention(thin) () -> () {
1575
+ bb0:
1576
+ %fn = function_ref @produceBad : $@convention(thin) () -> Bad
1577
+ %arg1 = apply %fn() : $@convention(thin) () -> Bad
1578
+ %arg2 = apply %fn() : $@convention(thin) () -> Bad
1579
+ %callee = function_ref @f272_typedThrows_throwGeneric : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0)
1580
+ try_apply %callee<Bad, Bad>(%arg1, %arg2) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : Error> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> (@out τ_0_1, @error_indirect τ_0_0), normal normalBB, error errorBB
1581
+
1582
+ normalBB(%r : $Bad):
1583
+ ignored_use %r
1584
+ br exitBB
1585
+
1586
+ errorBB(%e : $Bad):
1587
+ ignored_use %e
1588
+ ignored_use %e
1589
+ br exitBB
1590
+
1591
+ exitBB:
1592
+ %t = tuple ()
1593
+ return %t
1594
+ }
1595
+
1596
+
1457
1597
// CHECK-LABEL: sil [ossa] @fixeeLifetime : {{.*}} {
1458
1598
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
1459
1599
// CHECK: fix_lifetime [[ADDR]]
0 commit comments