diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp
index 8ea1c2000ef79..2697129bbfa57 100644
--- a/lib/SIL/IR/TypeLowering.cpp
+++ b/lib/SIL/IR/TypeLowering.cpp
@@ -2394,6 +2394,7 @@ namespace {
 
       if (D->isMoveOnly()) {
         properties.setNonTrivial();
+        properties.setLexical(IsLexical);
         if (properties.isAddressOnly())
           return handleMoveOnlyAddressOnly(structType, properties);
         return new (TC) MoveOnlyLoadableStructTypeLowering(
@@ -2475,6 +2476,7 @@ namespace {
 
       if (D->isMoveOnly()) {
         properties.setNonTrivial();
+        properties.setLexical(IsLexical);
         if (properties.isAddressOnly())
           return handleMoveOnlyAddressOnly(enumType, properties);
         return new (TC)
diff --git a/lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp b/lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp
index d3a2808d11379..ebf9a35bdd8e6 100644
--- a/lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp
+++ b/lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp
@@ -89,6 +89,7 @@
 #include "swift/SILOptimizer/Utils/InstructionDeleter.h"
 #include "swift/SILOptimizer/Utils/ParseTestSpecification.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 #include <iterator>
 #include <memory>
@@ -287,6 +288,19 @@ struct OwnershipUtilsHasPointerEscape : UnitTest {
   }
 };
 
+// Arguments:
+// - value: whose type will be printed
+// Dumps:
+// - the type lowering of the type
+struct PrintTypeLowering : UnitTest {
+  PrintTypeLowering(UnitTestRunner *pass) : UnitTest(pass) {}
+  void invoke(Arguments &arguments) override {
+    auto value = arguments.takeValue();
+    auto ty = value->getType();
+    getFunction()->getTypeLowering(ty).print(llvm::dbgs());
+  }
+};
+
 //===----------------------------------------------------------------------===//
 // MARK: OSSA Lifetime Unit Tests
 //===----------------------------------------------------------------------===//
@@ -899,6 +913,7 @@ void UnitTestRunner::withTest(StringRef name, Doit doit) {
     ADD_UNIT_TEST_SUBCLASS("find-enclosing-defs", FindEnclosingDefsTest)
     ADD_UNIT_TEST_SUBCLASS("function-get-self-argument-index", FunctionGetSelfArgumentIndex)
     ADD_UNIT_TEST_SUBCLASS("has-pointer-escape", OwnershipUtilsHasPointerEscape)
+    ADD_UNIT_TEST_SUBCLASS("print-type-lowering", PrintTypeLowering)
     ADD_UNIT_TEST_SUBCLASS("interior-liveness", InteriorLivenessTest)
     ADD_UNIT_TEST_SUBCLASS("is-deinit-barrier", IsDeinitBarrierTest)
     ADD_UNIT_TEST_SUBCLASS("is-lexical", IsLexicalTest)
diff --git a/test/SIL/type_lowering_unit.sil b/test/SIL/type_lowering_unit.sil
new file mode 100644
index 0000000000000..23e1ba35bbf64
--- /dev/null
+++ b/test/SIL/type_lowering_unit.sil
@@ -0,0 +1,18 @@
+// RUN: %target-sil-opt -unit-test-runner %s -o /dev/null 2>&1 | %FileCheck %s
+
+sil_stage raw
+
+import Builtin
+
+struct S : ~Copyable {}
+
+// CHECK-LABEL: begin {{.*}} print-type-lowering with: @argument[0]
+// CHECK:       isLexical: true
+// CHECK-LABEL: end {{.*}} print-type-lowering with: @argument[0]
+sil [ossa] @move_only_argument : $@convention(thin) (@owned S) -> () {
+bb0(%0 : @owned $S):
+  test_specification "print-type-lowering @argument[0]"
+  destroy_value %0 : $S
+  %retval = tuple ()
+  return %retval : $()
+}
diff --git a/test/SILGen/discard.swift b/test/SILGen/discard.swift
index abb4ba5d8a5ad..17a2e5a17360a 100644
--- a/test/SILGen/discard.swift
+++ b/test/SILGen/discard.swift
@@ -89,7 +89,8 @@ func invokedDeinit() {}
 // CHECK-LABEL: sil hidden [ossa] @$s4test11PointerTreeV10tryDestroy9doDiscardySb_tKF : $@convention(method) (Bool, @owned PointerTree) -> @error any Error {
 // CHECK:   bb0{{.*}}:
 // CHECK:     [[SELF_BOX:%.*]] = alloc_box ${ var PointerTree }, var, name "self"
-// CHECK:     [[SELF_PTR:%.*]] = project_box [[SELF_BOX]] : ${ var PointerTree }, 0
+// CHECK:     [[SELF_BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[SELF_BOX]]
+// CHECK:     [[SELF_PTR:%.*]] = project_box [[SELF_BOX_LIFETIME]] : ${ var PointerTree }, 0
 //            .. skip to the conditional test ..
 // CHECK:     [[SHOULD_FORGET:%.*]] = struct_extract {{.*}} : $Bool, #Bool._value
 // CHECK:     cond_br [[SHOULD_FORGET]], bb1, bb2
@@ -107,6 +108,7 @@ func invokedDeinit() {}
 // CHECK:     br bb3
 //
 // CHECK:   bb3:
+// CHECK:     end_borrow [[SELF_BOX_LIFETIME]]
 // CHECK:     destroy_value [[SELF_BOX]] : ${ var PointerTree }
 // CHECK:     throw
 // CHECK: } // end sil function
diff --git a/test/SILGen/moveonly.swift b/test/SILGen/moveonly.swift
index e25375482eb4e..a68c83106e85a 100644
--- a/test/SILGen/moveonly.swift
+++ b/test/SILGen/moveonly.swift
@@ -933,7 +933,8 @@ struct EmptyStruct {
   // CHECK-LABEL: sil hidden [ossa] @$s8moveonly11EmptyStructVACycfC : $@convention(method) (@thin EmptyStruct.Type) -> @owned EmptyStruct {
   // CHECK: [[BOX:%.*]] = alloc_box ${ var EmptyStruct }, var, name "self"
   // CHECK: [[MARKED_UNINIT:%.*]] = mark_uninitialized [rootself] [[BOX]]
-  // CHECK: [[PROJECT:%.*]] = project_box [[MARKED_UNINIT]]
+  // CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[MARKED_UNINIT]]
+  // CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
   // CHECK: [[STRUCT:%.*]] = struct $EmptyStruct ()
   // CHECK: store [[STRUCT]] to [init] [[PROJECT]]
   // CHECK: [[MV_CHECK:%.*]] = mark_must_check [assignable_but_not_consumable] [[PROJECT]]
@@ -1039,7 +1040,8 @@ public struct LoadableSubscriptGetOnlyTester : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly047testSubscriptGetOnly_BaseLoadable_ResultAddressE4_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -1077,7 +1079,8 @@ public func testSubscriptGetOnly_BaseLoadable_ResultAddressOnly_Var() {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly047testSubscriptGetOnly_BaseLoadable_ResultAddressE4_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
@@ -1140,7 +1143,8 @@ public struct LoadableSubscriptGetOnlyTesterNonCopyableStructParent : ~Copyable
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly077testSubscriptGetOnlyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressE4_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The first get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -1181,7 +1185,8 @@ public func testSubscriptGetOnlyThroughNonCopyableParentStruct_BaseLoadable_Resu
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly077testSubscriptGetOnlyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressE4_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box ${ let L
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
 // CHECK: [[LOAD:%.*]] = load_borrow [[MARK]]
@@ -1350,7 +1355,8 @@ public struct LoadableSubscriptGetSetTester : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly54testSubscriptGetSet_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -1396,7 +1402,8 @@ public func testSubscriptGetSet_BaseLoadable_ResultAddressOnly_Var() {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly54testSubscriptGetSet_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
@@ -1507,7 +1514,8 @@ public struct LoadableSubscriptGetSetTesterNonCopyableStructParent : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly84testSubscriptGetSetThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The first get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -1561,7 +1569,8 @@ public func testSubscriptGetSetThroughNonCopyableParentStruct_BaseLoadable_Resul
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly84testSubscriptGetSetThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box ${ let L
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
 // CHECK: [[LOAD:%.*]] = load_borrow [[MARK]]
@@ -1819,7 +1828,8 @@ public struct LoadableSubscriptReadSetTester : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly55testSubscriptReadSet_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The read call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -1865,7 +1875,8 @@ public func testSubscriptReadSet_BaseLoadable_ResultAddressOnly_Var() {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly55testSubscriptReadSet_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
@@ -1979,7 +1990,8 @@ public struct LoadableSubscriptReadSetTesterNonCopyableStructParent : ~Copyable
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly85testSubscriptReadSetThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The first get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -2031,7 +2043,8 @@ public func testSubscriptReadSetThroughNonCopyableParentStruct_BaseLoadable_Resu
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly85testSubscriptReadSetThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box ${ let L
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
 // CHECK: [[LOAD:%.*]] = load_borrow [[MARK]]
@@ -2285,7 +2298,8 @@ public struct LoadableSubscriptReadModifyTester : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly58testSubscriptReadModify_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The read call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -2328,7 +2342,8 @@ public func testSubscriptReadModify_BaseLoadable_ResultAddressOnly_Var() {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly58testSubscriptReadModify_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
@@ -2431,7 +2446,8 @@ public struct LoadableSubscriptReadModifyTesterNonCopyableStructParent : ~Copyab
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly88testSubscriptReadModifyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The first get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -2477,7 +2493,8 @@ public func testSubscriptReadModifyThroughNonCopyableParentStruct_BaseLoadable_R
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly88testSubscriptReadModifyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box ${ let L
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
 // CHECK: [[LOAD:%.*]] = load_borrow [[MARK]]
@@ -2699,7 +2716,8 @@ public struct LoadableSubscriptGetModifyTester : ~Copyable {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly57testSubscriptGetModify_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -2743,7 +2761,8 @@ public func testSubscriptGetModify_BaseLoadable_ResultAddressOnly_Var() {
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly57testSubscriptGetModify_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The get call
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
@@ -2850,7 +2869,8 @@ public struct LoadableSubscriptGetModifyTesterNonCopyableStructParent : ~Copyabl
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly87testSubscriptGetModifyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_VaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box $
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // The first get call
 // CHECK: [[ACCESS:%.*]] = begin_access [read] [unknown] [[PROJECT]]
@@ -2900,7 +2920,8 @@ public func testSubscriptGetModifyThroughNonCopyableParentStruct_BaseLoadable_Re
 
 // CHECK-LABEL: sil [ossa] @$s8moveonly87testSubscriptGetModifyThroughNonCopyableParentStruct_BaseLoadable_ResultAddressOnly_LetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box ${ let L
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 //
 // CHECK: [[MARK:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT]]
 // CHECK: [[LOAD:%.*]] = load_borrow [[MARK]]
diff --git a/test/SILGen/moveonly_deinits.swift b/test/SILGen/moveonly_deinits.swift
index 73a7353966af0..88a6fd778ef20 100644
--- a/test/SILGen/moveonly_deinits.swift
+++ b/test/SILGen/moveonly_deinits.swift
@@ -83,7 +83,8 @@ var value: Bool { false }
 
 // SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits24testIntPairWithoutDeinityyF : $@convention(thin) () -> () {
 // SILGEN: [[BOX:%.*]] = alloc_box
-// SILGEN: [[PROJECT:%.*]] = project_box [[BOX]]
+// SILGEN: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// SILGEN: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // SILGEN: cond_br {{%.*}}, bb1, bb2
 //
 // SILGEN: bb1:
@@ -132,7 +133,8 @@ public func testIntPairWithoutDeinit() {
 
 // SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits21testIntPairWithDeinityyF : $@convention(thin) () -> () {
 // SILGEN: [[BOX:%.*]] = alloc_box
-// SILGEN: [[PROJECT:%.*]] = project_box [[BOX]]
+// SILGEN: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// SILGEN: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // SILGEN: cond_br {{%.*}}, bb1, bb2
 //
 // SILGEN: bb1:
@@ -343,7 +345,8 @@ func consumeKlassEnumPairWithDeinit(_ x: __owned KlassEnumPairWithDeinit) { }
 
 // SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits28testIntEnumPairWithoutDeinityyF : $@convention(thin) () -> () {
 // SILGEN: [[BOX:%.*]] = alloc_box
-// SILGEN: [[PROJECT:%.*]] = project_box [[BOX]]
+// SILGEN: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// SILGEN: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // SILGEN: cond_br {{%.*}}, bb1, bb2
 //
 // SILGEN: bb1:
@@ -391,7 +394,8 @@ public func testIntEnumPairWithoutDeinit() {
 
 // SILGEN-LABEL: sil [ossa] @$s16moveonly_deinits25testIntEnumPairWithDeinityyF : $@convention(thin) () -> () {
 // SILGEN: [[BOX:%.*]] = alloc_box
-// SILGEN: [[PROJECT:%.*]] = project_box [[BOX]]
+// SILGEN: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// SILGEN: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // SILGEN: cond_br {{%.*}}, bb1, bb2
 //
 // SILGEN: bb1:
diff --git a/test/SILGen/moveonly_enum_literal.swift b/test/SILGen/moveonly_enum_literal.swift
index 4d566835f4b83..13555bce43a40 100644
--- a/test/SILGen/moveonly_enum_literal.swift
+++ b/test/SILGen/moveonly_enum_literal.swift
@@ -16,7 +16,8 @@ var value: Bool { false }
 
 // CHECK-LABEL: sil hidden [ossa] @$s21moveonly_enum_literal4testyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[VALUE:%.*]] = enum $MoveOnlyIntPair, #MoveOnlyIntPair.lhs!enumelt,
 // CHECK: store [[VALUE]] to [init] [[PROJECT]]
 //
diff --git a/test/SILGen/moveonly_escaping_closure.swift b/test/SILGen/moveonly_escaping_closure.swift
index 1b20481e0147e..3977658feebb9 100644
--- a/test/SILGen/moveonly_escaping_closure.swift
+++ b/test/SILGen/moveonly_escaping_closure.swift
@@ -24,9 +24,10 @@ func borrowConsumeVal(_ x: borrowing SingleElt, _ y: consuming SingleElt) {}
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure27testGlobalClosureCaptureVaryyF : $@convention(thin) () -> () {
 // CHECK: [[GLOBAL:%.*]] = global_addr @$s16moveonly_closure23globalClosureCaptureVaryycvp
 // CHECK: [[BOX:%.*]] = alloc_box ${ var SingleElt }
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure27testGlobalClosureCaptureVaryyFyycfU_ : $@convention(thin) (@guaranteed { var SingleElt }) -> ()
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[GLOBAL]]
 // CHECK: assign [[PAI]] to [[ACCESS]]
@@ -84,8 +85,9 @@ func testGlobalClosureCaptureVar() {
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure29testLocalLetClosureCaptureVaryyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [[PAI]]
@@ -151,8 +153,9 @@ func testLocalLetClosureCaptureVar() {
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure026testLocalVarClosureCaptureE0yyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: } // end sil function '$s16moveonly_closure026testLocalVarClosureCaptureE0yyF'
@@ -209,9 +212,10 @@ func testLocalVarClosureCaptureVar() {
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure026testInOutVarClosureCaptureF0yyyyczF : $@convention(thin) (@inout @callee_guaranteed () -> ()) -> () {
 // CHECK: bb0([[F:%.*]] : $*@callee_guaranteed () -> ()):
 // CHECK: [[BOX:%.*]] = alloc_box ${ var SingleElt }
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure026testInOutVarClosureCaptureF0yyyyczFyycfU_ : $@convention(thin) (@guaranteed { var SingleElt }) -> ()
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[F]]
 // CHECK: assign [[PAI]] to [[ACCESS]]
@@ -275,9 +279,10 @@ func testInOutVarClosureCaptureVar(_ f: inout () -> ()) {
 // CHECK:   store [[ARG]] to [init] [[UNWRAP]]
 //
 // CHECK:   [[BOX:%.*]] = alloc_box ${ var SingleElt }
-// CHECK:   [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK:   [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK:   [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK:   [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure36testConsumingEscapeClosureCaptureVaryyyycnFyycfU_ : $@convention(thin) (@guaranteed { var SingleElt })
-// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK:   mark_function_escape [[PROJECT]]
 // CHECK:   [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unknown] [[FUNC_PROJECT]]
@@ -342,9 +347,10 @@ func testConsumingEscapeClosureCaptureVar(_ f: consuming @escaping () -> ()) {
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure27testGlobalClosureCaptureLetyyF : $@convention(thin) () -> () {
 // CHECK: [[GLOBAL:%.*]] = global_addr @$s16moveonly_closure23globalClosureCaptureLetyycvp
 // CHECK: [[BOX:%.*]] = alloc_box ${ let SingleElt }
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure27testGlobalClosureCaptureLetyyFyycfU_ : $@convention(thin) (@guaranteed { let SingleElt }) -> ()
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[GLOBAL]]
 // CHECK: assign [[PAI]] to [[ACCESS]]
@@ -388,8 +394,9 @@ func testGlobalClosureCaptureLet() {
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure026testLocalLetClosureCaptureE0yyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [[PAI]]
@@ -437,8 +444,9 @@ func testLocalLetClosureCaptureLet() {
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure29testLocalVarClosureCaptureLetyyF : $@convention(thin) () -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: } // end sil function '$s16moveonly_closure29testLocalVarClosureCaptureLetyyF'
@@ -482,9 +490,10 @@ func testLocalVarClosureCaptureLet() {
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure29testInOutVarClosureCaptureLetyyyyczF : $@convention(thin) (@inout @callee_guaranteed () -> ()) -> () {
 // CHECK: bb0([[F:%.*]] : $*@callee_guaranteed () -> ()):
 // CHECK: [[BOX:%.*]] = alloc_box ${ let SingleElt }
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure29testInOutVarClosureCaptureLetyyyyczFyycfU_ : $@convention(thin) (@guaranteed { let SingleElt }) -> ()
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK: [[ACCESS:%.*]] = begin_access [modify] [unknown] [[F]]
 // CHECK: assign [[PAI]] to [[ACCESS]]
@@ -530,14 +539,15 @@ func testInOutVarClosureCaptureLet(_ f: inout () -> ()) {
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure36testConsumingEscapeClosureCaptureLetyyyycnF : $@convention(thin) (@owned @callee_guaranteed () -> ()) -> () {
 // CHECK: bb0([[ARG:%.*]] : @noImplicitCopy @_eagerMove @owned
 // CHECK:   [[FUNC_BOX:%.*]] = alloc_box ${ var @moveOnly @callee_guaranteed () -> () }
-// CHECK:   [[FUNC_PROJECT:%.*]] = project_box [[FUNC_BOX]]
+// CHECK:   [[PROJECT:%.*]] = project_box [[FUNC_BOX]]
 // CHECK:   [[UNWRAP:%.*]] = moveonlywrapper_to_copyable_addr [[FUNC_PROJECT]]
 // CHECK:   store [[ARG]] to [init] [[UNWRAP]]
 //
 // CHECK:   [[BOX:%.*]] = alloc_box ${ let SingleElt }
-// CHECK:   [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK:   [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK:   [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK:   [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure36testConsumingEscapeClosureCaptureLetyyyycnFyycfU_ : $@convention(thin) (@guaranteed { let SingleElt })
-// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK:   mark_function_escape [[PROJECT]]
 // CHECK:   [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unknown] [[FUNC_PROJECT]]
@@ -840,9 +850,10 @@ func testConsumingEscapeClosureCaptureInOut(_ f: consuming @escaping () -> (), _
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure33testGlobalClosureCaptureConsumingyyAA9SingleEltVnF : $@convention(thin) (@owned SingleElt) -> () {
 // CHECK: [[GLOBAL:%.*]] = global_addr @$s16moveonly_closure29globalClosureCaptureConsumingyycvp
 // CHECK: [[BOX:%.*]] = alloc_box ${ var SingleElt }
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK: [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure33testGlobalClosureCaptureConsumingyyAA9SingleEltVnFyycfU_ : $@convention(thin) (@guaranteed { var SingleElt }) -> ()
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK: [[ACCESS:%.*]] = begin_access [modify] [dynamic] [[GLOBAL]]
 // CHECK: assign [[PAI]] to [[ACCESS]]
@@ -898,8 +909,9 @@ func testGlobalClosureCaptureConsuming(_ x: consuming SingleElt) {
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure35testLocalLetClosureCaptureConsumingyyAA9SingleEltVnF : $@convention(thin) (@owned SingleElt) -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: [[BORROW_PAI:%.*]] = begin_borrow [lexical] [[PAI]]
@@ -976,8 +988,9 @@ func testLocalLetClosureCaptureConsuming2(_ x: consuming SingleElt) -> (() -> ()
 
 // CHECK-LABEL: sil hidden [ossa] @$s16moveonly_closure35testLocalVarClosureCaptureConsumingyyAA9SingleEltVnF : $@convention(thin) (@owned SingleElt) -> () {
 // CHECK: [[BOX:%.*]] = alloc_box
-// CHECK: [[PROJECT:%.*]] = project_box [[BOX]]
-// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK: [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK: [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
+// CHECK: [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK: mark_function_escape [[PROJECT]]
 // CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX_COPY]])
 // CHECK: } // end sil function '$s16moveonly_closure35testLocalVarClosureCaptureConsumingyyAA9SingleEltVnF'
@@ -1038,9 +1051,10 @@ func testLocalVarClosureCaptureConsuming(_ x: consuming SingleElt) {
 // CHECK:   store [[ARG]] to [init] [[UNWRAP]]
 //
 // CHECK:   [[BOX:%.*]] = alloc_box ${ var SingleElt }
-// CHECK:   [[PROJECT:%.*]] = project_box [[BOX]]
+// CHECK:   [[BOX_LIFETIME:%.*]] = begin_borrow [lexical] [[BOX]]
+// CHECK:   [[PROJECT:%.*]] = project_box [[BOX_LIFETIME]]
 // CHECK:   [[CLOSURE:%.*]] = function_ref @$s16moveonly_closure033testConsumingEscapeClosureCaptureD0yyyycn_AA9SingleEltVntFyycfU_ : $@convention(thin) (@guaranteed { var SingleElt }) -> ()
-// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX]]
+// CHECK:   [[BOX_COPY:%.*]] = copy_value [[BOX_LIFETIME]]
 // CHECK:   mark_function_escape [[PROJECT]]
 // CHECK:   [[PAI:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE]]([[BOX_COPY]])
 // CHECK:   [[ACCESS:%.*]] = begin_access [modify] [unknown] [[FUNC_PROJECT]]