Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,8 @@ void SILGenModule::preEmitFunction(SILDeclRef constant,

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

F->setGenericEnvironment(Types.getConstantInfo(constant).GenericEnv);
if (F->getLoweredFunctionType()->isPolymorphic())
F->setGenericEnvironment(Types.getConstantInfo(constant).GenericEnv);

// Create a debug scope for the function using astNode as source location.
F->setDebugScope(new (M) SILDebugScope(Loc, F));
Expand Down
9 changes: 6 additions & 3 deletions lib/SILGen/SILGenGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd,
unsigned pbdEntry) {
// Generic and dynamic static properties require lazy initialization, which
// isn't implemented yet.
if (pd->isStatic())
assert(!pd->getDeclContext()->isGenericContext());
if (pd->isStatic()) {
assert(!pd->getDeclContext()->isGenericContext()
|| pd->getDeclContext()->getGenericSignatureOfContext()
->areAllParamsConcrete());
}

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

SILFunction *onceFunc = emitLazyGlobalInitializer(onceFuncBuffer, pd,
pbdEntry);
Expand Down
5 changes: 0 additions & 5 deletions lib/SILGen/SILGenLValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1735,11 +1735,6 @@ void LValue::addMemberVarComponent(SILGenFunction &gen, SILLocation loc,
// FIXME: This has to be dynamically looked up for classes, and
// dynamically instantiated for generics.
if (strategy == AccessStrategy::Storage && var->isStatic()) {
auto baseMeta = baseFormalType->castTo<MetatypeType>()->getInstanceType();
(void)baseMeta;
assert(!baseMeta->is<BoundGenericType>() &&
"generic static stored properties not implemented");

// FIXME: this implicitly drops the earlier components, but maybe
// we ought to evaluate them for side-effects even during the
// formal access?
Expand Down
15 changes: 8 additions & 7 deletions lib/SILGen/SILGenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,13 @@ class SILGenVTable : public Lowering::ASTVisitor<SILGenVTable> {
};

static void emitTypeMemberGlobalVariable(SILGenModule &SGM,
GenericParamList *generics,
NominalTypeDecl *theType,
VarDecl *var) {
assert(!generics && "generic static properties not implemented");
if (var->getDeclContext()->isGenericContext()) {
assert(var->getDeclContext()->getGenericSignatureOfContext()
->areAllParamsConcrete()
&& "generic static vars are not implemented yet");
}

if (var->getDeclContext()->getAsClassOrClassExtensionContext()) {
assert(var->isFinal() && "only 'static' ('class final') stored properties are implemented in classes");
}
Expand Down Expand Up @@ -405,8 +408,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
// Collect global variables for static properties.
// FIXME: We can't statically emit a global variable for generic properties.
if (vd->isStatic() && vd->hasStorage()) {
return emitTypeMemberGlobalVariable(SGM, theType->getGenericParams(),
theType, vd);
return emitTypeMemberGlobalVariable(SGM, vd);
}

visitAbstractStorageDecl(vd);
Expand Down Expand Up @@ -494,8 +496,7 @@ class SILGenExtension : public TypeMemberVisitor<SILGenExtension> {
assert(vd->isStatic() && "stored property in extension?!");
ExtensionDecl *ext = cast<ExtensionDecl>(vd->getDeclContext());
NominalTypeDecl *theType = ext->getExtendedType()->getAnyNominal();
return emitTypeMemberGlobalVariable(SGM, ext->getGenericParams(),
theType, vd);
return emitTypeMemberGlobalVariable(SGM, vd);
}
visitAbstractStorageDecl(vd);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3701,7 +3701,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

// Stored type variables in a generic context need to logically
// occur once per instantiation, which we don't yet handle.
} else if (DC->isGenericContext()) {
} else if (DC->isGenericContext()
&& !DC->getGenericSignatureOfContext()->areAllParamsConcrete()) {
unimplementedStatic(GenericTypes);
} else if (DC->getAsClassOrClassExtensionContext()) {
auto StaticSpelling = PBD->getStaticSpelling();
Expand Down
21 changes: 21 additions & 0 deletions test/SILGen/static-stored-properties-in-concrete-contexts.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s

struct Foo<T> {
static var foo: T { return (0 as Int) as! T }
}

extension Foo where T == Int {
// CHECK: sil_global private [[X_TOKEN:@.*]] : $Builtin.Word
// CHECK: sil_global hidden [let] @_TZve4mainRxzSirVS_3Foo1xSi : $Int
static let x = foo

// CHECK: sil_global private [[Y_TOKEN:@.*]] : $Builtin.Word
// CHECK: sil_global hidden @_TZve4mainRxzSirVS_3Foo1ySi : $Int
static var y = foo
}

print(Foo<Int>.x)
Foo<Int>.y = 2
Foo<Int>.y += 3
print(Foo<Int>.y)