diff --git a/include/swift/SIL/SILUndef.h b/include/swift/SIL/SILUndef.h index ecbf54df084aa..3fda7fcf1f8d7 100644 --- a/include/swift/SIL/SILUndef.h +++ b/include/swift/SIL/SILUndef.h @@ -30,6 +30,12 @@ class SILUndef : public ValueBase { void operator delete(void *, size_t) = delete; static SILUndef *get(SILType ty, SILModule &m); + + /// Return a SILUndef with the same type as the passed in value. + static SILUndef *get(SILValue value) { + return SILUndef::get(value->getType(), *value->getModule()); + } + static SILUndef *get(SILType ty, const SILFunction &f); template diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 82bd77375ea3b..ca9603ee27440 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2385,7 +2385,7 @@ struct DeallocatorConventions : Conventions { ParameterConvention getIndirectSelfParameter(const AbstractionPattern &type) const override { - llvm_unreachable("Deallocators do not have indirect self parameters"); + return ParameterConvention::Indirect_In; } static bool classof(const Conventions *C) { diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 2096bf713ecd3..cdbb8fea57b78 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -674,6 +674,7 @@ struct ImmutableAddressUseVerifier { case SILInstructionKind::IndexAddrInst: case SILInstructionKind::TailAddrInst: case SILInstructionKind::IndexRawPointerInst: + case SILInstructionKind::MarkMustCheckInst: // Add these to our worklist. for (auto result : inst->getResults()) { llvm::copy(result->getUses(), std::back_inserter(worklist)); diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index 13acfd94ef1b9..476996c7f111c 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -3183,7 +3183,8 @@ RValue SILGenFunction::emitRValueForNonMemberVarDecl(SILLocation loc, SILValue accessAddr = UnenforcedFormalAccess::enter(*this, loc, destAddr, SILAccessKind::Read); - if (accessAddr->getType().isMoveOnly()) { + if (accessAddr->getType().isMoveOnly() && + !isa(accessAddr)) { // When loading an rvalue, we should never need to modify the place // we're loading from. accessAddr = B.createMarkMustCheckInst( diff --git a/lib/SILGen/SILGenProlog.cpp b/lib/SILGen/SILGenProlog.cpp index 0cc7854adcb2e..d4684b2d00f55 100644 --- a/lib/SILGen/SILGenProlog.cpp +++ b/lib/SILGen/SILGenProlog.cpp @@ -40,7 +40,7 @@ static void diagnose(ASTContext &Context, SourceLoc loc, Diag diag, SILValue SILGenFunction::emitSelfDeclForDestructor(VarDecl *selfDecl) { // Emit the implicit 'self' argument. - SILType selfType = getLoweredLoadableType(selfDecl->getType()); + SILType selfType = getLoweredType(selfDecl->getType()); SILValue selfValue = F.begin()->createFunctionArgument(selfType, selfDecl); // If we have a move only type, then mark it with mark_must_check so we can't @@ -748,7 +748,6 @@ class ArgumentInitHelper { /// if not null. void makeArgumentIntoBinding(SILLocation loc, ParamDecl *pd) { ManagedValue argrv = makeArgument(loc, pd); - SILValue value = argrv.getValue(); if (pd->isInOut()) { assert(argrv.getType().isAddress() && "expected inout to be address"); @@ -768,18 +767,52 @@ class ArgumentInitHelper { if (!argrv.getType().isAddress()) { // NOTE: We setup SGF.VarLocs[pd] in updateArgumentValueForBinding. updateArgumentValueForBinding(argrv, loc, pd, value, varinfo); - } else { - if (auto *allocStack = dyn_cast(value)) { - allocStack->setArgNo(ArgNo); - if (SGF.getASTContext().SILOpts.supportsLexicalLifetimes( - SGF.getModule()) && - SGF.F.getLifetime(pd, value->getType()).isLexical()) - allocStack->setIsLexical(); - } else { - SGF.B.createDebugValueAddr(loc, value, varinfo); - } + return; + } + + if (auto *allocStack = dyn_cast(value)) { + allocStack->setArgNo(ArgNo); + if (SGF.getASTContext().SILOpts.supportsLexicalLifetimes( + SGF.getModule()) && + SGF.F.getLifetime(pd, value->getType()).isLexical()) + allocStack->setIsLexical(); SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(value); + return; + } + + if (value->getType().isMoveOnly()) { + switch (pd->getValueOwnership()) { + case ValueOwnership::Default: + if (pd->isSelfParameter()) { + assert(!isa(value) && + "Should not have inserted mark must check inst in EmitBBArgs"); + if (!pd->isInOut()) { + value = SGF.B.createMarkMustCheckInst( + loc, value, MarkMustCheckInst::CheckKind::NoConsumeOrAssign); + } + } else { + assert(isa(value) && + "Should have inserted mark must check inst in EmitBBArgs"); + } + break; + case ValueOwnership::InOut: + assert(isa(value) && + "Expected mark must check inst with inout to be handled in " + "emitBBArgs earlier"); + break; + case ValueOwnership::Owned: + value = SGF.B.createMarkMustCheckInst( + loc, value, MarkMustCheckInst::CheckKind::ConsumableAndAssignable); + break; + case ValueOwnership::Shared: + value = SGF.B.createMarkMustCheckInst( + loc, value, MarkMustCheckInst::CheckKind::NoConsumeOrAssign); + break; + } } + + SGF.B.createDebugValueAddr(loc, value, varinfo); + SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(value); } void emitParam(ParamDecl *PD) { diff --git a/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp b/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp index 551009a8aa60f..132e5e549dacb 100644 --- a/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp +++ b/lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp @@ -1511,6 +1511,19 @@ bool GatherUsesVisitor::visitUse(Operand *op) { assert(op->getOperandNumber() == CopyAddrInst::Src && "Should have dest above in memInstMust{Rei,I}nitialize"); + auto leafRange = TypeTreeLeafTypeRange::get(op->get(), getRootAddress()); + if (!leafRange) + return false; + + // If we have a non-move only type, just treat this as a liveness use. + if (!copyAddr->getSrc()->getType().isMoveOnly()) { + LLVM_DEBUG(llvm::dbgs() + << "Found copy of copyable type. Treating as liveness use! " + << *user); + useState.livenessUses.insert({user, *leafRange}); + return true; + } + if (markedValue->getCheckKind() == MarkMustCheckInst::CheckKind::NoConsumeOrAssign) { LLVM_DEBUG(llvm::dbgs() @@ -1520,17 +1533,11 @@ bool GatherUsesVisitor::visitUse(Operand *op) { return true; } - auto leafRange = TypeTreeLeafTypeRange::get(op->get(), getRootAddress()); - if (!leafRange) - return false; - // TODO: Add borrow checking here like below. // TODO: Add destructure deinit checking here once address only checking is // completely brought up. - // TODO: Add check here that we don't error on trivial/copyable types. - if (copyAddr->isTakeOfSrc()) { LLVM_DEBUG(llvm::dbgs() << "Found take: " << *user); useState.takeInsts.insert({user, *leafRange}); @@ -1721,9 +1728,30 @@ bool GatherUsesVisitor::visitUse(Operand *op) { // Now that we have handled or loadTakeOrCopy, we need to now track our // additional pure takes. if (::memInstMustConsume(op)) { + // If we don't have a consumeable and assignable check kind, then we can't + // consume. Emit an error. + // + // NOTE: Since SILGen eagerly loads loadable types from memory, this + // generally will only handle address only types. + if (markedValue->getCheckKind() != + MarkMustCheckInst::CheckKind::ConsumableAndAssignable) { + auto *fArg = dyn_cast( + stripAccessMarkers(markedValue->getOperand())); + if (fArg && fArg->isClosureCapture() && fArg->getType().isAddress()) { + moveChecker.diagnosticEmitter.emitPromotedBoxArgumentError(markedValue, + fArg); + } else { + moveChecker.diagnosticEmitter + .emitAddressEscapingClosureCaptureLoadedAndConsumed(markedValue); + } + emittedEarlyDiagnostic = true; + return true; + } + auto leafRange = TypeTreeLeafTypeRange::get(op->get(), getRootAddress()); if (!leafRange) return false; + LLVM_DEBUG(llvm::dbgs() << "Pure consuming use: " << *user); useState.takeInsts.insert({user, *leafRange}); return true; @@ -2423,7 +2451,6 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck( LLVM_DEBUG(llvm::dbgs() << "Failed access path visit: " << *markedAddress); return false; } - addressUseState.initializeInOutTermUsers(); // If we found a load [copy] or copy_addr that requires multiple copies or an // exclusivity error, then we emitted an early error. Bail now and allow the @@ -2438,9 +2465,14 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck( if (diagCount != diagnosticEmitter.getDiagnosticCount()) return true; - // Then check if we emitted an error. If we did not, return true. - if (diagCount != diagnosticEmitter.getDiagnosticCount()) - return true; + // Now that we know that we have run our visitor and did not emit any errors + // and successfully visited everything, see if have any + // assignable_but_not_consumable of address only types that are consumed. + // + // DISCUSSION: For non address only types, this is not an issue since we + // eagerly load + + addressUseState.initializeInOutTermUsers(); //===--- // Liveness Checking diff --git a/test/Interpreter/moveonly.swift b/test/Interpreter/moveonly.swift index aa18cf5f1d4de..96a4b75a673f6 100644 --- a/test/Interpreter/moveonly.swift +++ b/test/Interpreter/moveonly.swift @@ -45,7 +45,7 @@ Tests.test("global destroyed once") { do { global = FD() } - expectEqual(0, LifetimeTracked.instances) + expectEqual(0, LifetimeTracked.instances) } @_moveOnly @@ -104,3 +104,31 @@ Tests.test("empty struct") { let _ = consume e } } + +protocol P { + var name: String { get } +} + +Tests.test("AddressOnly") { + class Klass : P { + var name: String { "myName" } + } + + @_moveOnly + struct S { + var t: T + } + + let e = S(t: Klass()) + expectEqual(e.t.name, "myName") + + func testGeneric(_ x: borrowing S) { + expectEqual(x.t.name, "myName") + } + testGeneric(e) + + if e.t.name.count == 5 { + let _ = consume e + } +} + diff --git a/test/SILGen/moveonly.swift b/test/SILGen/moveonly.swift index 08c2ac430458a..678292f4b7331 100644 --- a/test/SILGen/moveonly.swift +++ b/test/SILGen/moveonly.swift @@ -44,6 +44,18 @@ public enum NonTrivialEnum { case third(NonTrivialStruct) } +@_moveOnly +public struct AddressOnlyGeneric { + var t: T +} + +public protocol P {} + +@_moveOnly +public struct AddressOnlyProtocol { + var t: P +} + var varGlobal = NonTrivialStruct() let letGlobal = NonTrivialStruct() @@ -54,6 +66,8 @@ public func borrowVal(_ k: borrowing NonTrivialCopyableStruct) {} public func borrowVal(_ k: borrowing NonTrivialCopyableStruct2) {} public func borrowVal(_ s: borrowing NonTrivialStruct) {} public func borrowVal(_ s: borrowing NonTrivialStruct2) {} +public func borrowVal(_ s: borrowing AddressOnlyGeneric) {} +public func borrowVal(_ s: borrowing AddressOnlyProtocol) {} public func consumeVal(_ e : __owned NonTrivialEnum) {} public func consumeVal(_ e : __owned FD) {} @@ -62,6 +76,8 @@ public func consumeVal(_ k: __owned NonTrivialCopyableStruct) {} public func consumeVal(_ k: __owned NonTrivialCopyableStruct2) {} public func consumeVal(_ s: __owned NonTrivialStruct) {} public func consumeVal(_ s: __owned NonTrivialStruct2) {} +public func consumeVal(_ s: __owned AddressOnlyGeneric) {} +public func consumeVal(_ s: __owned AddressOnlyProtocol) {} var bool: Bool { false } @@ -137,6 +153,58 @@ public func useNonTrivialOwnedEnum(_ s: __owned NonTrivialEnum) { let _ = s2 } +// CHECK-LABEL: sil [ossa] @$s8moveonly21useAddressOnlyGenericyyAA0cdE0VyxGhlF : $@convention(thin) (@in_guaranteed AddressOnlyGeneric) -> () { +// CHECK: bb0([[ARG:%.*]] : +// CHECK: mark_must_check [no_consume_or_assign] [[ARG]] +// CHECK: } // end sil function '$s8moveonly21useAddressOnlyGenericyyAA0cdE0VyxGhlF' +public func useAddressOnlyGeneric(_ s: __shared AddressOnlyGeneric) { + borrowVal(s) + let s2 = s + let k = s.t + let _ = k + borrowVal(s) + let _ = s2 +} + +// CHECK-LABEL: sil [ossa] @$s8moveonly26useOwnedAddressOnlyGenericyyAA0deF0VyxGnlF : $@convention(thin) (@in AddressOnlyGeneric) -> () { +// CHECK: bb0([[ARG:%.*]] : +// CHECK: mark_must_check [consumable_and_assignable] [[ARG]] +// CHECK: } // end sil function '$s8moveonly26useOwnedAddressOnlyGenericyyAA0deF0VyxGnlF' +public func useOwnedAddressOnlyGeneric(_ s: __owned AddressOnlyGeneric) { + borrowVal(s) + let s2 = s + let k = s.t + let _ = k + borrowVal(s) + let _ = s2 +} + +// CHECK-LABEL: sil [ossa] @$s8moveonly22useAddressOnlyProtocolyyAA0cdE0VhF : $@convention(thin) (@in_guaranteed AddressOnlyProtocol) -> () { +// CHECK: bb0([[ARG:%.*]] : +// CHECK: mark_must_check [no_consume_or_assign] [[ARG]] +// CHECK: } // end sil function '$s8moveonly22useAddressOnlyProtocolyyAA0cdE0VhF' +public func useAddressOnlyProtocol(_ s: __shared AddressOnlyProtocol) { + borrowVal(s) + let s2 = s + let k = s.t + let _ = k + borrowVal(s) + let _ = s2 +} + +// CHECK-LABEL: sil [ossa] @$s8moveonly27useOwnedAddressOnlyProtocolyyAA0deF0VnF : $@convention(thin) (@in AddressOnlyProtocol) -> () { +// CHECK: bb0([[ARG:%.*]] : +// CHECK: mark_must_check [consumable_and_assignable] [[ARG]] +// CHECK: } // end sil function '$s8moveonly27useOwnedAddressOnlyProtocolyyAA0deF0VnF' +public func useOwnedAddressOnlyProtocol(_ s: __owned AddressOnlyProtocol) { + borrowVal(s) + let s2 = s + let k = s.t + let _ = k + borrowVal(s) + let _ = s2 +} + //===--- // Self in Init // @@ -169,6 +237,73 @@ extension NonTrivialEnum { } } +extension AddressOnlyGeneric { + // CHECK-LABEL: sil hidden [ossa] @$s8moveonly18AddressOnlyGenericV13testNoUseSelfyyF : $@convention(method) (@in_guaranteed AddressOnlyGeneric) -> () { + // CHECK: bb0([[ARG_IN:%.*]] : + // CHECK: [[ARG:%.*]] = mark_must_check [no_consume_or_assign] [[ARG_IN]] : + // + // CHECK: [[ALLOC_X:%.*]] = alloc_box $<τ_0_0> { let AddressOnlyGeneric<τ_0_0> } , let, name "x" + // CHECK: [[X:%.*]] = begin_borrow [lexical] [[ALLOC_X]] + // CHECK: [[PROJECT_X:%.*]] = project_box [[X]] + // CHECK: copy_addr [[ARG]] to [init] [[PROJECT_X]] + // CHECK: [[MARKED_X:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT_X]] + // CHECK: [[BLACKHOLE_ADDR:%.*]] = alloc_stack $AddressOnlyGeneric + // CHECK: copy_addr [[MARKED_X]] to [init] [[BLACKHOLE_ADDR]] + // CHECK: destroy_addr [[BLACKHOLE_ADDR]] + // CHECK: dealloc_stack [[BLACKHOLE_ADDR]] + // + // CHECK: [[ALLOC_Y:%.*]] = alloc_box $<τ_0_0> { let AddressOnlyGeneric<τ_0_0> } , let, name "y" + // CHECK: [[Y:%.*]] = begin_borrow [lexical] [[ALLOC_Y]] + // CHECK: [[PROJECT_Y:%.*]] = project_box [[Y]] + // CHECK: copy_addr [[ARG]] to [init] [[PROJECT_Y]] + // CHECK: [[MARKED_Y:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT_Y]] + // CHECK: [[BLACKHOLE_ADDR:%.*]] = alloc_stack $AddressOnlyGeneric + // CHECK: copy_addr [[MARKED_Y]] to [init] [[BLACKHOLE_ADDR]] + // CHECK: destroy_addr [[BLACKHOLE_ADDR]] + // CHECK: dealloc_stack [[BLACKHOLE_ADDR]] + // + // CHECK: } // end sil function '$s8moveonly18AddressOnlyGenericV13testNoUseSelfyyF' + func testNoUseSelf() { + let x = self + let _ = x + let y = self + let _ = y + } +} + +extension AddressOnlyProtocol { + // CHECK-LABEL: sil hidden [ossa] @$s8moveonly19AddressOnlyProtocolV13testNoUseSelfyyF : $@convention(method) (@in_guaranteed AddressOnlyProtocol) -> () { + // CHECK: bb0([[ARG_IN:%.*]] : + // CHECK: [[ARG:%.*]] = mark_must_check [no_consume_or_assign] [[ARG_IN]] : + // + // CHECK: [[ALLOC_X:%.*]] = alloc_box ${ let AddressOnlyProtocol }, let, name "x" + // CHECK: [[X:%.*]] = begin_borrow [lexical] [[ALLOC_X]] + // CHECK: [[PROJECT_X:%.*]] = project_box [[X]] + // CHECK: copy_addr [[ARG]] to [init] [[PROJECT_X]] + // CHECK: [[MARKED_X:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT_X]] + // CHECK: [[BLACKHOLE_ADDR:%.*]] = alloc_stack $AddressOnlyProtocol + // CHECK: copy_addr [[MARKED_X]] to [init] [[BLACKHOLE_ADDR]] + // CHECK: destroy_addr [[BLACKHOLE_ADDR]] + // CHECK: dealloc_stack [[BLACKHOLE_ADDR]] + // + // CHECK: [[ALLOC_Y:%.*]] = alloc_box ${ let AddressOnlyProtocol }, let, name "y" + // CHECK: [[Y:%.*]] = begin_borrow [lexical] [[ALLOC_Y]] + // CHECK: [[PROJECT_Y:%.*]] = project_box [[Y]] + // CHECK: copy_addr [[ARG]] to [init] [[PROJECT_Y]] + // CHECK: [[MARKED_Y:%.*]] = mark_must_check [no_consume_or_assign] [[PROJECT_Y]] + // CHECK: [[BLACKHOLE_ADDR:%.*]] = alloc_stack $AddressOnlyProtocol + // CHECK: copy_addr [[MARKED_Y]] to [init] [[BLACKHOLE_ADDR]] + // CHECK: destroy_addr [[BLACKHOLE_ADDR]] + // CHECK: dealloc_stack [[BLACKHOLE_ADDR]] + // CHECK: } // end sil function '$s8moveonly19AddressOnlyProtocolV13testNoUseSelfyyF' + func testNoUseSelf() { + let x = self + let _ = x + let y = self + let _ = y + } +} + /////////////////////////////// // Black Hole Initialization // /////////////////////////////// diff --git a/test/SILOptimizer/move_only_checker_addressonly_fail.swift b/test/SILOptimizer/move_only_checker_addressonly_fail.swift index 5b68cf46a6af2..4b752989a3df5 100644 --- a/test/SILOptimizer/move_only_checker_addressonly_fail.swift +++ b/test/SILOptimizer/move_only_checker_addressonly_fail.swift @@ -10,8 +10,12 @@ struct GenericAggregate { func test1(_ x: T) { @_noImplicitCopy let x2 = x // expected-error {{@_noImplicitCopy can not be used on a generic or existential typed binding or a nominal type containing such typed things}} - consumeValue(x2) // expected-error {{'x2' has guaranteed ownership but was consumed}} - // expected-note @-1 {{consuming use here}} - consumeValue(x2) // expected-error {{'x2' has guaranteed ownership but was consumed}} - // expected-note @-1 {{consuming use here}} + // These fail b/c we use an unchecked_addr_cast to convert addresses from + // @moveOnly to non-@moveOnly. We should change moveonly_to_copyable to + // handle addresses as well. + // + // An earlier change, I believe made it so that SILGen did not emit these + // unchecked_addr_cast. + consumeValue(x2) // expected-error {{Usage of @noImplicitCopy that the move checker does not know how to check!}} + consumeValue(x2) // expected-error {{Usage of @noImplicitCopy that the move checker does not know how to check!}} } diff --git a/test/SILOptimizer/moveonly_addresschecker.sil b/test/SILOptimizer/moveonly_addresschecker.sil index 8b4b27539b8ac..0c2b250e6ccc1 100644 --- a/test/SILOptimizer/moveonly_addresschecker.sil +++ b/test/SILOptimizer/moveonly_addresschecker.sil @@ -526,7 +526,7 @@ sil [ossa] @test_in_use : $@convention(thin) () -> () { %9 = function_ref @getNonTrivialStruct : $@convention(thin) () -> @owned NonTrivialStruct %10 = apply %9() : $@convention(thin) () -> @owned NonTrivialStruct %0 = alloc_stack [moveable_value_debuginfo] $NonTrivialStruct - %2 = mark_must_check [assignable_but_not_consumable] %0 : $*NonTrivialStruct + %2 = mark_must_check [consumable_and_assignable] %0 : $*NonTrivialStruct store %10 to [init] %2 : $*NonTrivialStruct %f2 = function_ref @consumeNonTrivialStructAddr : $@convention(thin) (@in NonTrivialStruct) -> () apply %f2(%2) : $@convention(thin) (@in NonTrivialStruct) -> () diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil index 3ac609dee69d0..a9a53189faa22 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.sil @@ -59,12 +59,30 @@ public struct AggStruct { var pair: KlassPair } +protocol P { + static var value: Self { get } + static var value2: any P { get } +} + +@_moveOnly +public struct AddressOnlyGeneric { + var copyable: T + var moveOnly: NonTrivialStruct + + init() + init(_ input1: T) +} + sil @get_aggstruct : $@convention(thin) () -> @owned AggStruct sil @nonConsumingUseKlass : $@convention(thin) (@guaranteed Klass) -> () sil @nonConsumingUseNonTrivialStruct : $@convention(thin) (@guaranteed NonTrivialStruct) -> () sil @classConsume : $@convention(thin) (@owned Klass) -> () // user: %18 sil @copyableClassConsume : $@convention(thin) (@owned CopyableKlass) -> () // user: %24 sil @copyableClassUseMoveOnlyWithoutEscaping : $@convention(thin) (@guaranteed CopyableKlass) -> () // user: %16 +sil @getAddressOnlyGeneric : $@convention(thin) <τ_0_0 where τ_0_0 : P> () -> @out AddressOnlyGeneric<τ_0_0> +sil @addressOnlyGenericInOutUse : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@inout AddressOnlyGeneric<τ_0_0>) -> () +sil @addressOnlyGenericConsume : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> () +sil @addressOnlyGenericUse : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed AddressOnlyGeneric<τ_0_0>) -> () /////////// // Tests // @@ -316,3 +334,34 @@ bb0(%0 : $*Klass): %27 = tuple () return %27 : $() } + +//////////////////////// +// Address Only Tests // +//////////////////////// + +sil [ossa] @inoutCaptureTestAddressOnlyGenericClosure2 : $@convention(thin) (@guaranteed <τ_0_0 where τ_0_0 : P> { var AddressOnlyGeneric<τ_0_0> } ) -> () { +bb0(%0 : @closureCapture @guaranteed $<τ_0_0 where τ_0_0 : P> { var AddressOnlyGeneric<τ_0_0> } ): + %1 = project_box %0 : $<τ_0_0 where τ_0_0 : P> { var AddressOnlyGeneric<τ_0_0> } , 0 + debug_value %1 : $*AddressOnlyGeneric, var, name "x", argno 1, expr op_deref + %3 = alloc_stack $AddressOnlyGeneric + %5 = function_ref @getAddressOnlyGeneric : $@convention(thin) <τ_0_0 where τ_0_0 : P> () -> @out AddressOnlyGeneric<τ_0_0> + %6 = apply %5(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> () -> @out AddressOnlyGeneric<τ_0_0> + %7 = begin_access [modify] [dynamic] %1 : $*AddressOnlyGeneric + %8 = mark_must_check [assignable_but_not_consumable] %7 : $*AddressOnlyGeneric + copy_addr [take] %3 to %8 : $*AddressOnlyGeneric + end_access %7 : $*AddressOnlyGeneric + dealloc_stack %3 : $*AddressOnlyGeneric + %12 = begin_access [modify] [dynamic] %1 : $*AddressOnlyGeneric + %13 = mark_must_check [assignable_but_not_consumable] %12 : $*AddressOnlyGeneric + %14 = function_ref @addressOnlyGenericInOutUse : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@inout AddressOnlyGeneric<τ_0_0>) -> () + %15 = apply %14(%13) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@inout AddressOnlyGeneric<τ_0_0>) -> () + end_access %12 : $*AddressOnlyGeneric + %17 = begin_access [deinit] [dynamic] %1 : $*AddressOnlyGeneric + %18 = mark_must_check [assignable_but_not_consumable] %17 : $*AddressOnlyGeneric + // expected-error @-1 {{'x' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + %19 = function_ref @addressOnlyGenericConsume : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> () + %20 = apply %19(%18) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> () + end_access %17 : $*AddressOnlyGeneric + %22 = tuple () + return %22 : $() +} \ No newline at end of file diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift index e5c6c0039cd6d..164545250f74f 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift @@ -18,6 +18,9 @@ public func borrowVal(_ x: borrowing AggStruct) {} public func borrowVal(_ x: borrowing AggGenericStruct) {} public func borrowVal(_ x: borrowing AggGenericStruct) {} public func borrowVal(_ x: borrowing EnumTy) {} +public func borrowVal(_ x: borrowing AddressOnlyGeneric) {} +public func borrowVal(_ x: borrowing AddressOnlyProtocol) {} +public func borrowVal(_ x: borrowing T) {} public func consumeVal(_ x: __owned CopyableKlass) {} public func consumeVal(_ x: __owned Klass) {} @@ -28,6 +31,9 @@ public func consumeVal(_ x: __owned AggGenericStruct) {} public func consumeVal(_ x: __owned EnumTy) {} public func consumeVal(_ x: __owned NonTrivialStruct) {} public func consumeVal(_ x: __owned NonTrivialStruct2) {} +public func consumeVal(_ x: __owned AddressOnlyGeneric) {} +public func consumeVal(_ x: __owned AddressOnlyProtocol) {} +public func consumeVal(_ x: __owned T) {} @_moveOnly public final class Klass { @@ -47,6 +53,8 @@ public struct NonTrivialStruct { var copyableK = CopyableKlass() var nonTrivialStruct2 = NonTrivialStruct2() var nonTrivialCopyableStruct = NonTrivialCopyableStruct() + + var computedCopyableK: CopyableKlass { CopyableKlass() } } @_moveOnly @@ -61,6 +69,7 @@ public struct NonTrivialCopyableStruct { public struct NonTrivialCopyableStruct2 { var copyableKlass = CopyableKlass() + var computedCopyableKlass: CopyableKlass { CopyableKlass() } } @_moveOnly @@ -81,6 +90,39 @@ public final class CopyableKlassWithMoveOnlyField { let moveOnlyLetStruct = NonTrivialStruct() } +public protocol P { + static var value: Self { get } + var name: CopyableKlass { get } + static var value2: any P { get } +} + +@_moveOnly +public struct AddressOnlyGeneric { + var copyable: T + var moveOnly = NonTrivialStruct() + + init() { + self.copyable = T.value + } + + init(_ input1: T) { + copyable = input1 + moveOnly = NonTrivialStruct() + } +} + +extension CopyableKlass : P { + public static var value: Self { fatalError() } + public static var value2: any P { CopyableKlass() } + public var name: CopyableKlass { CopyableKlass() } +} + +@_moveOnly +public struct AddressOnlyProtocol { + var copyable: any P = CopyableKlass.value2 + var moveOnly = NonTrivialStruct() +} + /////////// // Tests // /////////// @@ -1839,219 +1881,1388 @@ public func enumPatternMatchSwitch2WhereClause2Arg(_ x2: inout EnumTy) { // expe } } -///////////////////////////// -// Closure and Defer Tests // -///////////////////////////// +//////////////////////////////// +// Address Only Generic Tests // +//////////////////////////////// -public func closureClassUseAfterConsume1() { - let f = { - var x2 = Klass() // expected-error {{'x2' consumed more than once}} - x2 = Klass() - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) // expected-note {{consuming use here}} - } - f() +public func addressOnlyGenericSimpleChainTest(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + // expected-error @-1 {{'x2' consumed more than once}} + x2 = x // expected-note {{consuming use here}} + let y2 = x2 // expected-note {{consuming use here}} + let k2 = y2 + let k3 = x2 // expected-note {{consuming use here}} + let _ = k3 + borrowVal(k2) } -public func closureClassUseAfterConsume2() { - let f = { () in - var x2 = Klass() // expected-error {{'x2' consumed more than once}} - x2 = Klass() - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) // expected-note {{consuming use here}} - } - f() +public func addressOnlyGenericSimpleChainArgTest(_ x2: inout AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed more than once}} + // expected-error @-2 {{'x2' consumed but not reinitialized before end of function}} + var y2 = x2 // expected-note {{consuming use here}} + y2 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + let k2 = y2 + borrowVal(k2) } -public func closureClassUseAfterConsumeArg(_ argX: inout Klass) { - // TODO: Fix this - let f = { (_ x2: inout Klass) in - // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} - // expected-error @-2 {{'x2' consumed more than once}} - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) // expected-note {{consuming use here}} - // expected-note @-1 {{consuming use here}} - } - f(&argX) +public func addressOnlyGenericSimpleChainConsumingArgTest(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed more than once}} + var y2 = x2 // expected-note {{consuming use here}} + y2 = x2 // expected-note {{consuming use here}} + let k2 = y2 + borrowVal(k2) } -// We do not support captures of vars by closures today. -// -// TODO: Why are we erroring for the same variable twice? -public func closureCaptureClassUseAfterConsume() { - var x2 = Klass() // expected-error {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - // expected-error @-1 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - x2 = Klass() - let f = { - borrowVal(x2) - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - } - f() +public func addressOnlyGenericSimpleNonConsumingUseTest(_ x: borrowing AddressOnlyGeneric) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) } -public func closureCaptureClassUseAfterConsume2() { - var x2 = Klass() - // expected-error @-1 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - x2 = Klass() - let f = { - borrowVal(x2) - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - } - f() +public func addressOnlyGenericSimpleNonConsumingUseArgTest(_ x2: inout AddressOnlyGeneric) { + borrowVal(x2) } -public func closureCaptureClassUseAfterConsumeError() { - var x2 = Klass() - // expected-error @-1 {{'x2' consumed more than once}} - // expected-error @-2 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - // expected-error @-3 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - x2 = Klass() - let f = { // expected-note {{consuming use here}} - borrowVal(x2) - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - } - f() - let x3 = x2 // expected-note {{consuming use here}} - let _ = x3 +public func addressOnlyGenericMultipleNonConsumingUseTest(_ x: borrowing AddressOnlyGeneric) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) } -public func closureCaptureClassArgUseAfterConsume(_ x2: inout Klass) { - // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} - // expected-note @-2 {{'x2' is declared 'inout'}} - let f = { // expected-note {{consuming use here}} - // expected-error @-1 {{escaping closure captures 'inout' parameter 'x2'}} - borrowVal(x2) // expected-note {{captured here}} - consumeVal(x2) // expected-note {{captured here}} - consumeVal(x2) // expected-note {{captured here}} - } - f() +public func addressOnlyGenericMultipleNonConsumingUseArgTest(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} } -public func deferCaptureClassUseAfterConsume() { - var x2 = Klass() - // expected-error @-1 {{'x2' used after consume}} - // expected-error @-2 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-3 {{'x2' consumed more than once}} - x2 = Klass() - defer { // expected-note {{non-consuming use here}} - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - // expected-note @-2 {{consuming use here}} - } +public func addressOnlyGenericMultipleNonConsumingUseArgTest2(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} } -public func deferCaptureClassUseAfterConsume2() { - var x2 = Klass() - // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{'x2' used after consume}} - x2 = Klass() - defer { // expected-note {{non-consuming use here}} - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) // expected-note {{consuming use here}} - // expected-note @-1 {{consuming use here}} - } - let x3 = x2 // expected-note {{consuming use here}} - let _ = x3 +public func addressOnlyGenericMultipleNonConsumingUseArgTest3(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} } -public func deferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { - // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-2 {{'x2' consumed more than once}} +public func addressOnlyGenericMultipleNonConsumingUseArgTest4(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' used after consume}} borrowVal(x2) - defer { - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) // expected-note {{consuming use here}} - // expected-note @-1 {{consuming use here}} - } - print("foo") + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x2 = AddressOnlyGeneric() } -public func closureAndDeferCaptureClassUseAfterConsume() { - var x2 = Klass() - // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-2 {{'x2' consumed more than once}} - x2 = Klass() - let f = { - defer { - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - // expected-note @-2 {{consuming use here}} - } - print("foo") - } - f() +public func addressOnlyGenericMultipleNonConsumingUseConsumingArgTest(_ x2: consuming AddressOnlyGeneric) { + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) } -public func closureAndDeferCaptureClassUseAfterConsume2() { - var x2 = Klass() - // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - x2 = Klass() - let f = { - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - defer { - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - // expected-note @-2 {{consuming use here}} - } - print("foo") - } - f() +public func addressOnlyGenericMultipleNonConsumingUseConsumingArgTest2(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} } -public func closureAndDeferCaptureClassUseAfterConsume3() { - var x2 = Klass() - // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-2 {{'x2' consumed more than once}} - // expected-error @-3 {{'x2' consumed more than once}} - // expected-error @-4 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} - x2 = Klass() - let f = { // expected-note {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - defer { - borrowVal(x2) - consumeVal(x2) // expected-note {{consuming use here}} - consumeVal(x2) - // expected-note @-1 {{consuming use here}} - // expected-note @-2 {{consuming use here}} - } - print("foo") - } - f() +public func addressOnlyGenericMultipleNonConsumingUseConsumingArgTest3(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} consumeVal(x2) // expected-note {{consuming use here}} } -public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { - // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} - // expected-error @-2 {{'x2' consumed in closure but not reinitialized before end of closure}} - // expected-error @-3 {{'x2' consumed more than once}} - // expected-note @-4 {{'x2' is declared 'inout'}} - let f = { // expected-error {{escaping closure captures 'inout' parameter 'x2'}} - // expected-note @-1 {{consuming use here}} - defer { // expected-note {{captured indirectly by this call}} +public func addressOnlyGenericMultipleNonConsumingUseConsumingArgTest4(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x2 = AddressOnlyGeneric() +} + +public func addressOnlyGenericUseAfterConsume(_ x: borrowing AddressOnlyGeneric) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyGenericUseAfterConsumeArg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} +} + +public func addressOnlyGenericUseAfterConsumeArg2(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyGenericDoubleConsume(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyGeneric() + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyGenericDoubleConsumeArg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} +} + +public func addressOnlyGenericDoubleConsumeArg2(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed more than once}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyGenericLoopConsume(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed by a use in a loop}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyGeneric() + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyGenericLoopConsumeArg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyGenericLoopConsumeArg2(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed by a use in a loop}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } + x2 = AddressOnlyGeneric() +} + +public func addressOnlyGenericLoopConsumeArg3(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' consumed by a use in a loop}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } + x2 = AddressOnlyGeneric() +} + +public func addressOnlyGenericDiamond(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + if boolValue { + consumeVal(x2) + } else { + consumeVal(x2) + } +} + +public func addressOnlyGenericDiamondArg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyGenericDiamondArg2(_ x2: consuming AddressOnlyGeneric) { + if boolValue { + consumeVal(x2) + } else { + consumeVal(x2) + } +} + +public func addressOnlyGenericDiamondInLoop(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + // expected-note @-2 {{consuming use here}} + x2 = AddressOnlyGeneric() + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } +} + +public func addressOnlyGenericDiamondInLoopArg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + } + } +} + +public func addressOnlyGenericDiamondInLoopArg2(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } + x2 = AddressOnlyGeneric() +} + +public func addressOnlyGenericDiamondInLoopArg3(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } +} + +public func addressOnlyGenericDiamondInLoopArg4(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } + x2 = AddressOnlyGeneric() +} + +public func addressOnlyGenericAssignToVar1(_ x: borrowing AddressOnlyGeneric) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyGeneric() + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar1Arg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + x3 = AddressOnlyGeneric() + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar1Arg2(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + x3 = AddressOnlyGeneric() + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar2(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyGeneric() + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyGenericAssignToVar2Arg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyGenericAssignToVar2Arg2(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyGenericAssignToVar3(_ x: borrowing AddressOnlyGeneric) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + var x3 = x2 + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar3Arg(_ x: borrowing AddressOnlyGeneric, _ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar3Arg2(_ x: borrowing AddressOnlyGeneric, _ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar4(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyGeneric() + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar4Arg(_ x2: inout AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar4Arg2(_ x2: consuming AddressOnlyGeneric) { // expected-error {{'x2' consumed more than once}} + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar5(_ ty: T.Type) { + var x2 = AddressOnlyGeneric() // expected-error {{'x2' used after consume}} + x2 = AddressOnlyGeneric() + var x3 = x2 // expected-note {{consuming use here}} + // TODO: Need to mark this as the lifetime extending use. We fail + // appropriately though. + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = AddressOnlyGeneric() + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar5Arg(_ x: borrowing AddressOnlyGeneric, _ x2: inout AddressOnlyGeneric) { + // expected-error @-1 {{'x2' used after consume}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyGenericAssignToVar5Arg2(_ x: borrowing AddressOnlyGeneric, _ x2: inout AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + // expected-error @-1 {{'x2' used after consume}} + var x3 = x2 // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) + x2 = AddressOnlyGeneric() +} + +// MG: We are calling these consuming uses since I have not taught the checker +// that a use of a copy_addr that is copyable is not a consuming use. I will +// remove them when I fix it in the next commit. +public func addressOnlyGenericAccessAccessField(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessAccessField2(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyGenericAccessAccessFieldArg(_ x2: inout AddressOnlyGeneric) { + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessAccessFieldArg2(_ x2: inout AddressOnlyGeneric) { + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyGenericAccessAccessFieldArg3(_ x2: consuming AddressOnlyGeneric) { + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessAccessFieldArg4(_ x2: consuming AddressOnlyGeneric) { + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyGenericAccessConsumeField(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + + consumeVal(x2.copyable) + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessConsumeField2(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + x2 = AddressOnlyGeneric() + + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeGrandField(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + + consumeVal(x2.copyable.name) + for _ in 0..<1024 { + consumeVal(x2.copyable.name) + } +} + +public func addressOnlyGenericAccessConsumeGrandField2(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + // expected-error @-1 {{'x2' consumed more than once}} + // expected-error @-2 {{'x2' consumed by a use in a loop}} + x2 = AddressOnlyGeneric() + + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + for _ in 0..<1024 { + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeGrandField2a(_ x: borrowing AddressOnlyGeneric) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyGeneric() + + consumeVal(x2.moveOnly.copyableK) + for _ in 0..<1024 { + consumeVal(x2.moveOnly.copyableK) + } +} + +public func addressOnlyGenericAccessConsumeFieldArg(_ x2: inout AddressOnlyGeneric) { + consumeVal(x2.copyable) + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessConsumeFieldArg2(_ x2: inout AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-2 {{'x2' consumed but not reinitialized before end of function}} + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeFieldArg3(_ x2: consuming AddressOnlyGeneric) { + consumeVal(x2.copyable) + + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyGenericAccessConsumeFieldArg4(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg(_ x2: inout AddressOnlyGeneric) { + consumeVal(x2.copyable.name) + for _ in 0..<1024 { + consumeVal(x2.copyable.name) + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg2(_ x2: inout AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-2 {{'x2' consumed but not reinitialized before end of function}} + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg2a(_ x2: inout AddressOnlyGeneric) { + consumeVal(x2.moveOnly.copyableK) + + for _ in 0..<1024 { + consumeVal(x2.moveOnly.copyableK) + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg3(_ x2: consuming AddressOnlyGeneric) { + consumeVal(x2.copyable.name) + + for _ in 0..<1024 { + consumeVal(x2.copyable.name) + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg4(_ x2: consuming AddressOnlyGeneric) { + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly.k) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +public func addressOnlyGenericAccessConsumeGrandFieldArg4a(_ x2: consuming AddressOnlyGeneric) { + consumeVal(x2.moveOnly.copyableK) + + for _ in 0..<1024 { + consumeVal(x2.moveOnly.copyableK) + } +} + +extension AddressOnlyGeneric { + func testNoUseSelf() { // expected-error {{'self' has guaranteed ownership but was consumed}} + let x = self // expected-note {{consuming use here}} + let _ = x + } + + mutating func testNoUseSelf2() { // expected-error {{'self' consumed but not reinitialized before end of function}} + let x = self // expected-note {{consuming use here}} + let _ = x + } +} + +@_moveOnly +struct AddressOnlyGenericInit { + var copyable: T + var moveOnly: NonTrivialStruct + var moveOnly2: AddressOnlyGeneric + + init(_ input1: T, _ input2: consuming NonTrivialStruct) { + if boolValue { + copyable = input1 + } else { + copyable = T.value + } + moveOnly2 = AddressOnlyGeneric(T.value) + moveOnly = input2 + } + + init(_ input1: T, _ input2: consuming NonTrivialStruct, _ input3 : consuming AddressOnlyGeneric) { + copyable = input1 + if boolValue { + moveOnly2 = input3 + } else { + moveOnly2 = AddressOnlyGeneric(T.value) + } + moveOnly = input2 + } +} + +/////////////////////////// +// Address Only Protocol // +/////////////////////////// + +public func addressOnlyProtocolSimpleChainTest(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + // expected-error @-1 {{'x2' consumed more than once}} + x2 = x // expected-note {{consuming use here}} + let y2 = x2 // expected-note {{consuming use here}} + let k2 = y2 + let k3 = x2 // expected-note {{consuming use here}} + let _ = k3 + borrowVal(k2) +} + +public func addressOnlyProtocolSimpleChainArgTest(_ x2: inout AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed more than once}} + // expected-error @-2 {{'x2' consumed but not reinitialized before end of function}} + var y2 = x2 // expected-note {{consuming use here}} + y2 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + let k2 = y2 + borrowVal(k2) +} + +public func addressOnlyProtocolSimpleChainConsumingArgTest(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed more than once}} + var y2 = x2 // expected-note {{consuming use here}} + y2 = x2 // expected-note {{consuming use here}} + let k2 = y2 + borrowVal(k2) +} + +public func addressOnlyProtocolSimpleNonConsumingUseTest(_ x: borrowing AddressOnlyProtocol) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) +} + +public func addressOnlyProtocolSimpleNonConsumingUseArgTest(_ x2: inout AddressOnlyProtocol) { + borrowVal(x2) +} + +public func addressOnlyProtocolMultipleNonConsumingUseTest(_ x: borrowing AddressOnlyProtocol) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) +} + +public func addressOnlyProtocolMultipleNonConsumingUseArgTest(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolMultipleNonConsumingUseArgTest2(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} +} + +public func addressOnlyProtocolMultipleNonConsumingUseArgTest3(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} +} + +public func addressOnlyProtocolMultipleNonConsumingUseArgTest4(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolMultipleNonConsumingUseConsumingArgTest(_ x2: consuming AddressOnlyProtocol) { + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) +} + +public func addressOnlyProtocolMultipleNonConsumingUseConsumingArgTest2(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} +} + +public func addressOnlyProtocolMultipleNonConsumingUseConsumingArgTest3(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolMultipleNonConsumingUseConsumingArgTest4(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' used after consume}} + borrowVal(x2) + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolUseAfterConsume(_ x: borrowing AddressOnlyProtocol) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = x // expected-note {{consuming use here}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolUseAfterConsumeArg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} +} + +public func addressOnlyProtocolUseAfterConsumeArg2(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed more than once}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolDoubleConsume(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyProtocol() + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolDoubleConsumeArg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed more than once}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} +} + +public func addressOnlyProtocolDoubleConsumeArg2(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed more than once}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func addressOnlyProtocolLoopConsume(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed by a use in a loop}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyProtocol() + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyProtocolLoopConsumeArg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyProtocolLoopConsumeArg2(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed by a use in a loop}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolLoopConsumeArg3(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' consumed by a use in a loop}} + for _ in 0..<1024 { + consumeVal(x2) // expected-note {{consuming use here}} + } + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolDiamond(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyProtocol() + if boolValue { + consumeVal(x2) + } else { + consumeVal(x2) + } +} + +public func addressOnlyProtocolDiamondArg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + } +} + +public func addressOnlyProtocolDiamondArg2(_ x2: consuming AddressOnlyProtocol) { + if boolValue { + consumeVal(x2) + } else { + consumeVal(x2) + } +} + +public func addressOnlyProtocolDiamondInLoop(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + // expected-note @-2 {{consuming use here}} + x2 = AddressOnlyProtocol() + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } +} + +public func addressOnlyProtocolDiamondInLoopArg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + } + } +} + +public func addressOnlyProtocolDiamondInLoopArg2(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolDiamondInLoopArg3(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } +} + +public func addressOnlyProtocolDiamondInLoopArg4(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' consumed by a use in a loop}} + // expected-error @-1 {{'x2' consumed more than once}} + for _ in 0..<1024 { + if boolValue { + consumeVal(x2) // expected-note {{consuming use here}} + } else { + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + } + x2 = AddressOnlyProtocol() +} + +public func addressOnlyProtocolAssignToVar1(_ x: borrowing AddressOnlyProtocol) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyProtocol() + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar1Arg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + x3 = AddressOnlyProtocol() + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar1Arg2(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + x3 = AddressOnlyProtocol() + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar2(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyProtocol() + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyProtocolAssignToVar2Arg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyProtocolAssignToVar2Arg2(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x2 // expected-note {{consuming use here}} + borrowVal(x3) +} + +public func addressOnlyProtocolAssignToVar3(_ x: borrowing AddressOnlyProtocol) { + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyProtocol() + var x3 = x2 + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar3Arg(_ x: borrowing AddressOnlyProtocol, _ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar3Arg2(_ x: borrowing AddressOnlyProtocol, _ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-1 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar4(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-error {{'x2' consumed more than once}} + // expected-note @-1 {{consuming use here}} + x2 = AddressOnlyProtocol() + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar4Arg(_ x2: inout AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar4Arg2(_ x2: consuming AddressOnlyProtocol) { // expected-error {{'x2' consumed more than once}} + let x3 = x2 // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar5(_ ty: T.Type) { + var x2 = AddressOnlyProtocol() // expected-error {{'x2' used after consume}} + x2 = AddressOnlyProtocol() + var x3 = x2 // expected-note {{consuming use here}} + // TODO: Need to mark this as the lifetime extending use. We fail + // appropriately though. + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = AddressOnlyProtocol() + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar5Arg(_ x: borrowing AddressOnlyProtocol, _ x2: inout AddressOnlyProtocol) { + // expected-error @-1 {{'x2' used after consume}} + // expected-error @-2 {{'x' has guaranteed ownership but was consumed}} + var x3 = x2 // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) +} + +public func addressOnlyProtocolAssignToVar5Arg2(_ x: borrowing AddressOnlyProtocol, _ x2: inout AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + // expected-error @-1 {{'x2' used after consume}} + var x3 = x2 // expected-note {{consuming use here}} + borrowVal(x2) // expected-note {{non-consuming use here}} + x3 = x // expected-note {{consuming use here}} + consumeVal(x3) + x2 = AddressOnlyProtocol() +} + +// MG: We are calling these consuming uses since I have not taught the checker +// that a use of a copy_addr that is copyable is not a consuming use. I will +// remove them when I fix it in the next commit. +public func addressOnlyProtocolAccessAccessField(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyProtocol() + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessAccessField2(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyProtocol() + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyProtocolAccessAccessFieldArg(_ x2: inout AddressOnlyProtocol) { + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessAccessFieldArg2(_ x2: inout AddressOnlyProtocol) { + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyProtocolAccessAccessFieldArg3(_ x2: consuming AddressOnlyProtocol) { + borrowVal(x2.copyable) + for _ in 0..<1024 { + borrowVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessAccessFieldArg4(_ x2: consuming AddressOnlyProtocol) { + borrowVal(x2.moveOnly) + for _ in 0..<1024 { + borrowVal(x2.moveOnly) + } +} + +public func addressOnlyProtocolAccessConsumeField(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + x2 = AddressOnlyProtocol() + + consumeVal(x2.copyable) + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessConsumeField2(_ x: borrowing AddressOnlyProtocol) { // expected-error {{'x' has guaranteed ownership but was consumed}} + var x2 = x // expected-note {{consuming use here}} + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + x2 = AddressOnlyProtocol() + + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +public func addressOnlyProtocolAccessConsumeFieldArg(_ x2: inout AddressOnlyProtocol) { + consumeVal(x2.copyable) + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessConsumeFieldArg2(_ x2: inout AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-2 {{'x2' consumed but not reinitialized before end of function}} + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + } +} + +public func addressOnlyProtocolAccessConsumeFieldArg3(_ x2: consuming AddressOnlyProtocol) { + consumeVal(x2.copyable) + + for _ in 0..<1024 { + consumeVal(x2.copyable) + } +} + +public func addressOnlyProtocolAccessConsumeFieldArg4(_ x2: consuming AddressOnlyProtocol) { + // expected-error @-1 {{'x2' consumed by a use in a loop}} + // expected-error @-2 {{'x2' consumed more than once}} + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + + for _ in 0..<1024 { + consumeVal(x2.moveOnly) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } +} + +extension AddressOnlyProtocol { + func testNoUseSelf() { // expected-error {{'self' has guaranteed ownership but was consumed}} + let x = self // expected-note {{consuming use here}} + let _ = x + } +} + +///////////////////////////// +// Closure and Defer Tests // +///////////////////////////// + +public func closureClassUseAfterConsume1() { + let f = { + var x2 = Klass() // expected-error {{'x2' consumed more than once}} + x2 = Klass() + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + } + f() +} + +public func closureClassUseAfterConsume2() { + let f = { () in + var x2 = Klass() // expected-error {{'x2' consumed more than once}} + x2 = Klass() + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + } + f() +} + +public func closureClassUseAfterConsumeArg(_ argX: inout Klass) { + // TODO: Fix this + let f = { (_ x2: inout Klass) in + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-2 {{'x2' consumed more than once}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + f(&argX) +} + +// We do not support captures of vars by closures today. +// +// TODO: Why are we erroring for the same variable twice? +public func closureCaptureClassUseAfterConsume() { + var x2 = Klass() // expected-error {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + // expected-error @-1 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x2 = Klass() + let f = { + borrowVal(x2) + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + } + f() +} + +public func closureCaptureClassUseAfterConsume2() { + var x2 = Klass() + // expected-error @-1 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x2 = Klass() + let f = { + borrowVal(x2) + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + } + f() +} + +public func closureCaptureClassUseAfterConsumeError() { + var x2 = Klass() + // expected-error @-1 {{'x2' consumed more than once}} + // expected-error @-2 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + // expected-error @-3 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x2 = Klass() + let f = { // expected-note {{consuming use here}} + borrowVal(x2) + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + } + f() + let x3 = x2 // expected-note {{consuming use here}} + let _ = x3 +} + +public func closureCaptureClassArgUseAfterConsume(_ x2: inout Klass) { + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-note @-2 {{'x2' is declared 'inout'}} + let f = { // expected-note {{consuming use here}} + // expected-error @-1 {{escaping closure captures 'inout' parameter 'x2'}} + borrowVal(x2) // expected-note {{captured here}} + consumeVal(x2) // expected-note {{captured here}} + consumeVal(x2) // expected-note {{captured here}} + } + f() +} + +public func deferCaptureClassUseAfterConsume() { + var x2 = Klass() + // expected-error @-1 {{'x2' used after consume}} + // expected-error @-2 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-3 {{'x2' consumed more than once}} + x2 = Klass() + defer { // expected-note {{non-consuming use here}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + // expected-note @-2 {{consuming use here}} + } + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func deferCaptureClassUseAfterConsume2() { + var x2 = Klass() + // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-2 {{'x2' consumed more than once}} + // expected-error @-3 {{'x2' used after consume}} + x2 = Klass() + defer { // expected-note {{non-consuming use here}} + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + let x3 = x2 // expected-note {{consuming use here}} + let _ = x3 +} + +public func deferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { + // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-2 {{'x2' consumed more than once}} + borrowVal(x2) + defer { + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) // expected-note {{consuming use here}} + // expected-note @-1 {{consuming use here}} + } + print("foo") +} + +public func closureAndDeferCaptureClassUseAfterConsume() { + var x2 = Klass() + // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-2 {{'x2' consumed more than once}} + x2 = Klass() + let f = { + defer { + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + // expected-note @-2 {{consuming use here}} + } + print("foo") + } + f() +} + +public func closureAndDeferCaptureClassUseAfterConsume2() { + var x2 = Klass() + // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-2 {{'x2' consumed more than once}} + // expected-error @-3 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x2 = Klass() + let f = { + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + defer { + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + // expected-note @-2 {{consuming use here}} + } + print("foo") + } + f() +} + +public func closureAndDeferCaptureClassUseAfterConsume3() { + var x2 = Klass() + // expected-error @-1 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-2 {{'x2' consumed more than once}} + // expected-error @-3 {{'x2' consumed more than once}} + // expected-error @-4 {{'x2' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x2 = Klass() + let f = { // expected-note {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + defer { + borrowVal(x2) + consumeVal(x2) // expected-note {{consuming use here}} + consumeVal(x2) + // expected-note @-1 {{consuming use here}} + // expected-note @-2 {{consuming use here}} + } + print("foo") + } + f() + consumeVal(x2) // expected-note {{consuming use here}} +} + +public func closureAndDeferCaptureClassArgUseAfterConsume(_ x2: inout Klass) { + // expected-error @-1 {{'x2' consumed but not reinitialized before end of function}} + // expected-error @-2 {{'x2' consumed in closure but not reinitialized before end of closure}} + // expected-error @-3 {{'x2' consumed more than once}} + // expected-note @-4 {{'x2' is declared 'inout'}} + let f = { // expected-error {{escaping closure captures 'inout' parameter 'x2'}} + // expected-note @-1 {{consuming use here}} + defer { // expected-note {{captured indirectly by this call}} borrowVal(x2) // expected-note {{captured here}} consumeVal(x2) // expected-note {{captured here}} // expected-note @-1 {{consuming use here}} @@ -2267,6 +3478,49 @@ func copyableStructsInMoveOnlyStructNonConsuming() { borrowVal(a.nonTrivialCopyableStruct.nonTrivialCopyableStruct2.copyableKlass) } +func computedCopyableKlassInAMoveOnlyStruct() { + var a = NonTrivialStruct() + a = NonTrivialStruct() + borrowVal(a.computedCopyableK) + consumeVal(a.computedCopyableK) +} + +// This shouldn't error since we are consuming a copyable type. +func computedCopyableKlassInAMoveOnlyStruct2() { + var a = NonTrivialStruct() + a = NonTrivialStruct() + borrowVal(a.computedCopyableK) + consumeVal(a.computedCopyableK) + consumeVal(a.computedCopyableK) +} + +// This shouldn't error since we are working with a copyable type. +func computedCopyableKlassInAMoveOnlyStruct3() { + var a = NonTrivialStruct() + a = NonTrivialStruct() + borrowVal(a.computedCopyableK) + consumeVal(a.computedCopyableK) + borrowVal(a.computedCopyableK) +} + +// This used to error, but no longer errors since we are using a true field +// sensitive model. +func computedCopyableKlassInAMoveOnlyStruct4() { + var a = NonTrivialStruct() + a = NonTrivialStruct() + borrowVal(a.computedCopyableK) + consumeVal(a.computedCopyableK) + borrowVal(a.nonTrivialStruct2) +} + +func computedCopyableStructsInMoveOnlyStructNonConsuming() { + var a = NonTrivialStruct() + a = NonTrivialStruct() + borrowVal(a) + borrowVal(a.computedCopyableK) + borrowVal(a.nonTrivialCopyableStruct.nonTrivialCopyableStruct2.computedCopyableKlass) +} + /////////////////////////// // Field Sensitive Tests // /////////////////////////// @@ -2487,6 +3741,29 @@ func inoutCaptureTest() -> (() -> ()) { return f } +func inoutCaptureTestAddressOnlyGeneric(_ t: T.Type) -> (() -> ()) { + var x = AddressOnlyGeneric() + x = AddressOnlyGeneric() + + func useInOut(_ x: inout AddressOnlyGeneric) {} + let f = { + useInOut(&x) + } + + borrowVal(x) + consumeVal(x) // expected-error {{'x' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + x = AddressOnlyGeneric() + + let g = { + x = AddressOnlyGeneric() + useInOut(&x) + consumeVal(x) // expected-error {{'x' was consumed but it is illegal to consume a noncopyable mutable capture of an escaping closure. One can only read from it or assign over it}} + } + g() + + return f +} + //////////////// // Misc Tests // ////////////////