Skip to content

Commit 69701b1

Browse files
committed
AST: Fix "statically derived metatype" check
A static reference to DynamicSelfType can only be written as an implicit member expression where the contextual type is a DynamicSelfType, ie, 'return .init(...)' in a static method returning Self. In this case, the base expression is not a statically-derived metatype.
1 parent ccc23c9 commit 69701b1

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

lib/AST/Expr.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -639,15 +639,24 @@ bool Expr::isTypeReference(
639639

640640
bool Expr::isStaticallyDerivedMetatype(
641641
llvm::function_ref<Type(const Expr *)> getType) const {
642-
// The type must first be a type reference.
642+
// The expression must first be a type reference.
643643
if (!isTypeReference(getType))
644644
return false;
645645

646+
auto type = getType(this)
647+
->castTo<AnyMetatypeType>()
648+
->getInstanceType();
649+
646650
// Archetypes are never statically derived.
647-
return !getType(this)
648-
->getAs<AnyMetatypeType>()
649-
->getInstanceType()
650-
->is<ArchetypeType>();
651+
if (type->is<ArchetypeType>())
652+
return false;
653+
654+
// Dynamic Self is never statically derived.
655+
if (type->is<DynamicSelfType>())
656+
return false;
657+
658+
// Everything else is statically derived.
659+
return true;
651660
}
652661

653662
bool Expr::isSuperExpr() const {

test/expr/postfix/call/construction.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ enum E {
2121
}
2222

2323
class C {
24-
init(i: Int) { } // expected-note 3{{selected non-required initializer 'init(i:)'}}
24+
init(i: Int) { } // expected-note 4{{selected non-required initializer 'init(i:)'}}
2525

2626
required init(d: Double) { }
2727

@@ -49,7 +49,7 @@ class C {
4949

5050
static func makeSelfImplicitBaseBad() -> Self {
5151
return .init(i: 0)
52-
// FIXME
52+
// expected-error@-1 {{constructing an object of class type 'Self' with a metatype value must use a 'required' initializer}}
5353
}
5454

5555
static func makeSelfImplicitBaseGood() -> Self {

0 commit comments

Comments
 (0)