@@ -555,7 +555,7 @@ func testDiscardLValue() {
555
555
}
556
556
557
557
558
- func dynamicTypePlusZero( _ a : Super1 ) -> Super1 . Type {
558
+ func dynamicTypePlusZero( _ a: Super1 ) -> Super1 . Type {
559
559
return type ( of: a)
560
560
}
561
561
// CHECK-LABEL: dynamicTypePlusZero
@@ -567,9 +567,15 @@ func dynamicTypePlusZero(_ a : Super1) -> Super1.Type {
567
567
// CHECK: end_borrow [[BORROWED_ARG]] from [[ARG]]
568
568
// CHECK: destroy_value [[ARG]]
569
569
570
- struct NonTrivialStruct { var c : Super1 }
570
+ struct NonTrivialStruct {
571
+ var c : Super1
572
+ var x : NonTrivialStruct ? {
573
+ get { return nil }
574
+ set { }
575
+ }
576
+ }
571
577
572
- func dontEmitIgnoredLoadExpr( _ a : NonTrivialStruct ) -> NonTrivialStruct . Type {
578
+ func dontEmitIgnoredLoadExpr( _ a: NonTrivialStruct ) -> NonTrivialStruct . Type {
573
579
return type ( of: a)
574
580
}
575
581
// CHECK-LABEL: dontEmitIgnoredLoadExpr
@@ -581,6 +587,118 @@ func dontEmitIgnoredLoadExpr(_ a : NonTrivialStruct) -> NonTrivialStruct.Type {
581
587
// CHECK-NEXT: destroy_value %0
582
588
// CHECK-NEXT: return %4 : $@thin NonTrivialStruct.Type
583
589
590
+ // Test that we evaluate the force unwrap to get its side effects (a potential trap),
591
+ // but don't actually need to perform the load of its value.
592
+ func dontLoadIgnoredLValueForceUnwrap( _ a: inout NonTrivialStruct ? ) -> NonTrivialStruct . Type {
593
+ return type ( of: a!)
594
+ }
595
+ // CHECK-LABEL: dontLoadIgnoredLValueForceUnwrap
596
+ // CHECK: bb0(%0 : @trivial $*Optional<NonTrivialStruct>):
597
+ // CHECK-NEXT: debug_value_addr %0
598
+ // CHECK-NEXT: [[READ:%[0-9]+]] = begin_access [read] [unknown] %0
599
+ // CHECK-NEXT: switch_enum_addr [[READ]] : $*Optional<NonTrivialStruct>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
600
+ // CHECK: bb1:
601
+ // CHECK: unreachable
602
+ // CHECK: bb2:
603
+ // CHECK-NEXT: unchecked_take_enum_data_addr [[READ]] : $*Optional<NonTrivialStruct>, #Optional.some!enumelt.1
604
+ // CHECK-NEXT: end_access [[READ]]
605
+ // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin NonTrivialStruct.Type
606
+ // CHECK-NEXT: return [[METATYPE]]
607
+
608
+ func dontLoadIgnoredLValueDoubleForceUnwrap( _ a: inout NonTrivialStruct ? ? ) -> NonTrivialStruct . Type {
609
+ return type ( of: a!! )
610
+ }
611
+ // CHECK-LABEL: dontLoadIgnoredLValueDoubleForceUnwrap
612
+ // CHECK: bb0(%0 : @trivial $*Optional<Optional<NonTrivialStruct>>):
613
+ // CHECK-NEXT: debug_value_addr %0
614
+ // CHECK-NEXT: [[READ:%[0-9]+]] = begin_access [read] [unknown] %0
615
+ // CHECK-NEXT: switch_enum_addr [[READ]] : $*Optional<Optional<NonTrivialStruct>>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
616
+ // CHECK: bb1:
617
+ // CHECK: unreachable
618
+ // CHECK: bb2:
619
+ // CHECK-NEXT: [[UNWRAPPED:%[0-9]+]] = unchecked_take_enum_data_addr [[READ]] : $*Optional<Optional<NonTrivialStruct>>, #Optional.some!enumelt.1
620
+ // CHECK-NEXT: switch_enum_addr [[UNWRAPPED]] : $*Optional<NonTrivialStruct>, case #Optional.some!enumelt.1: bb4, case #Optional.none!enumelt: bb3
621
+ // CHECK: bb3:
622
+ // CHECK: unreachable
623
+ // CHECK: bb4:
624
+ // CHECK-NEXT: unchecked_take_enum_data_addr [[UNWRAPPED]] : $*Optional<NonTrivialStruct>, #Optional.some!enumelt.1
625
+ // CHECK-NEXT: end_access [[READ]]
626
+ // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin NonTrivialStruct.Type
627
+ // CHECK-NEXT: return [[METATYPE]]
628
+
629
+ func loadIgnoredLValueForceUnwrap( _ a: inout NonTrivialStruct ) -> NonTrivialStruct . Type {
630
+ return type ( of: a. x!)
631
+ }
632
+ // CHECK-LABEL: loadIgnoredLValueForceUnwrap
633
+ // CHECK: bb0(%0 : @trivial $*NonTrivialStruct):
634
+ // CHECK-NEXT: debug_value_addr %0
635
+ // CHECK-NEXT: [[READ:%[0-9]+]] = begin_access [read] [unknown] %0
636
+ // CHECK-NEXT: [[BORROW:%[0-9]+]] = load_borrow [[READ]]
637
+ // CHECK-NEXT: // function_ref NonTrivialStruct.x.getter
638
+ // CHECK-NEXT: [[GETTER:%[0-9]+]] = function_ref @$S{{[_0-9a-zA-Z]*}}vg : $@convention(method) (@guaranteed NonTrivialStruct) -> @owned Optional<NonTrivialStruct>
639
+ // CHECK-NEXT: [[X:%[0-9]+]] = apply [[GETTER]]([[BORROW]])
640
+ // CHECK-NEXT: end_borrow [[BORROW]] from [[READ]]
641
+ // CHECK-NEXT: end_access [[READ]]
642
+ // CHECK-NEXT: switch_enum [[X]] : $Optional<NonTrivialStruct>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
643
+ // CHECK: bb1:
644
+ // CHECK: unreachable
645
+ // CHECK: bb2([[UNWRAPPED_X:%[0-9]+]] : @owned $NonTrivialStruct):
646
+ // CHECK-NEXT: destroy_value [[UNWRAPPED_X]]
647
+ // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin NonTrivialStruct.Type
648
+ // CHECK-NEXT: return [[METATYPE]]
649
+
650
+ func loadIgnoredLValueThroughForceUnwrap( _ a: inout NonTrivialStruct ? ) -> NonTrivialStruct . Type {
651
+ return type ( of: a!. x!)
652
+ }
653
+ // CHECK-LABEL: loadIgnoredLValueThroughForceUnwrap
654
+ // CHECK: bb0(%0 : @trivial $*Optional<NonTrivialStruct>):
655
+ // CHECK-NEXT: debug_value_addr %0
656
+ // CHECK-NEXT: [[READ:%[0-9]+]] = begin_access [read] [unknown] %0
657
+ // CHECK-NEXT: switch_enum_addr [[READ]] : $*Optional<NonTrivialStruct>, case #Optional.some!enumelt.1: bb2, case #Optional.none!enumelt: bb1
658
+ // CHECK: bb1:
659
+ // CHECK: unreachable
660
+ // CHECK: bb2:
661
+ // CHECK-NEXT: [[UNWRAPPED:%[0-9]+]] = unchecked_take_enum_data_addr [[READ]] : $*Optional<NonTrivialStruct>, #Optional.some!enumelt.1
662
+ // CHECK-NEXT: [[BORROW:%[0-9]+]] = load_borrow [[UNWRAPPED]]
663
+ // CHECK-NEXT: // function_ref NonTrivialStruct.x.getter
664
+ // CHECK-NEXT: [[GETTER:%[0-9]+]] = function_ref @$S{{[_0-9a-zA-Z]*}}vg : $@convention(method) (@guaranteed NonTrivialStruct) -> @owned Optional<NonTrivialStruct>
665
+ // CHECK-NEXT: [[X:%[0-9]+]] = apply [[GETTER]]([[BORROW]])
666
+ // CHECK-NEXT: end_borrow [[BORROW]] from [[UNWRAPPED]]
667
+ // CHECK-NEXT: end_access [[READ]]
668
+ // CHECK-NEXT: switch_enum [[X]] : $Optional<NonTrivialStruct>, case #Optional.some!enumelt.1: bb4, case #Optional.none!enumelt: bb3
669
+ // CHECK: bb3:
670
+ // CHECK: unreachable
671
+ // CHECK: bb4([[UNWRAPPED_X:%[0-9]+]] : @owned $NonTrivialStruct):
672
+ // CHECK-NEXT: destroy_value [[UNWRAPPED_X]]
673
+ // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin NonTrivialStruct.Type
674
+ // CHECK-NEXT: return [[METATYPE]]
675
+
676
+ func evaluateIgnoredKeyPathExpr( _ s: inout NonTrivialStruct , _ kp: WritableKeyPath < NonTrivialStruct , Int > ) -> Int . Type {
677
+ return type ( of: s [ keyPath: kp] )
678
+ }
679
+ // CHECK-LABEL: evaluateIgnoredKeyPathExpr
680
+ // CHECK: bb0(%0 : @trivial $*NonTrivialStruct, %1 : @owned $WritableKeyPath<NonTrivialStruct, Int>):
681
+ // CHECK-NEXT: debug_value_addr %0
682
+ // CHECK-NEXT: debug_value %1
683
+ // CHECK-NEXT: [[S_READ:%[0-9]+]] = begin_access [read] [unknown] %0
684
+ // CHECK-NEXT: [[S_TEMP:%[0-9]+]] = alloc_stack $NonTrivialStruct
685
+ // CHECK-NEXT: copy_addr [[S_READ]] to [initialization] [[S_TEMP]]
686
+ // CHECK-NEXT: [[KP_BORROW:%[0-9]+]] = begin_borrow %1
687
+ // CHECK-NEXT: [[KP_TEMP:%[0-9]+]] = copy_value [[KP_BORROW]]
688
+ // CHECK-NEXT: [[KP:%[0-9]+]] = upcast [[KP_TEMP]]
689
+ // CHECK-NEXT: [[RESULT:%[0-9]+]] = alloc_stack $Int
690
+ // CHECK-NEXT: // function_ref
691
+ // CHECK-NEXT: [[PROJECT_FN:%[0-9]+]] = function_ref @$Ss23_projectKeyPathReadOnly{{[_0-9a-zA-Z]*}}F
692
+ // CHECK-NEXT: apply [[PROJECT_FN]]<NonTrivialStruct, Int>([[RESULT]], [[S_TEMP]], [[KP]])
693
+ // CHECK-NEXT: end_access [[S_READ]]
694
+ // CHECK-NEXT: dealloc_stack [[RESULT]]
695
+ // CHECK-NEXT: end_borrow [[KP_BORROW]] from %1
696
+ // CHECK-NEXT: dealloc_stack [[S_TEMP]]
697
+ // CHECK-NEXT: [[METATYPE:%[0-9]+]] = metatype $@thin Int.Type
698
+ // CHECK-NEXT: destroy_value %1
699
+ // CHECK-NEXT: return [[METATYPE]]
700
+
701
+
584
702
585
703
// <rdar://problem/18851497> Swiftc fails to compile nested destructuring tuple binding
586
704
// CHECK-LABEL: sil hidden @$S11expressions21implodeRecursiveTupleyySi_Sit_SitSgF
0 commit comments