Skip to content

Commit ad12cc9

Browse files
authored
Merge pull request #17870 from slavapestov/fix-compiler-crashers
Fix compiler crashers
2 parents 4023105 + d4782b0 commit ad12cc9

25 files changed

+178
-118
lines changed

include/swift/AST/Types.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -767,9 +767,12 @@ class alignas(1 << TypeAlignInBits) TypeBase {
767767

768768
/// \brief Retrieve the superclass of this type.
769769
///
770+
/// \param useArchetypes Whether to use context archetypes for outer generic
771+
/// parameters if the class is nested inside a generic function.
772+
///
770773
/// \returns The superclass of this type, or a null type if it has no
771774
/// superclass.
772-
Type getSuperclass();
775+
Type getSuperclass(bool useArchetypes = true);
773776

774777
/// \brief True if this type is the exact superclass of another type.
775778
///
@@ -797,7 +800,11 @@ class alignas(1 << TypeAlignInBits) TypeBase {
797800
///
798801
/// Calling `C<String, NSObject>`->getSuperclassForDecl(`A`) will return
799802
/// `A<Int, NSObject>`.
800-
Type getSuperclassForDecl(const ClassDecl *classDecl);
803+
///
804+
/// \param useArchetypes Whether to use context archetypes for outer generic
805+
/// parameters if the class is nested inside a generic function.
806+
Type getSuperclassForDecl(const ClassDecl *classDecl,
807+
bool useArchetypes = true);
801808

802809
/// \brief Whether this type or its superclasses has some form of generic
803810
/// context.

lib/AST/ConformanceLookupTable.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
319319
return;
320320
llvm::SaveAndRestore<bool> visiting(VisitingSuperclass, true);
321321

322+
// Don't update our own lookup table if we inherit from ourselves.
323+
if (classDecl == superclassDecl)
324+
break;
325+
322326
// Resolve the conformances of the superclass.
323327
superclassDecl->prepareConformanceTable();
324328
superclassDecl->ConformanceTable->updateLookupTable(

lib/AST/LookupVisibleDecls.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -847,10 +847,6 @@ class OverrideFilteringConsumer : public VisibleDeclConsumer {
847847

848848
// Does it make sense to substitute types?
849849

850-
// Don't pass UnboundGenericType here. If you see this assertion
851-
// being hit, fix the caller, don't remove it.
852-
assert(IsTypeLookup || !BaseTy->hasUnboundGenericType());
853-
854850
// If the base type is AnyObject, we might be doing a dynamic
855851
// lookup, so the base type won't match the type of the member's
856852
// context type.

lib/AST/Type.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@ bool TypeBase::satisfiesClassConstraint() {
14611461
return mayHaveSuperclass() || isObjCExistentialType();
14621462
}
14631463

1464-
Type TypeBase::getSuperclass() {
1464+
Type TypeBase::getSuperclass(bool useArchetypes) {
14651465
auto *nominalDecl = getAnyNominal();
14661466
auto *classDecl = dyn_cast_or_null<ClassDecl>(nominalDecl);
14671467

@@ -1496,7 +1496,9 @@ Type TypeBase::getSuperclass() {
14961496
ModuleDecl *module = classDecl->getModuleContext();
14971497
auto subMap = getContextSubstitutionMap(module,
14981498
classDecl,
1499-
classDecl->getGenericEnvironment());
1499+
(useArchetypes
1500+
? classDecl->getGenericEnvironment()
1501+
: nullptr));
15001502
return superclassTy.subst(subMap);
15011503
}
15021504

@@ -3220,7 +3222,8 @@ static Type getConcreteTypeForSuperclassTraversing(Type t) {
32203222
return t;
32213223
}
32223224

3223-
Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass) {
3225+
Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass,
3226+
bool useArchetypes) {
32243227
Type t = getConcreteTypeForSuperclassTraversing(this);
32253228

32263229
while (t) {
@@ -3233,7 +3236,7 @@ Type TypeBase::getSuperclassForDecl(const ClassDecl *baseClass) {
32333236
if (nominalDecl == baseClass)
32343237
return t;
32353238

3236-
t = t->getSuperclass();
3239+
t = t->getSuperclass(useArchetypes);
32373240
}
32383241
llvm_unreachable("no inheritance relationship between given classes");
32393242
}

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5484,9 +5484,11 @@ Expr *ExprRewriter::coerceExistential(Expr *expr, Type toType,
54845484
Type toInstanceType = toType;
54855485

54865486
// Look through metatypes
5487-
while (fromInstanceType->is<AnyMetatypeType>() &&
5487+
while ((fromInstanceType->is<UnresolvedType>() ||
5488+
fromInstanceType->is<AnyMetatypeType>()) &&
54885489
toInstanceType->is<ExistentialMetatypeType>()) {
5489-
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
5490+
if (!fromInstanceType->is<UnresolvedType>())
5491+
fromInstanceType = fromInstanceType->castTo<AnyMetatypeType>()->getInstanceType();
54905492
toInstanceType = toInstanceType->castTo<ExistentialMetatypeType>()->getInstanceType();
54915493
}
54925494

lib/Sema/ConstraintSystem.cpp

Lines changed: 31 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,31 +1053,6 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
10531053
return { valueType, valueType };
10541054
}
10551055

1056-
static Type getInnermostConformingType(TypeChecker &TC, DeclContext *DC,
1057-
ProtocolDecl *protocol) {
1058-
do {
1059-
if (DC->isTypeContext()) {
1060-
if (protocol == DC->getAsProtocolOrProtocolExtensionContext())
1061-
return DC->mapTypeIntoContext(DC->getProtocolSelfType());
1062-
1063-
auto *NTD = DC->getAsNominalTypeOrNominalTypeExtensionContext();
1064-
auto type = NTD->getDeclaredType();
1065-
1066-
ConformanceCheckOptions options;
1067-
options |= ConformanceCheckFlags::InExpression;
1068-
options |= ConformanceCheckFlags::SuppressDependencyTracking;
1069-
options |= ConformanceCheckFlags::SkipConditionalRequirements;
1070-
1071-
auto result =
1072-
TC.conformsToProtocol(type, protocol, NTD->getDeclContext(), options);
1073-
1074-
if (result)
1075-
return DC->getDeclaredTypeInContext();
1076-
}
1077-
} while ((DC = DC->getParent()));
1078-
1079-
return nullptr;
1080-
}
10811056
/// Bind type variables for archetypes that are determined from
10821057
/// context.
10831058
///
@@ -1093,10 +1068,10 @@ static Type getInnermostConformingType(TypeChecker &TC, DeclContext *DC,
10931068
///
10941069
/// A final case we have to handle, even though it is invalid, is
10951070
/// when a type is nested inside another protocol. We bind the
1096-
/// protocol type variable for the protocol Self to its archetype
1097-
/// in protocol context. This of course makes no sense, but we
1098-
/// can't leave the type variable dangling, because then we crash
1099-
/// later.
1071+
/// protocol type variable for the protocol Self to an unresolved
1072+
/// type, since it will conform to anything. This of course makes
1073+
/// no sense, but we can't leave the type variable dangling,
1074+
/// because then we crash later.
11001075
///
11011076
/// If we ever do want to allow nominal types to be nested inside
11021077
/// protocols, the key is to set their declared type to a
@@ -1117,43 +1092,43 @@ static void bindArchetypesFromContext(
11171092

11181093
auto *genericEnv = cs.DC->getGenericEnvironmentOfContext();
11191094

1095+
auto bindContextArchetype = [&](Type paramTy, Type contextTy) {
1096+
auto found = replacements.find(cast<GenericTypeParamType>(
1097+
paramTy->getCanonicalType()));
1098+
1099+
// We might not have a type variable for this generic parameter
1100+
// because either we're opening up an UnboundGenericType,
1101+
// in which case we only want to infer the innermost generic
1102+
// parameters, or because this generic parameter was constrained
1103+
// away into a concrete type.
1104+
if (found != replacements.end()) {
1105+
auto typeVar = found->second;
1106+
cs.addConstraint(ConstraintKind::Bind, typeVar, contextTy,
1107+
locatorPtr);
1108+
}
1109+
};
1110+
1111+
// Find the innermost non-type context.
11201112
for (const auto *parentDC = outerDC;
11211113
!parentDC->isModuleScopeContext();
11221114
parentDC = parentDC->getParent()) {
1123-
if (parentDC->isTypeContext() &&
1124-
(parentDC == outerDC ||
1125-
!parentDC->getAsProtocolOrProtocolExtensionContext()))
1115+
if (parentDC->isTypeContext()) {
1116+
if (parentDC != outerDC && parentDC->getAsProtocolOrProtocolExtensionContext()) {
1117+
auto selfTy = parentDC->getSelfInterfaceType();
1118+
auto contextTy = cs.TC.Context.TheUnresolvedType;
1119+
bindContextArchetype(selfTy, contextTy);
1120+
}
11261121
continue;
1122+
}
11271123

1124+
// If it's not generic, there's nothing to do.
11281125
auto *genericSig = parentDC->getGenericSignatureOfContext();
11291126
if (!genericSig)
11301127
break;
11311128

11321129
for (auto *paramTy : genericSig->getGenericParams()) {
1133-
auto found = replacements.find(cast<GenericTypeParamType>(
1134-
paramTy->getCanonicalType()));
1135-
1136-
// We might not have a type variable for this generic parameter
1137-
// because either we're opening up an UnboundGenericType,
1138-
// in which case we only want to infer the innermost generic
1139-
// parameters, or because this generic parameter was constrained
1140-
// away into a concrete type.
1141-
if (found != replacements.end()) {
1142-
Type contextTy;
1143-
1144-
if (genericEnv) {
1145-
contextTy = genericEnv->mapTypeIntoContext(paramTy);
1146-
} else {
1147-
auto *protocol = parentDC->getAsProtocolOrProtocolExtensionContext();
1148-
contextTy = getInnermostConformingType(cs.TC, cs.DC, protocol);
1149-
}
1150-
1151-
assert(contextTy);
1152-
1153-
auto typeVar = found->second;
1154-
cs.addConstraint(ConstraintKind::Bind, typeVar, contextTy,
1155-
locatorPtr);
1156-
}
1130+
Type contextTy = genericEnv->mapTypeIntoContext(paramTy);
1131+
bindContextArchetype(paramTy, contextTy);
11571132
}
11581133

11591134
break;

lib/Sema/GenericTypeResolver.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class GenericTypeResolver {
3636
public:
3737
virtual ~GenericTypeResolver();
3838

39+
virtual bool usesArchetypes() = 0;
40+
3941
/// Resolve the given interface type to a contextual type if necessary.
4042
virtual Type mapTypeIntoContext(Type type) = 0;
4143

@@ -66,6 +68,8 @@ class GenericTypeResolver {
6668
/// and only trivially resolves dependent member types.
6769
class DependentGenericTypeResolver : public GenericTypeResolver {
6870
public:
71+
virtual bool usesArchetypes() { return false; }
72+
6973
virtual Type mapTypeIntoContext(Type type);
7074

7175
virtual Type resolveDependentMemberType(Type baseTy,
@@ -93,6 +97,8 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
9397
explicit GenericTypeToArchetypeResolver(DeclContext *dc)
9498
: GenericEnv(dc->getGenericEnvironmentOfContext()) { }
9599

100+
virtual bool usesArchetypes() { return true; }
101+
96102
virtual Type mapTypeIntoContext(Type type);
97103

98104
virtual Type resolveDependentMemberType(Type baseTy, DeclContext *DC,
@@ -111,6 +117,8 @@ class GenericTypeToArchetypeResolver : public GenericTypeResolver {
111117
/// protocols.
112118
class ProtocolRequirementTypeResolver : public GenericTypeResolver {
113119
public:
120+
virtual bool usesArchetypes() { return false; }
121+
114122
virtual Type mapTypeIntoContext(Type type);
115123

116124
virtual Type resolveDependentMemberType(Type baseTy, DeclContext *DC,
@@ -137,6 +145,8 @@ class CompleteGenericTypeResolver : public GenericTypeResolver {
137145
public:
138146
CompleteGenericTypeResolver(TypeChecker &tc, GenericSignature *genericSig);
139147

148+
virtual bool usesArchetypes() { return false; }
149+
140150
virtual Type mapTypeIntoContext(Type type);
141151

142152
virtual Type resolveDependentMemberType(Type baseTy,

lib/Sema/TypeCheckDecl.cpp

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -603,23 +603,6 @@ static ArrayRef<EnumDecl *> getInheritedForCycleCheck(TypeChecker &tc,
603603
return { };
604604
}
605605

606-
// Break the inheritance cycle for a protocol by removing all inherited
607-
// protocols.
608-
//
609-
// FIXME: Just remove the problematic inheritance?
610-
static void breakInheritanceCycle(ProtocolDecl *proto) {
611-
}
612-
613-
/// Break the inheritance cycle for a class by removing its superclass.
614-
static void breakInheritanceCycle(ClassDecl *classDecl) {
615-
classDecl->setSuperclass(Type());
616-
}
617-
618-
/// Break the inheritance cycle for an enum by removing its raw type.
619-
static void breakInheritanceCycle(EnumDecl *enumDecl) {
620-
enumDecl->setRawType(Type());
621-
}
622-
623606
/// Check for circular inheritance.
624607
template<typename T>
625608
static void checkCircularity(TypeChecker &tc, T *decl,
@@ -649,9 +632,6 @@ static void checkCircularity(TypeChecker &tc, T *decl,
649632
circularDiag,
650633
path.back()->getName());
651634

652-
decl->setInvalid();
653-
decl->setInterfaceType(ErrorType::get(tc.Context));
654-
breakInheritanceCycle(decl);
655635
break;
656636
}
657637

@@ -663,10 +643,6 @@ static void checkCircularity(TypeChecker &tc, T *decl,
663643
declKind, (*i)->getName());
664644
}
665645

666-
// Set this declaration as invalid, then break the cycle somehow.
667-
decl->setInvalid();
668-
decl->setInterfaceType(ErrorType::get(tc.Context));
669-
breakInheritanceCycle(decl);
670646
break;
671647
}
672648

@@ -3374,6 +3350,7 @@ static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
33743350
// of typealias underlying type e.g. `typealias F = () -> Int#^TOK^#`
33753351
auto underlyingType = typeAlias->getUnderlyingTypeLoc();
33763352
if (underlyingType.isNull()) {
3353+
typeAlias->getUnderlyingTypeLoc().setInvalidType(tc.Context);
33773354
typeAlias->setInterfaceType(ErrorType::get(tc.Context));
33783355
typeAlias->setInvalid();
33793356
return;
@@ -3723,6 +3700,13 @@ void TypeChecker::validateDecl(ValueDecl *D) {
37233700
return;
37243701
}
37253702

3703+
// Validating the parent may have triggered validation of this declaration,
3704+
// so just return if that was the case.
3705+
if (D->hasValidationStarted()) {
3706+
assert(D->hasValidSignature());
3707+
return;
3708+
}
3709+
37263710
if (Context.Stats)
37273711
Context.Stats->getFrontendCounters().NumDeclsValidated++;
37283712

@@ -4743,8 +4727,14 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
47434727
if (!typealias->getGenericParams()) {
47444728
if (typealias->isBeingValidated()) return;
47454729

4746-
typealias->setIsBeingValidated();
4747-
SWIFT_DEFER { typealias->setIsBeingValidated(false); };
4730+
bool validated = typealias->hasValidationStarted();
4731+
4732+
if (!validated)
4733+
typealias->setIsBeingValidated();
4734+
SWIFT_DEFER {
4735+
if (!validated)
4736+
typealias->setIsBeingValidated(false);
4737+
};
47484738

47494739
(void) typealias->getFormalAccess();
47504740

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,10 @@ static bool diagnoseOverrideForAvailability(ValueDecl *override,
13451345

13461346
static bool recordOverride(TypeChecker &TC, ValueDecl *override,
13471347
ValueDecl *base, bool isKnownObjC) {
1348+
// This can happen with circular inheritance.
1349+
if (override == base)
1350+
return true;
1351+
13481352
ASTContext &ctx = override->getASTContext();
13491353
auto &diags = ctx.Diags;
13501354

0 commit comments

Comments
 (0)