Skip to content

Commit 0ca7826

Browse files
committed
[ModuleInterface] Allow global/static variables without initial values
1 parent f061dff commit 0ca7826

File tree

2 files changed

+51
-23
lines changed

2 files changed

+51
-23
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2520,45 +2520,61 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
25202520
if (!var->hasStorage())
25212521
return;
25222522

2523+
if (var->isInvalid() || PBD->isInvalid())
2524+
return;
2525+
25232526
auto *varDC = var->getDeclContext();
25242527

2525-
// Non-member observing properties need an initializer.
2526-
if (var->getWriteImpl() == WriteImplKind::StoredWithObservers &&
2527-
!isTypeContext && !var->isInvalid() && !PBD->isInvalid()) {
2528-
TC.diagnose(var->getLoc(), diag::observingprop_requires_initializer);
2528+
auto markVarAndPBDInvalid = [PBD, var] {
25292529
PBD->setInvalid();
25302530
var->setInvalid();
2531-
if (!var->hasType()) {
2531+
if (!var->hasType())
25322532
var->markInvalid();
2533-
}
2533+
};
2534+
2535+
// Non-member observing properties need an initializer.
2536+
if (var->getWriteImpl() == WriteImplKind::StoredWithObservers &&
2537+
!isTypeContext) {
2538+
TC.diagnose(var->getLoc(), diag::observingprop_requires_initializer);
2539+
markVarAndPBDInvalid();
25342540
return;
25352541
}
25362542

25372543
// Static/class declarations require an initializer unless in a
25382544
// protocol.
2539-
if (var->isStatic() && !isa<ProtocolDecl>(varDC) &&
2540-
!var->isInvalid() && !PBD->isInvalid()) {
2545+
if (var->isStatic() && !isa<ProtocolDecl>(varDC)) {
2546+
// ...but don't enforce this for SIL or textual interface files.
2547+
switch (varDC->getParentSourceFile()->Kind) {
2548+
case SourceFileKind::Interface:
2549+
case SourceFileKind::SIL:
2550+
return;
2551+
case SourceFileKind::Main:
2552+
case SourceFileKind::REPL:
2553+
case SourceFileKind::Library:
2554+
break;
2555+
}
2556+
25412557
TC.diagnose(var->getLoc(), diag::static_requires_initializer,
25422558
var->getCorrectStaticSpelling());
2543-
PBD->setInvalid();
2544-
var->setInvalid();
2545-
if (!var->hasType()) {
2546-
var->markInvalid();
2547-
}
2559+
markVarAndPBDInvalid();
25482560
return;
25492561
}
25502562

2551-
// Global variables require an initializer (except in top level code).
2552-
if (varDC->isModuleScopeContext() &&
2553-
!varDC->getParentSourceFile()->isScriptMode() &&
2554-
!var->isInvalid() && !PBD->isInvalid()) {
2555-
TC.diagnose(var->getLoc(),
2556-
diag::global_requires_initializer, var->isLet());
2557-
PBD->setInvalid();
2558-
var->setInvalid();
2559-
if (!var->hasType()) {
2560-
var->markInvalid();
2563+
// Global variables require an initializer in normal source files.
2564+
if (varDC->isModuleScopeContext()) {
2565+
switch (varDC->getParentSourceFile()->Kind) {
2566+
case SourceFileKind::Main:
2567+
case SourceFileKind::REPL:
2568+
case SourceFileKind::Interface:
2569+
case SourceFileKind::SIL:
2570+
return;
2571+
case SourceFileKind::Library:
2572+
break;
25612573
}
2574+
2575+
TC.diagnose(var->getLoc(), diag::global_requires_initializer,
2576+
var->isLet());
2577+
markVarAndPBDInvalid();
25622578
return;
25632579
}
25642580
});

test/ModuleInterface/SmokeTest.swiftinterface

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class TestClass {
2222
// CHECK: public var prop: Int{{$}}
2323
public var prop: Int { get set }
2424

25+
// CHECK: public static var propWithNoAccessors: Int{{$}}
26+
public static var propWithNoAccessors: Int
27+
2528
// NEGATIVE-NOT: deinit
2629
deinit
2730
} // CHECK: {{^}$}}
@@ -42,6 +45,9 @@ public enum TestEnum {
4245

4346
// CHECK: public var prop: Int{{$}}
4447
public var prop: Int { get set }
48+
49+
// CHECK: public static var propWithNoAccessors: Int{{$}}
50+
public static var propWithNoAccessors: Int
4551
} // CHECK: {{^}$}}
4652

4753
// CHECK-LABEL: public struct TestStruct
@@ -57,8 +63,14 @@ public struct TestStruct {
5763

5864
// CHECK: public var prop: Int{{$}}
5965
public var prop: Int { get set }
66+
67+
// CHECK: public static var propWithNoAccessors: Int{{$}}
68+
public static var propWithNoAccessors: Int
6069
} // CHECK: {{^}$}}
6170

71+
// CHECK: public let globalWithNoAccessors: Int{{$}}
72+
public let globalWithNoAccessors: Int
73+
6274
// CHECK: public var readOnlyVar: Int { get }{{$}}
6375
public var readOnlyVar: Int { get }
6476

0 commit comments

Comments
 (0)