Skip to content

Commit 68dc945

Browse files
committed
Sema: Remove redundant mapType{Into,OutOf}Context() calls
The code in recordTypeWitness() seemed to be completely bogus; it already receives a type written in terms of the archetypes of the adoptee's context, so mapTypeOutOfContext() did nothing here, because it was using the wrong substitutions. The logic for synthesizing designated initializers was also slightly wrong if the class was nested inside a generic function. Finally, interface and contextual types of a derived rawValue were flipped around.
1 parent 584eda3 commit 68dc945

File tree

6 files changed

+29
-33
lines changed

6 files changed

+29
-33
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,15 +2060,17 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
20602060
return nullptr;
20612061

20622062
// Lookup will sometimes give us initializers that are from the ancestors of
2063-
// our immediate superclass. So, from the superclass constructor, we look
2064-
// one level up to the enclosing type context which will either be a class
2063+
// our immediate superclass. So, from the superclass constructor, we look
2064+
// one level up to the enclosing type context which will either be a class
20652065
// or an extension. We can use the type declared in that context to check
20662066
// if it's our immediate superclass and give up if we didn't.
2067-
//
2067+
//
20682068
// FIXME: Remove this when lookup of initializers becomes restricted to our
20692069
// immediate superclass.
2070-
Type superclassTyInCtor = superclassCtor->getDeclContext()->getDeclaredTypeInContext();
2070+
Type superclassTyInCtor = superclassCtor->getDeclContext()->getDeclaredTypeOfContext();
20712071
Type superclassTy = classDecl->getSuperclass();
2072+
Type superclassTyInContext = ArchetypeBuilder::mapTypeIntoContext(
2073+
classDecl, superclassTy);
20722074
NominalTypeDecl *superclassDecl = superclassTy->getAnyNominal();
20732075
if (superclassTyInCtor->getAnyNominal() != superclassDecl) {
20742076
return nullptr;
@@ -2093,7 +2095,7 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
20932095
if (superclassDecl->isGenericContext()) {
20942096
if (auto *superclassSig = superclassDecl->getGenericSignatureOfContext()) {
20952097
auto *moduleDecl = classDecl->getParentModule();
2096-
auto subs = superclassTy->gatherAllSubstitutions(
2098+
auto subs = superclassTyInContext->gatherAllSubstitutions(
20972099
moduleDecl, nullptr, nullptr);
20982100
auto subsMap = superclassSig->getSubstitutionMap(subs);
20992101

@@ -2103,13 +2105,14 @@ swift::createDesignatedInitOverride(TypeChecker &tc,
21032105
auto paramTy = ArchetypeBuilder::mapTypeOutOfContext(
21042106
superclassDecl, decl->getType());
21052107

2106-
// Apply the superclass substitutions to produce an interface
2107-
// type in terms of the class generic signature.
2108+
// Apply the superclass substitutions to produce a contextual
2109+
// type in terms of the derived class archetypes.
21082110
auto paramSubstTy = paramTy.subst(moduleDecl, subsMap, SubstOptions());
2109-
decl->setInterfaceType(paramSubstTy);
2111+
decl->overwriteType(paramSubstTy);
21102112

2111-
// Map it to a contextual type in terms of the class's archetypes.
2112-
decl->overwriteType(ArchetypeBuilder::mapTypeIntoContext(
2113+
// Map it to an interface type in terms of the derived class
2114+
// generic signature.
2115+
decl->setInterfaceType(ArchetypeBuilder::mapTypeOutOfContext(
21132116
classDecl, paramSubstTy));
21142117
}
21152118
}

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ static VarDecl *deriveRawRepresentable_raw(TypeChecker &tc,
141141
PatternBindingDecl *pbDecl;
142142
std::tie(propDecl, pbDecl)
143143
= declareDerivedReadOnlyProperty(tc, parentDecl, enumDecl,
144-
C.Id_rawValue, rawType,
144+
C.Id_rawValue,
145145
rawInterfaceType,
146+
rawType,
146147
getterDecl);
147148

148149
auto dc = cast<IterableDeclContext>(parentDecl);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,8 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
372372
continue;
373373

374374
// Retrieve the interface type for this inherited type.
375-
if (DC->isGenericContext() && DC->isTypeContext()) {
375+
if (inheritedTy->hasArchetype())
376376
inheritedTy = ArchetypeBuilder::mapTypeOutOfContext(DC, inheritedTy);
377-
}
378377

379378
// Check whether we inherited from the same type twice.
380379
CanType inheritedCanTy = inheritedTy->getCanonicalType();

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,7 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func) {
626626
initArgTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/true);
627627
}
628628
} else {
629-
argTy = paramLists[e - i - 1]->getType(Context);
630-
631-
// For an implicit declaration, our argument type will be in terms of
632-
// archetypes rather than dependent types. Replace the
633-
// archetypes with their corresponding dependent types.
634-
if (func->isImplicit()) {
635-
argTy = ArchetypeBuilder::mapTypeOutOfContext(func, argTy);
636-
}
629+
argTy = paramLists[e - i - 1]->getInterfaceType(func);
637630

638631
if (initFuncTy)
639632
initArgTy = argTy;
@@ -653,9 +646,12 @@ void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func) {
653646
}
654647

655648
// Record the interface type.
649+
assert(!funcTy->hasArchetype());
656650
func->setInterfaceType(funcTy);
657-
if (initFuncTy)
651+
if (initFuncTy) {
652+
assert(!initFuncTy->hasArchetype());
658653
cast<ConstructorDecl>(func)->setInitializerInterfaceType(initFuncTy);
654+
}
659655

660656
if (func->getGenericParams()) {
661657
// Collect all generic params referenced in parameter types,

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,17 +1889,6 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
18891889
TypeDecl *typeDecl,
18901890
DeclContext *fromDC,
18911891
bool performRedeclarationCheck) {
1892-
// If the declaration context from which the type witness was determined
1893-
// differs from that of the conformance, adjust the type so that it is
1894-
// based on the declaration context of the conformance.
1895-
if (fromDC != DC && DC->getGenericSignatureOfContext() &&
1896-
fromDC->getGenericSignatureOfContext() && !isa<ProtocolDecl>(fromDC)) {
1897-
// Map the type to an interface type.
1898-
type = ArchetypeBuilder::mapTypeOutOfContext(fromDC, type);
1899-
1900-
// Map the type into the conformance's context.
1901-
type = Adoptee->getTypeOfMember(DC->getParentModule(), type, fromDC);
1902-
}
19031892

19041893
// If we already recoded this type witness, there's nothing to do.
19051894
if (Conformance->hasTypeWitness(assocType)) {

test/decl/inherit/initializer.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,11 @@ class SuperVariadic {
142142

143143
class SubVariadic : SuperVariadic { } // expected-warning 4{{synthesizing a variadic inherited initializer for subclass 'SubVariadic' is unsupported}}
144144

145+
// Don't crash with invalid nesting of class in generic function
146+
147+
func testClassInGenericFunc<T>(t: T) {
148+
class A { init(t: T) {} } // expected-error {{type 'A' cannot be nested in generic function 'testClassInGenericFunc'}}
149+
class B : A {} // expected-error {{type 'B' cannot be nested in generic function 'testClassInGenericFunc'}}
150+
151+
_ = B(t: t)
152+
}

0 commit comments

Comments
 (0)