Skip to content

Commit 4afdc9d

Browse files
committed
AST: Lazily map archetype superclass into context
We don't really want to support this, at least not yet, but there are ways to sneak it past the diagnostic that are hard to close. Fixes rdar://problem/135348472.
1 parent 08bb001 commit 4afdc9d

File tree

4 files changed

+71
-20
lines changed

4 files changed

+71
-20
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6580,11 +6580,7 @@ class ArchetypeType : public SubstitutableType,
65806580
bool requiresClass() const;
65816581

65826582
/// Retrieve the superclass of this type, if such a requirement exists.
6583-
Type getSuperclass() const {
6584-
if (!Bits.ArchetypeType.HasSuperclass) return Type();
6585-
6586-
return *getSubclassTrailingObjects<Type>();
6587-
}
6583+
Type getSuperclass() const;
65886584

65896585
/// Retrieve the layout constraint of this type, if such a requirement exists.
65906586
LayoutConstraint getLayoutConstraint() const {

lib/AST/GenericEnvironment.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -404,14 +404,6 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
404404
// requirements.
405405
auto requirements = genericSig->getLocalRequirements(reducedType);
406406

407-
// Substitute into the superclass.
408-
Type superclass = requirements.superclass;
409-
if (superclass && superclass->hasTypeParameter()) {
410-
superclass = mapTypeIntoContext(superclass);
411-
if (superclass->is<ErrorType>())
412-
superclass = Type();
413-
}
414-
415407
Type result;
416408

417409
auto sugaredType = genericSig->getSugaredType(reducedType);
@@ -422,11 +414,13 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
422414
if (rootGP->isParameterPack()) {
423415
result = PackArchetypeType::get(ctx, this, sugaredType,
424416
requirements.packShape,
425-
requirements.protos, superclass,
417+
requirements.protos,
418+
requirements.superclass,
426419
requirements.layout);
427420
} else {
428421
result = PrimaryArchetypeType::getNew(ctx, this, sugaredType,
429-
requirements.protos, superclass,
422+
requirements.protos,
423+
requirements.superclass,
430424
requirements.layout);
431425
}
432426

@@ -442,7 +436,8 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
442436
}
443437

444438
result = OpaqueTypeArchetypeType::getNew(this, sugaredType,
445-
requirements.protos, superclass,
439+
requirements.protos,
440+
requirements.superclass,
446441
requirements.layout);
447442
break;
448443
}
@@ -468,10 +463,12 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
468463
protos.push_back(proto);
469464

470465
result = OpenedArchetypeType::getNew(this, sugaredType, protos,
471-
superclass, requirements.layout);
466+
requirements.superclass,
467+
requirements.layout);
472468
} else {
473469
result = OpenedArchetypeType::getNew(this, sugaredType,
474-
requirements.protos, superclass,
470+
requirements.protos,
471+
requirements.superclass,
475472
requirements.layout);
476473
}
477474

@@ -485,7 +482,8 @@ GenericEnvironment::getOrCreateArchetypeFromInterfaceType(Type depType) {
485482
}
486483

487484
result = ElementArchetypeType::getNew(this, sugaredType,
488-
requirements.protos, superclass,
485+
requirements.protos,
486+
requirements.superclass,
489487
requirements.layout);
490488
break;
491489
}

lib/AST/Type.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3450,6 +3450,14 @@ bool ArchetypeType::requiresClass() const {
34503450
return false;
34513451
}
34523452

3453+
Type ArchetypeType::getSuperclass() const {
3454+
if (!Bits.ArchetypeType.HasSuperclass) return Type();
3455+
3456+
auto *genericEnv = getGenericEnvironment();
3457+
return genericEnv->mapTypeIntoContext(
3458+
*getSubclassTrailingObjects<Type>());
3459+
}
3460+
34533461
Type ArchetypeType::getValueType() const {
34543462
if (auto gp = getInterfaceType()->getAs<GenericTypeParamType>())
34553463
return gp->getValueType();
@@ -3506,7 +3514,12 @@ static RecursiveTypeProperties archetypeProperties(
35063514
}
35073515
}
35083516

3509-
if (superclass) properties |= superclass->getRecursiveProperties();
3517+
if (superclass) {
3518+
auto superclassProps = superclass->getRecursiveProperties();
3519+
superclassProps.removeHasTypeParameter();
3520+
superclassProps.removeHasDependentMember();
3521+
properties |= superclassProps;
3522+
}
35103523

35113524
return properties;
35123525
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// While we disallow explicitly-stated requirements like
4+
// `T: C<T>`, there are ways to sneak them past the
5+
// diagnostic.
6+
//
7+
// We could relax the diagnostic eventually by rejecting
8+
// the truly invalid cases, where the superclass contains
9+
// a member type of a conformance made redundant by the
10+
// superclass requirement itself.
11+
12+
class C<T> {
13+
var t: T
14+
15+
init(t: T) {
16+
self.t = t
17+
}
18+
}
19+
20+
protocol P1 {
21+
associatedtype A: C<B.A>
22+
associatedtype B: P1
23+
}
24+
25+
func f<T: P1>(_: T, t: T.A) -> C<T.B.B.B.B.A> {
26+
return t.t.t.t
27+
}
28+
29+
protocol P2 {
30+
associatedtype A: C<B>
31+
associatedtype B
32+
}
33+
34+
extension P2 where Self == A {
35+
func f() -> C<B> {
36+
return self
37+
}
38+
}
39+
40+
extension P2 where Self == A, A == B {
41+
func g() -> C<Self> {
42+
return self
43+
}
44+
}

0 commit comments

Comments
 (0)