Skip to content

Commit 38786ba

Browse files
authored
Merge pull request #66124 from kavon/5.9-noncopyable-diagnostics-cleanup
[5.9🍒] polish up the noncopyable diagnostics
2 parents a63c8d5 + b2a87de commit 38786ba

File tree

59 files changed

+5080
-4897
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+5080
-4897
lines changed

docs/SIL.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2805,7 +2805,7 @@ canonical SIL that the value was never copied and thus is a "move only value"
28052805
even though the actual underlying wrapped type is copyable. As an example of
28062806
this, consider the following Swift::
28072807

2808-
func doSomething(@_noImplicitCopy _ x: Klass) -> () { // expected-error {{'x' has guaranteed ownership but was consumed}}
2808+
func doSomething(@_noImplicitCopy _ x: Klass) -> () { // expected-error {{'x' is borrowed and cannot be consumed}}
28092809
x.doSomething()
28102810
let x2 = x // expected-note {{consuming use}}
28112811
x2.doSomething()

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ ERROR(conforms_to_not_protocol,none,
248248
"%0 %1 referenced in protocol conformance '%2' is not a protocol", (DescriptiveDeclKind, ValueDecl *, StringRef))
249249

250250
ERROR(move_only_requires_move_only,none,
251-
"use of move-only C++ type '%0' requires -enable-experimental-move-only",
251+
"use of noncopyable C++ type '%0' requires -enable-experimental-move-only",
252252
(StringRef))
253253

254254
NOTE(unsupported_builtin_type, none, "built-in type '%0' not supported", (StringRef))

include/swift/AST/DiagnosticsSIL.def

Lines changed: 56 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -747,97 +747,70 @@ NOTE(discard_nontrivial_implicit_storage_note,none,
747747
"type %0 implicitly contains %1 which cannot be trivially destroyed",
748748
(Type, Type))
749749

750-
// move only checker diagnostics
751-
ERROR(sil_moveonlychecker_owned_value_consumed_more_than_once, none,
750+
751+
/// Move Checking / Noncopyable types diagnostics
752+
753+
ERROR(sil_movechecking_owned_value_consumed_more_than_once, none,
752754
"'%0' consumed more than once", (StringRef))
753-
ERROR(sil_moveonlychecker_owned_value_consumed_and_used_at_same_time, none,
755+
ERROR(sil_movechecking_owned_value_consumed_and_used_at_same_time, none,
754756
"'%0' consumed and used at the same time", (StringRef))
755-
ERROR(sil_moveonlychecker_value_used_after_consume, none,
757+
ERROR(sil_movechecking_value_used_after_consume, none,
756758
"'%0' used after consume", (StringRef))
757-
ERROR(sil_moveonlychecker_guaranteed_value_consumed, none,
758-
"'%0' has guaranteed ownership but was consumed", (StringRef))
759-
ERROR(sil_moveonlychecker_guaranteed_value_captured_by_closure, none,
760-
"'%0' has guaranteed ownership but was consumed due to being captured by a closure", (StringRef))
761-
ERROR(sil_moveonlychecker_let_value_consumed_in_closure, none,
762-
"'%0' consumed in closure. This is illegal since if the closure is invoked more than once the binding will be uninitialized on later invocations", (StringRef))
763-
ERROR(sil_moveonlychecker_inout_not_reinitialized_before_end_of_function, none,
764-
"'%0' consumed but not reinitialized before end of function", (StringRef))
765-
ERROR(sil_moveonlychecker_inout_not_reinitialized_before_end_of_closure, none,
766-
"'%0' consumed in closure but not reinitialized before end of closure", (StringRef))
767-
ERROR(sil_moveonlychecker_value_consumed_in_a_loop, none,
768-
"'%0' consumed by a use in a loop", (StringRef))
769-
ERROR(sil_moveonlychecker_exclusivity_violation, none,
770-
"'%0' has consuming use that cannot be eliminated due to a tight exclusivity scope", (StringRef))
771-
ERROR(sil_moveonlychecker_moveonly_field_consumed, none,
772-
"'%0' has a move only field that was consumed before later uses", (StringRef))
773-
774-
ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed_classfield_let, none,
775-
"'%0' was consumed but it is illegal to consume a noncopyable class let field. One can only read from it",
776-
(StringRef))
777-
ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed_classfield_var, none,
778-
"'%0' was consumed but it is illegal to consume a noncopyable class var field. One can only read from it or assign to it",
779-
(StringRef))
780-
ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed_global_var, none,
781-
"'%0' was consumed but it is illegal to consume a noncopyable global var. One can only read from it or assign to it",
782-
(StringRef))
783-
ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed_global_let, none,
784-
"'%0' was consumed but it is illegal to consume a noncopyable global let. One can only read from it",
785-
(StringRef))
786-
ERROR(sil_moveonlychecker_notconsumable_but_assignable_was_consumed_escaping_var, none,
787-
"'%0' 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",
788-
(StringRef))
789-
ERROR(sil_moveonlychecker_let_capture_consumed, none,
790-
"'%0' was consumed but it is illegal to consume a noncopyable immutable capture of an escaping closure. One can only read from it", (StringRef))
791-
ERROR(sil_moveonlychecker_cannot_destructure_deinit_nominal_type_self, none,
792-
"Cannot partially consume '%0' since it has a user defined deinit",
759+
ERROR(sil_movechecking_guaranteed_value_consumed, none,
760+
"'%0' is borrowed and cannot be consumed", (StringRef))
761+
762+
// FIXME: this diagnostic shouldn't ever be emitted now. rdar://109742587 (closures may still try to consume captures, e.g., borrowed parameters)
763+
ERROR(sil_movechecking_guaranteed_value_captured_by_closure, none,
764+
"'%0' is borrowed and cannot be consumed by closure capture", (StringRef))
765+
766+
ERROR(sil_movechecking_capture_consumed, none,
767+
"noncopyable '%0' cannot be consumed when captured by a closure", (StringRef))
768+
ERROR(sil_movechecking_inout_not_reinitialized_before_end_of_function, none,
769+
"missing reinitialization of inout parameter '%0' after consume", (StringRef))
770+
ERROR(sil_movechecking_value_consumed_in_a_loop, none,
771+
"'%0' consumed in a loop", (StringRef))
772+
ERROR(sil_movechecking_use_after_partial_consume, none,
773+
"cannot use '%0' after partial consume", (StringRef))
774+
ERROR(sil_movechecking_notconsumable_but_assignable_was_consumed, none,
775+
"cannot consume noncopyable stored property '%0' %select{of a class|that is global}1",
776+
(StringRef, bool))
777+
ERROR(sil_movechecking_cannot_destructure_has_deinit, none,
778+
"cannot partially consume '%0' when it has a deinitializer",
793779
(StringRef))
794-
ERROR(sil_moveonlychecker_cannot_destructure_deinit_nominal_type_field, none,
795-
"Cannot partially consume '%0' since it contains field '%1.%2' whose type %3 has a user defined deinit",
796-
(StringRef, StringRef, StringRef, DeclBaseName))
797-
798-
NOTE(sil_moveonlychecker_moveonly_field_consumed_here, none,
799-
"move only field consumed here", ())
800-
NOTE(sil_moveonlychecker_boundary_use, none,
801-
"boundary use here", ())
802-
NOTE(sil_moveonlychecker_consuming_use_here, none,
803-
"consuming use here", ())
804-
NOTE(sil_moveonlychecker_other_consuming_use_here, none,
805-
"other consuming use here", ())
806-
NOTE(sil_moveonlychecker_two_consuming_uses_here, none,
807-
"two consuming uses here", ())
808-
NOTE(sil_moveonlychecker_consuming_and_non_consuming_uses_here, none,
809-
"consuming and non-consuming uses here", ())
810-
NOTE(sil_moveonlychecker_consuming_closure_use_here, none,
811-
"closure capture here", ())
812-
NOTE(sil_moveonlychecker_nonconsuming_use_here, none,
813-
"non-consuming use here", ())
814-
NOTE(sil_movekillscopyablevalue_value_cyclic_consumed_in_loop_here, none,
815-
"consuming in loop use here", ())
816-
NOTE(sil_moveonlychecker_deinit_here, none,
817-
"deinit declared here", ())
818-
819-
ERROR(sil_moveonlychecker_not_understand_consumable_and_assignable, none,
820-
"Usage of @noImplicitCopy that the move checker does not know how to "
821-
"check!", ())
822-
ERROR(sil_moveonlychecker_not_understand_moveonly, none,
823-
"Usage of a move only type that the move checker does not know how to "
824-
"check!", ())
825-
ERROR(sil_moveonlychecker_missed_copy, none,
826-
"copy of noncopyable typed value. This is a compiler bug. Please file a bug with a small example of the bug", ())
827780

828-
// move kills copyable values checker diagnostics
829-
ERROR(sil_movekillscopyablevalue_value_consumed_more_than_once, none,
830-
"'%0' used after being consumed", (StringRef))
831-
NOTE(sil_movekillscopyablevalue_move_here, none,
832-
"consume here", ())
833-
NOTE(sil_movekillscopyablevalue_use_here, none,
834-
"use here", ())
835-
NOTE(sil_movekillscopyablevalue_value_consumed_in_loop, none,
836-
"consume here would occur multiple times in loop", ())
781+
NOTE(sil_movechecking_partial_consume_here, none,
782+
"partially consumed here", ())
783+
NOTE(sil_movechecking_consuming_use_here, none,
784+
"consumed here", ())
785+
NOTE(sil_movechecking_consumed_again_here, none,
786+
"consumed again here", ())
787+
NOTE(sil_movechecking_two_consuming_uses_here, none,
788+
"multiple consumes here", ())
789+
NOTE(sil_movechecking_consuming_and_non_consuming_uses_here, none,
790+
"consumed and used here", ())
791+
NOTE(sil_movechecking_consuming_closure_use_here, none,
792+
"closure capturing '%0' here", (StringRef))
793+
NOTE(sil_movechecking_nonconsuming_use_here, none,
794+
"used here", ())
795+
NOTE(sil_movechecking_consumed_in_loop_here, none,
796+
"consumed in loop here", ())
797+
NOTE(sil_movechecking_deinit_here, none,
798+
"deinitializer declared here", ())
799+
800+
// errors involving noncopyables that are considered to be bugs in the compiler
801+
ERROR(sil_movechecking_not_understand_consumable_and_assignable, none,
802+
"usage of no-implicit-copy value that the compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug", ())
803+
ERROR(sil_movechecking_not_understand_moveonly, none,
804+
"usage of a noncopyable type that compiler can't verify. This is a compiler bug. Please file a bug with a small example of the bug", ())
805+
ERROR(sil_movechecking_bug_missed_copy, none,
806+
"copy of noncopyable typed value. This is a compiler bug. Please file a bug with a small example of the bug", ())
807+
ERROR(sil_movechecking_bug_exclusivity_violation, none,
808+
"'%0' has an unexpected exclusivity violation. This is a compiler bug. Please file a bug with a small example of the bug", (StringRef))
837809
ERROR(sil_movekillscopyablevalue_move_applied_to_unsupported_move, none,
838-
"'consume' applied to value that the compiler does not support checking",
810+
"'consume' applied to value that the compiler does not support. This is a compiler bug. Please file a bug with a small example of the bug",
839811
())
840812

813+
841814
// Implicit inout-to-UnsafeRawPointer conversions
842815
WARNING(nontrivial_to_rawpointer_conversion,none,
843816
"forming %1 to a variable of type %0; this is likely incorrect because %2 may contain "

include/swift/AST/DiagnosticsSema.def

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,7 @@ ERROR(expose_enum_case_tuple_to_cxx,none,
17021702
ERROR(expose_protocol_to_cxx_unsupported,none,
17031703
"protocol %0 can not yet be represented in C++", (ValueDecl *))
17041704
ERROR(expose_move_only_to_cxx,none,
1705-
"move-only %0 %1 can not yet be represented in C++", (DescriptiveDeclKind, ValueDecl *))
1705+
"noncopyable %0 %1 can not yet be represented in C++", (DescriptiveDeclKind, ValueDecl *))
17061706
ERROR(unexposed_other_decl_in_cxx,none,
17071707
"%0 %1 is not yet exposed to C++", (DescriptiveDeclKind, ValueDecl *))
17081708
ERROR(unsupported_other_decl_in_cxx,none,
@@ -6915,30 +6915,6 @@ ERROR(wrap_invalid_attr_added_by_access_note, none,
69156915

69166916
#undef WHICH_ACCESS_NOTE
69176917

6918-
// Move Only diagnostics
6919-
6920-
ERROR(experimental_moveonly_feature_can_only_be_used_when_enabled,
6921-
none, "Can not use feature when experimental move only is disabled! Pass"
6922-
" the frontend flag -enable-experimental-move-only to swift to enable "
6923-
"the usage of this language feature", ())
6924-
ERROR(noimplicitcopy_attr_valid_only_on_local_let_params,
6925-
none, "'@_noImplicitCopy' attribute can only be applied to local lets and params", ())
6926-
ERROR(noimplicitcopy_attr_invalid_in_generic_context,
6927-
none, "'@_noImplicitCopy' attribute cannot be applied to entities in generic contexts", ())
6928-
ERROR(moveonly_generics, none, "move-only type %0 cannot be used with generics yet", (Type))
6929-
ERROR(moveonly_effectful_getter,none,
6930-
"%0 of move-only type cannot be 'async' or 'throws'", (DescriptiveDeclKind))
6931-
ERROR(noimplicitcopy_attr_not_allowed_on_moveonlytype,none,
6932-
"'@_noImplicitCopy' has no effect when applied to a move only type", ())
6933-
ERROR(moveonly_enums_do_not_support_indirect,none,
6934-
"move-only enum %0 cannot be marked indirect or have indirect cases yet", (Identifier))
6935-
ERROR(moveonly_cast,none,
6936-
"move-only types cannot be conditionally cast", ())
6937-
ERROR(moveonly_failable_init,none,
6938-
"move-only types cannot have failable initializers yet", ())
6939-
ERROR(moveonly_objc_enum_banned, none,
6940-
"@objc enums cannot be marked as move-only", ())
6941-
69426918
//------------------------------------------------------------------------------
69436919
// MARK: Type inference from default expressions
69446920
//------------------------------------------------------------------------------
@@ -6996,21 +6972,6 @@ ERROR(concurrency_task_to_thread_model_global_actor_annotation,none,
69966972
"annotating a type with a global actor %0 is not permitted within %1",
69976973
(TypeRepr*, StringRef))
69986974

6999-
ERROR(moveOnly_not_allowed_here,none,
7000-
"'moveOnly' only applies to structs or enums", ())
7001-
ERROR(consume_expression_not_passed_lvalue,none,
7002-
"'consume' can only be applied to lvalues", ())
7003-
ERROR(borrow_expression_not_passed_lvalue,none,
7004-
"'borrow' can only be applied to lvalues", ())
7005-
ERROR(copy_expression_not_passed_lvalue,none,
7006-
"'copy' can only be applied to lvalues", ())
7007-
ERROR(copy_expression_cannot_be_used_with_noncopyable_types,none,
7008-
"'copy' cannot be applied to noncopyable types", ())
7009-
7010-
ERROR(moveOnly_requires_lexical_lifetimes,none,
7011-
"noncopyable types require lexical borrow scopes "
7012-
"(add -enable-lexical-borrow-scopes=true)", ())
7013-
70146975
//------------------------------------------------------------------------------
70156976
// MARK: #_hasSymbol
70166977
//------------------------------------------------------------------------------
@@ -7143,31 +7104,68 @@ NOTE(macro_expand_circular_reference_unnamed_through, none,
71437104
"circular reference expanding %0 macros", (StringRef))
71447105

71457106
//------------------------------------------------------------------------------
7146-
// MARK: Move Only Errors
7107+
// MARK: Noncopyable Types Diagnostics
71477108
//------------------------------------------------------------------------------
71487109

7149-
ERROR(moveonly_copyable_type_that_contains_moveonly_type, none,
7150-
"%0 %1 cannot contain a move-only type without also being move-only",
7110+
ERROR(noncopyable_within_copyable, none,
7111+
"%0 %1 cannot contain a noncopyable type without also being noncopyable",
71517112
(DescriptiveDeclKind, DeclName))
7152-
NOTE(moveonly_copyable_type_that_contains_moveonly_type_location, none,
7153-
"contained move-only %0 '%1.%2'",
7113+
NOTE(noncopyable_within_copyable_location, none,
7114+
"contained noncopyable %0 '%1.%2'",
71547115
(DescriptiveDeclKind, StringRef, StringRef))
7155-
ERROR(moveonly_cannot_conform_to_type, none,
7156-
"move-only %0 %1 cannot conform to %2",
7116+
ERROR(noncopyable_cannot_conform_to_type, none,
7117+
"noncopyable %0 %1 cannot conform to %2",
71577118
(DescriptiveDeclKind, DeclName, Type))
7158-
ERROR(moveonly_parameter_missing_ownership, none,
7119+
ERROR(noncopyable_parameter_requires_ownership, none,
71597120
"noncopyable parameter must specify its ownership", ())
7160-
ERROR(moveonly_parameter_subscript_unsupported, none,
7121+
ERROR(noncopyable_parameter_subscript_unsupported, none,
71617122
"subscripts cannot have noncopyable parameters yet", ())
7162-
NOTE(moveonly_parameter_ownership_suggestion, none,
7123+
NOTE(noncopyable_parameter_ownership_suggestion, none,
71637124
"add '%0' %1", (StringRef, StringRef))
71647125
ERROR(ownership_specifier_copyable,none,
7165-
"Copyable types cannot be 'consuming' or 'borrowing' yet", ())
7126+
"copyable types cannot be 'consuming' or 'borrowing' yet", ())
71667127
ERROR(self_ownership_specifier_copyable,none,
7167-
"%0 is not yet valid on %1s in a Copyable type",
7128+
"%0 is not yet valid on %1s of a copyable type",
71687129
(SelfAccessKind, DescriptiveDeclKind))
71697130
ERROR(ownership_specifier_nonescaping_closure,none,
71707131
"'%0' cannot be applied to nonescaping closure", (StringRef))
7132+
ERROR(noncopyable_generics, none, "noncopyable type %0 cannot be used with generics yet", (Type))
7133+
ERROR(noncopyable_effectful_getter,none,
7134+
"%0 of noncopyable type cannot be 'async' or 'throws'", (DescriptiveDeclKind))
7135+
ERROR(noncopyable_enums_do_not_support_indirect,none,
7136+
"noncopyable enum %0 cannot be marked indirect or have indirect cases yet", (Identifier))
7137+
ERROR(noncopyable_cast,none,
7138+
"noncopyable types cannot be conditionally cast", ())
7139+
ERROR(noncopyable_failable_init,none,
7140+
"noncopyable types cannot have failable initializers yet", ())
7141+
ERROR(noncopyable_objc_enum, none,
7142+
"noncopyable enums cannot be marked '@objc'", ())
7143+
ERROR(moveOnly_not_allowed_here,none,
7144+
"'@_moveOnly' attribute is only valid on structs or enums", ())
7145+
ERROR(consume_expression_not_passed_lvalue,none,
7146+
"'consume' can only be applied to a local binding ('let', 'var', or parameter)", ())
7147+
ERROR(borrow_expression_not_passed_lvalue,none,
7148+
"'borrow' can only be applied to a local binding ('let', 'var', or parameter)", ())
7149+
ERROR(copy_expression_not_passed_lvalue,none,
7150+
"'copy' can only be applied to a local binding ('let', 'var', or parameter)", ())
7151+
ERROR(copy_expression_cannot_be_used_with_noncopyable_types,none,
7152+
"'copy' cannot be applied to noncopyable types", ())
7153+
7154+
ERROR(moveOnly_requires_lexical_lifetimes,none,
7155+
"noncopyable types require lexical borrow scopes "
7156+
"(add -enable-lexical-borrow-scopes=true)", ())
7157+
7158+
// Experimental noncopyable feature diagnostics:
7159+
ERROR(experimental_moveonly_feature_can_only_be_used_when_enabled,
7160+
none, "Can not use feature when experimental move only is disabled! Pass"
7161+
" the frontend flag -enable-experimental-move-only to swift to enable "
7162+
"the usage of this language feature", ())
7163+
ERROR(noimplicitcopy_attr_valid_only_on_local_let_params,
7164+
none, "'@_noImplicitCopy' attribute can only be applied to local lets and params", ())
7165+
ERROR(noimplicitcopy_attr_invalid_in_generic_context,
7166+
none, "'@_noImplicitCopy' attribute cannot be applied to entities in generic contexts", ())
7167+
ERROR(noimplicitcopy_attr_not_allowed_on_moveonlytype,none,
7168+
"'@_noImplicitCopy' has no effect when applied to a noncopyable type", ())
71717169

71727170
//------------------------------------------------------------------------------
71737171
// MARK: Runtime discoverable attributes (@runtimeMetadata)

lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,19 +507,19 @@ void FieldSensitivePrunedLiveBlocks::updateForUse(
507507

508508
auto *bb = user->getParent();
509509
getBlockLiveness(bb, startBitNo, endBitNo, resultingLivenessInfo);
510+
assert(resultingLivenessInfo.size() == (endBitNo - startBitNo));
510511

511-
for (auto pair : llvm::enumerate(resultingLivenessInfo)) {
512-
unsigned index = pair.index();
512+
for (unsigned index : indices(resultingLivenessInfo)) {
513513
unsigned specificBitNo = startBitNo + index;
514-
switch (pair.value()) {
514+
switch (resultingLivenessInfo[index]) {
515515
case LiveOut:
516516
case LiveWithin:
517517
continue;
518518
case Dead: {
519519
// This use block has not yet been marked live. Mark it and its
520520
// predecessor blocks live.
521521
computeScalarUseBlockLiveness(bb, specificBitNo);
522-
resultingLivenessInfo.push_back(getBlockLiveness(bb, specificBitNo));
522+
resultingLivenessInfo[index] = getBlockLiveness(bb, specificBitNo);
523523
continue;
524524
}
525525
}
@@ -537,6 +537,7 @@ FieldSensitivePrunedLiveBlocks::getStringRef(IsLive isLive) const {
537537
case LiveOut:
538538
return "LiveOut";
539539
}
540+
llvm_unreachable("Covered switch?!");
540541
}
541542

542543
void FieldSensitivePrunedLiveBlocks::print(llvm::raw_ostream &OS) const {

0 commit comments

Comments
 (0)