Skip to content

Commit fc86f35

Browse files
authored
Merge pull request #7750 from jckarter/static-stored-vars-in-concrete-extensions
SILGen: Allow static stored properties in fully-concrete extensions of generic types.
2 parents c6f305b + 886c83f commit fc86f35

File tree

6 files changed

+39
-17
lines changed

6 files changed

+39
-17
lines changed

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,8 @@ void SILGenModule::preEmitFunction(SILDeclRef constant,
594594

595595
assert(F->empty() && "already emitted function?!");
596596

597-
F->setGenericEnvironment(Types.getConstantInfo(constant).GenericEnv);
597+
if (F->getLoweredFunctionType()->isPolymorphic())
598+
F->setGenericEnvironment(Types.getConstantInfo(constant).GenericEnv);
598599

599600
// Create a debug scope for the function using astNode as source location.
600601
F->setDebugScope(new (M) SILDebugScope(Loc, F));

lib/SILGen/SILGenGlobalVariable.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,11 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd,
201201
unsigned pbdEntry) {
202202
// Generic and dynamic static properties require lazy initialization, which
203203
// isn't implemented yet.
204-
if (pd->isStatic())
205-
assert(!pd->getDeclContext()->isGenericContext());
204+
if (pd->isStatic()) {
205+
assert(!pd->getDeclContext()->isGenericContext()
206+
|| pd->getDeclContext()->getGenericSignatureOfContext()
207+
->areAllParamsConcrete());
208+
}
206209

207210
// Emit the lazy initialization token for the initialization expression.
208211
auto counter = anonymousSymbolCounter++;
@@ -248,7 +251,7 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd,
248251
NewMangling::ASTMangler NewMangler;
249252
std::string New = NewMangler.mangleGlobalInit(varDecl, counter, true);
250253
onceFuncBuffer = NewMangling::selectMangling(Old, New);
251-
}
254+
}
252255

253256
SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncBuffer, pd,
254257
pbdEntry);

lib/SILGen/SILGenLValue.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,11 +1757,6 @@ void LValue::addMemberVarComponent(SILGenFunction &gen, SILLocation loc,
17571757
// FIXME: This has to be dynamically looked up for classes, and
17581758
// dynamically instantiated for generics.
17591759
if (strategy == AccessStrategy::Storage && var->isStatic()) {
1760-
auto baseMeta = baseFormalType->castTo<MetatypeType>()->getInstanceType();
1761-
(void)baseMeta;
1762-
assert(!baseMeta->is<BoundGenericType>() &&
1763-
"generic static stored properties not implemented");
1764-
17651760
// FIXME: this implicitly drops the earlier components, but maybe
17661761
// we ought to evaluate them for side-effects even during the
17671762
// formal access?

lib/SILGen/SILGenType.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,13 @@ class SILGenVTable : public Lowering::ASTVisitor<SILGenVTable> {
299299
};
300300

301301
static void emitTypeMemberGlobalVariable(SILGenModule &SGM,
302-
GenericParamList *generics,
303-
NominalTypeDecl *theType,
304302
VarDecl *var) {
305-
assert(!generics && "generic static properties not implemented");
303+
if (var->getDeclContext()->isGenericContext()) {
304+
assert(var->getDeclContext()->getGenericSignatureOfContext()
305+
->areAllParamsConcrete()
306+
&& "generic static vars are not implemented yet");
307+
}
308+
306309
if (var->getDeclContext()->getAsClassOrClassExtensionContext()) {
307310
assert(var->isFinal() && "only 'static' ('class final') stored properties are implemented in classes");
308311
}
@@ -405,8 +408,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
405408
// Collect global variables for static properties.
406409
// FIXME: We can't statically emit a global variable for generic properties.
407410
if (vd->isStatic() && vd->hasStorage()) {
408-
return emitTypeMemberGlobalVariable(SGM, theType->getGenericParams(),
409-
theType, vd);
411+
return emitTypeMemberGlobalVariable(SGM, vd);
410412
}
411413

412414
visitAbstractStorageDecl(vd);
@@ -494,8 +496,7 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
494496
assert(vd->isStatic() && "stored property in extension?!");
495497
ExtensionDecl *ext = cast<ExtensionDecl>(vd->getDeclContext());
496498
NominalTypeDecl *theType = ext->getExtendedType()->getAnyNominal();
497-
return emitTypeMemberGlobalVariable(SGM, ext->getGenericParams(),
498-
theType, vd);
499+
return emitTypeMemberGlobalVariable(SGM, vd);
499500
}
500501
visitAbstractStorageDecl(vd);
501502
}

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3701,7 +3701,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
37013701

37023702
// Stored type variables in a generic context need to logically
37033703
// occur once per instantiation, which we don't yet handle.
3704-
} else if (DC->isGenericContext()) {
3704+
} else if (DC->isGenericContext()
3705+
&& !DC->getGenericSignatureOfContext()->areAllParamsConcrete()) {
37053706
unimplementedStatic(GenericTypes);
37063707
} else if (DC->getAsClassOrClassExtensionContext()) {
37073708
auto StaticSpelling = PBD->getStaticSpelling();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
2+
3+
struct Foo<T> {
4+
static var foo: T { return (0 as Int) as! T }
5+
}
6+
7+
extension Foo where T == Int {
8+
// CHECK: sil_global private [[X_TOKEN:@.*]] : $Builtin.Word
9+
// CHECK: sil_global hidden [let] @_TZve4mainRxzSirVS_3Foo1xSi : $Int
10+
static let x = foo
11+
12+
// CHECK: sil_global private [[Y_TOKEN:@.*]] : $Builtin.Word
13+
// CHECK: sil_global hidden @_TZve4mainRxzSirVS_3Foo1ySi : $Int
14+
static var y = foo
15+
}
16+
17+
print(Foo<Int>.x)
18+
Foo<Int>.y = 2
19+
Foo<Int>.y += 3
20+
print(Foo<Int>.y)
21+

0 commit comments

Comments
 (0)