Skip to content

Commit f79938c

Browse files
authored
Merge pull request #66587 from kavon/improve-noncopyable-closure-diags
Improve noncopyable closure diags
2 parents 8feefce + 219f94f commit f79938c

12 files changed

+354
-340
lines changed

include/swift/AST/DiagnosticsSIL.def

+4-3
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,10 @@ ERROR(sil_movechecking_borrowed_parameter_captured_by_closure, none,
766766
"parameter",
767767
(StringRef))
768768
ERROR(sil_movechecking_capture_consumed, none,
769-
"noncopyable '%0' cannot be consumed when captured by a closure", (StringRef))
770-
ERROR(sil_movechecking_inout_not_reinitialized_before_end_of_function, none,
771-
"missing reinitialization of inout parameter '%0' after consume", (StringRef))
769+
"noncopyable '%0' cannot be consumed when captured by an escaping closure", (StringRef))
770+
ERROR(sil_movechecking_not_reinitialized_before_end_of_function, none,
771+
"missing reinitialization of %select{inout parameter|closure capture}1 '%0' "
772+
"after consume", (StringRef, bool))
772773
ERROR(sil_movechecking_value_consumed_in_a_loop, none,
773774
"'%0' consumed in a loop", (StringRef))
774775
ERROR(sil_movechecking_use_after_partial_consume, none,

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,19 @@ void DiagnosticEmitter::emitObjectDiagnosticsForPartialApplyUses(
542542
// MARK: Address Diagnostics
543543
//===----------------------------------------------------------------------===//
544544

545+
static bool isClosureCapture(MarkMustCheckInst *markedValue) {
546+
SILValue val = markedValue->getOperand();
547+
548+
// look past any project-box
549+
if (auto *pbi = dyn_cast<ProjectBoxInst>(val))
550+
val = pbi->getOperand();
551+
552+
if (auto *fArg = dyn_cast<SILFunctionArgument>(val))
553+
return fArg->isClosureCapture();
554+
555+
return false;
556+
}
557+
545558
void DiagnosticEmitter::emitAddressExclusivityHazardDiagnostic(
546559
MarkMustCheckInst *markedValue, SILInstruction *consumingUser) {
547560
if (!useWithDiagnostic.insert(consumingUser).second)
@@ -596,8 +609,8 @@ void DiagnosticEmitter::emitAddressDiagnostic(MarkMustCheckInst *markedValue,
596609
diagnose(
597610
astContext, markedValue,
598611
diag::
599-
sil_movechecking_inout_not_reinitialized_before_end_of_function,
600-
varName);
612+
sil_movechecking_not_reinitialized_before_end_of_function,
613+
varName, isClosureCapture(markedValue));
601614
diagnose(astContext, violatingUser,
602615
diag::sil_movechecking_consuming_use_here);
603616
return;
@@ -647,8 +660,8 @@ void DiagnosticEmitter::emitInOutEndOfFunctionDiagnostic(
647660
// consuming message:
648661
diagnose(
649662
astContext, markedValue,
650-
diag::sil_movechecking_inout_not_reinitialized_before_end_of_function,
651-
varName);
663+
diag::sil_movechecking_not_reinitialized_before_end_of_function,
664+
varName, isClosureCapture(markedValue));
652665
diagnose(astContext, violatingUser,
653666
diag::sil_movechecking_consuming_use_here);
654667
}

test/SILGen/moveonly_escaping_closure.swift

+56-56
Large diffs are not rendered by default.

test/SILOptimizer/definite_init_moveonly_controlflowdep_init.sil

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ bb3:
119119
%23 = apply %22(%21) : $@convention(thin) (@guaranteed S) -> ()
120120
destroy_value %21 : $S
121121
%25 = mark_must_check [assignable_but_not_consumable] %3 : $*S
122-
// expected-error @-1 {{noncopyable 's' cannot be consumed when captured by a closure}}
122+
// expected-error @-1 {{noncopyable 's' cannot be consumed when captured by an escaping closure}}
123123
%26 = load [take] %25 : $*S
124124
%27 = function_ref @consumeVal : $@convention(thin) (@owned S) -> ()
125125
%28 = apply %27(%26) : $@convention(thin) (@owned S) -> ()

test/SILOptimizer/discard_checking.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ struct Basics: ~Copyable {
388388

389389
// FIXME move checker is treating the defer like a closure capture (rdar://100468597)
390390
// not expecting any errors here
391-
consuming func brokenPositiveTest(_ i: Int) { // expected-error {{missing reinitialization of inout parameter 'self' after consume}}
391+
consuming func brokenPositiveTest(_ i: Int) { // expected-error {{missing reinitialization of closure capture 'self' after consume}}
392392
defer { discard self } // expected-note {{consumed here}}
393393
switch i {
394394
case 0, 1, 2, 3: return

test/SILOptimizer/moveonly_addresschecker_diagnostics.sil

+2-2
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ bb0(%0 : @closureCapture @guaranteed $<τ_0_0 where τ_0_0 : P> { var AddressOnl
359359
end_access %12 : $*AddressOnlyGeneric<T>
360360
%17 = begin_access [deinit] [dynamic] %1 : $*AddressOnlyGeneric<T>
361361
%18 = mark_must_check [assignable_but_not_consumable] %17 : $*AddressOnlyGeneric<T>
362-
// expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by a closure}}
362+
// expected-error @-1 {{noncopyable 'x' cannot be consumed when captured by an escaping closure}}
363363
%19 = function_ref @addressOnlyGenericConsume : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> ()
364364
%20 = apply %19<T>(%18) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in AddressOnlyGeneric<τ_0_0>) -> ()
365365
end_access %17 : $*AddressOnlyGeneric<T>
@@ -528,4 +528,4 @@ bb0(%0 : @owned $NonTrivialStruct):
528528
dealloc_stack %1 : $*NonTrivialStruct
529529
%9999 = tuple()
530530
return %9999 : $()
531-
}
531+
}

0 commit comments

Comments
 (0)