Skip to content

Commit 6f4e9a9

Browse files
authored
Merge pull request #4875 from DougGregor/sr-993-3_0
[Type checker] Don't infer 'dynamic' for 'let' variables or within final classes
2 parents d99e1b0 + 23afce9 commit 6f4e9a9

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2104,16 +2104,29 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
21042104
return;
21052105

21062106
// Only introduce 'dynamic' on declarations...
2107+
bool isNSManaged = D->getAttrs().hasAttribute<NSManagedAttr>();
21072108
if (!isa<ExtensionDecl>(D->getDeclContext())) {
21082109
// ...and in classes on decls marked @NSManaged.
2109-
if (!D->getAttrs().hasAttribute<NSManagedAttr>())
2110+
if (!isNSManaged)
21102111
return;
21112112
}
21122113

21132114
// The presence of 'dynamic' or 'final' blocks the inference of 'dynamic'.
21142115
if (D->isDynamic() || D->isFinal())
21152116
return;
21162117

2118+
// Variables declared with 'let' cannot be 'dynamic'.
2119+
if (auto VD = dyn_cast<VarDecl>(D)) {
2120+
if (VD->isLet() && !isNSManaged) return;
2121+
}
2122+
2123+
// The presence of 'final' on a class prevents 'dynamic'.
2124+
auto classDecl = D->getDeclContext()->getAsClassOrClassExtensionContext();
2125+
if (!classDecl) return;
2126+
if (!isNSManaged && classDecl->isFinal() &&
2127+
!classDecl->requiresStoredPropertyInits())
2128+
return;
2129+
21172130
// Add the 'dynamic' attribute.
21182131
D->getAttrs().add(new (ctx) DynamicAttr(/*isImplicit=*/true));
21192132
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil -I %S/Inputs/custom-modules %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
// Note: make sure we don't get a bogus error from nowhere,
8+
// error: a declaration cannot be both 'final' and 'dynamic'
9+
extension NSObject {
10+
public static let staticIntProperty: Int = 17
11+
}
12+
13+
final class MyClass : NSObject { }
14+
15+
extension MyClass {
16+
public static var otherStaticIntProperty: Int = 17
17+
}

0 commit comments

Comments
 (0)