Skip to content

Commit ddd36a7

Browse files
authored
Merge pull request #79662 from swiftlang/gaborh/dynamic-self-frt
[cxx-interop] Interpret Self as a static shorthand for FRTs
2 parents 605f1c9 + 8f58ad6 commit ddd36a7

File tree

6 files changed

+63
-4
lines changed

6 files changed

+63
-4
lines changed

lib/ClangImporter/ImportDecl.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -3028,6 +3028,10 @@ namespace {
30283028
/*Obsoleted=*/{});
30293029
classDecl->getAttrs().add(AvAttr);
30303030
}
3031+
3032+
if (decl->isEffectivelyFinal())
3033+
classDecl->getAttrs().add(new (Impl.SwiftContext)
3034+
FinalAttr(/*IsImplicit=*/true));
30313035
}
30323036

30333037
// If this module is declared as a C++ module, try to synthesize

lib/Sema/PreCheckTarget.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,8 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
709709
if (DeclContext *typeContext = DC->getInnermostTypeContext()){
710710
Type SelfType = typeContext->getSelfInterfaceType();
711711

712-
if (typeContext->getSelfClassDecl())
712+
if (typeContext->getSelfClassDecl() &&
713+
!typeContext->getSelfClassDecl()->isForeignReferenceType())
713714
SelfType = DynamicSelfType::get(SelfType, Context);
714715
return new (Context)
715716
TypeExpr(new (Context) SelfTypeRepr(SelfType, Loc));

lib/Sema/TypeCheckType.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,10 @@ static SelfTypeKind getSelfTypeKind(DeclContext *dc,
16791679
if (!typeDC->getSelfClassDecl())
16801680
return SelfTypeKind::StaticSelf;
16811681

1682+
// For foreign reference types `Self` is a shorthand for the nominal type.
1683+
if (typeDC->getSelfClassDecl()->isForeignReferenceType())
1684+
return SelfTypeKind::StaticSelf;
1685+
16821686
// In class methods, 'Self' is the DynamicSelfType and can only appear in
16831687
// the return type.
16841688
switch (options.getBaseContext()) {

test/Interop/Cxx/foreign-reference/Inputs/inheritance.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ DerivedFromValueTypeAndAnnotated *returnDerivedFromValueTypeAndAnnotated() { //
109109
return new DerivedFromValueTypeAndAnnotated();
110110
}
111111

112-
struct DerivedFromRefType : RefType {};
112+
struct DerivedFromRefType final : RefType {};
113113
DerivedFromRefType *returnDerivedFromRefType() {
114114
return new DerivedFromRefType();
115115
}
@@ -180,7 +180,7 @@ __attribute__((swift_attr("release:RCRelease"))) RefType {};
180180

181181
RefType *returnRefType() { return new RefType(); }; // expected-warning {{'returnRefType' should be annotated with either SWIFT_RETURNS_RETAINED or SWIFT_RETURNS_UNRETAINED as it is returning a SWIFT_SHARED_REFERENC}}
182182

183-
struct DerivedFromRefType : RefType {};
183+
struct DerivedFromRefType final : RefType {};
184184
DerivedFromRefType *returnDerivedFromRefType() { // TODO: rdar://145098078 Missing SWIFT_RETURNS_(UN)RETAINED annotation warning should trigger for inferred foreeign reference types as well
185185
return new DerivedFromRefType();
186186
};

test/Interop/Cxx/foreign-reference/Inputs/reference-counted.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace NS {
1414

1515
struct __attribute__((swift_attr("import_as_ref")))
1616
__attribute__((swift_attr("retain:LCRetain")))
17-
__attribute__((swift_attr("release:LCRelease"))) LocalCount {
17+
__attribute__((swift_attr("release:LCRelease"))) LocalCount final {
1818
int value = 0;
1919

2020
static LocalCount *create() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -cxx-interoperability-mode=default -Xfrontend -disable-availability-checking -Onone) | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
// Metadata for foreign reference types is not supported on Windows.
5+
// UNSUPPORTED: OS=windows-msvc
6+
7+
import ReferenceCounted
8+
9+
protocol MyProto {
10+
static func g()
11+
func foo() -> Self
12+
func bar(_ x: Self)
13+
func baz()
14+
}
15+
16+
extension NS.LocalCount: MyProto {
17+
static func g() {
18+
print("Static method g called")
19+
}
20+
21+
public func foo() -> Self {
22+
Self.g()
23+
return self
24+
}
25+
26+
public func bar(_ x: Self) {
27+
}
28+
}
29+
30+
extension MyProto {
31+
func baz() {
32+
Self.g()
33+
}
34+
}
35+
36+
extension NS.LocalCount {
37+
public func f() {
38+
Self.g()
39+
}
40+
}
41+
42+
43+
let x = NS.LocalCount.create()
44+
x.f()
45+
// CHECK: Static method g called
46+
let _ = x.foo()
47+
// CHECK-NEXT: Static method g called
48+
let _ = x.baz()
49+
// CHECK-NEXT: Static method g called
50+
x.bar(x)

0 commit comments

Comments
 (0)