Skip to content

Commit f9ede2a

Browse files
authored
Merge pull request #83804 from egorzhdan/egorzhdan/6.2-weak-references
🍒[cxx-interop] Prohibit weak references to foreign reference types
2 parents 49dbb15 + 92b7bc7 commit f9ede2a

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6275,6 +6275,9 @@ ERROR(invalid_ownership_protocol_type,none,
62756275
ERROR(invalid_ownership_incompatible_class,none,
62766276
"%0 is incompatible with %1 references",
62776277
(Type, ReferenceOwnership))
6278+
ERROR(invalid_ownership_incompatible_foreign_reference_type,none,
6279+
"%0 is incompatible with 'weak' references, because it is a foreign reference type",
6280+
(Type))
62786281
ERROR(invalid_ownership_with_optional,none,
62796282
"%0 variable cannot have optional type", (ReferenceOwnership))
62806283
ERROR(invalid_ownership_not_optional,none,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5294,13 +5294,28 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
52945294
}
52955295

52965296
ClassDecl *underlyingClass = underlyingType->getClassOrBoundGenericClass();
5297-
if (underlyingClass && underlyingClass->isIncompatibleWithWeakReferences()) {
5298-
Diags
5299-
.diagnose(attr->getLocation(),
5300-
diag::invalid_ownership_incompatible_class, underlyingType,
5301-
ownershipKind)
5302-
.fixItRemove(attr->getRange());
5303-
attr->setInvalid();
5297+
if (underlyingClass) {
5298+
if (underlyingClass->isIncompatibleWithWeakReferences()) {
5299+
Diags
5300+
.diagnose(attr->getLocation(),
5301+
diag::invalid_ownership_incompatible_class, underlyingType,
5302+
ownershipKind)
5303+
.fixItRemove(attr->getRange());
5304+
attr->setInvalid();
5305+
}
5306+
// Foreign reference types cannot be held as weak references, since the
5307+
// Swift runtime has no way to make the pointer null when the object is
5308+
// deallocated.
5309+
// Unowned references to foreign reference types are supported.
5310+
if (ownershipKind == ReferenceOwnership::Weak &&
5311+
underlyingClass->isForeignReferenceType()) {
5312+
Diags
5313+
.diagnose(attr->getLocation(),
5314+
diag::invalid_ownership_incompatible_foreign_reference_type,
5315+
underlyingType)
5316+
.fixItRemove(attr->getRange());
5317+
attr->setInvalid();
5318+
}
53045319
}
53055320

53065321
auto PDC = dyn_cast<ProtocolDecl>(dc);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift -cxx-interoperability-mode=default -I %S/Inputs -disable-availability-checking
2+
3+
import POD
4+
5+
struct HasWeakReference {
6+
weak var x: Empty? // expected-error {{'Empty' is incompatible with 'weak' references, because it is a foreign reference type}}
7+
}
8+
9+
struct HasUnownedReference {
10+
unowned var x: Empty!
11+
}

0 commit comments

Comments
 (0)