Sema: Fix crashes in CSDiag

- TypeMatchVisitor doesn't like seeing ErrorTypes -- stop if we have one.

- Common logic for replacing type parameters and variables with
  UnresolvedType.

- Fix crash in coerceToType() if one of the two types has an UnresolvedType
  in it, but not at the top level.

Fixes one compiler_crasher and some regressions with upcoming patches.
This commit is contained in:
Slava Pestov
2016-12-25 18:42:20 -05:00
parent 6c9f99fd1d
commit 584f47d025
3 changed files with 52 additions and 31 deletions

View File

@@ -1219,6 +1219,9 @@ static bool findGenericSubstitutions(DeclContext *dc, Type paramType,
}
};
if (paramType->hasError())
return false;
GenericVisitor visitor(dc, archetypesMap);
return visitor.match(paramType, actualArgType);
}
@@ -1474,6 +1477,38 @@ CalleeCandidateInfo::evaluateCloseness(UncurriedCandidate candidate,
return { closeness, {}};
}
/// Rewrite any type parameters in the specified type with UnresolvedType.
static Type replaceTypeParametersWithUnresolved(Type ty) {
if (!ty) return ty;
if (!ty->hasTypeParameter() && !ty->hasArchetype()) return ty;
auto &ctx = ty->getASTContext();
return ty.transform([&](Type type) -> Type {
if (type->is<ArchetypeType>() ||
type->isTypeParameter())
return ctx.TheUnresolvedType;
return type;
});
}
/// Rewrite any type variables & archetypes in the specified type with
/// UnresolvedType.
static Type replaceTypeVariablesWithUnresolved(Type ty) {
if (!ty) return ty;
if (!ty->hasTypeVariable()) return ty;
auto &ctx = ty->getASTContext();
return ty.transform([&](Type type) -> Type {
if (type->isTypeVariableOrMember())
return ctx.TheUnresolvedType;
return type;
});
}
void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
bool implicitDotSyntax) {
fn = fn->getValueProvidingExpr();
@@ -1552,21 +1587,23 @@ void CalleeCandidateInfo::collectCalleeCandidates(Expr *fn,
collectCalleeCandidates(AE->getFn(),
/*implicitDotSyntax=*/AE->getMemberOperatorRef());
// If this is a DotSyntaxCallExpr, then the callee is a method, and the
// argument list of this apply is the base being applied to the method.
// If we have a type for that, capture it so that we can calculate a
// substituted type, which resolves many generic arguments.
Type baseType;
if (isa<SelfApplyExpr>(AE) &&
!isUnresolvedOrTypeVarType(AE->getArg()->getType()))
baseType = AE->getArg()->getType()->getLValueOrInOutObjectType();
// If we found a candidate list with a recursive walk, try adjust the curry
// level for the applied subexpression in this call.
if (!candidates.empty()) {
// If this is a DotSyntaxCallExpr, then the callee is a method, and the
// argument list of this apply is the base being applied to the method.
// If we have a type for that, capture it so that we can calculate a
// substituted type, which resolves many generic arguments.
Type baseType;
if (isa<SelfApplyExpr>(AE) &&
!isUnresolvedOrTypeVarType(AE->getArg()->getType()))
baseType = AE->getArg()->getType()->getLValueOrInOutObjectType();
for (auto &C : candidates) {
C.level += 1;
baseType = replaceTypeVariablesWithUnresolved(baseType);
// Compute a new substituted type if we have a base type to apply.
if (baseType && C.level == 1 && C.getDecl()) {
C.entityType = baseType->getTypeOfMember(CS->DC->getParentModule(),
@@ -1755,7 +1792,8 @@ CalleeCandidateInfo::CalleeCandidateInfo(Type baseType,
// it to get a simpler and more concrete type.
//
if (baseType) {
auto substType = baseType;
auto substType = replaceTypeVariablesWithUnresolved(baseType);
// If this is a DeclViaUnwrappingOptional, then we're actually looking
// through an optional to get the member, and baseType is an Optional or
// Metatype<Optional>.
@@ -3366,22 +3404,6 @@ static void eraseOpenedExistentials(Expr *&expr) {
expr = expr->walk(ExistentialEraser());
}
/// Rewrite any type variables & archetypes in the specified type with
/// UnresolvedType.
static Type replaceArchetypesAndTypeVarsWithUnresolved(Type ty) {
if (!ty) return ty;
auto &ctx = ty->getASTContext();
return ty.transform([&](Type type) -> Type {
if (type->isTypeVariableOrMember() ||
type->is<ArchetypeType>() ||
type->isTypeParameter())
return ctx.TheUnresolvedType;
return type;
});
}
/// Unless we've already done this, retypecheck the specified subexpression on
/// its own, without including any contextual constraints or parent expr
/// nodes. This is more likely to succeed than type checking the original
@@ -3414,9 +3436,8 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
convertType = FT->getResult();
// Replace archetypes and type parameters with UnresolvedType.
if (convertType->hasTypeVariable() || convertType->hasArchetype() ||
convertType->hasTypeParameter())
convertType = replaceArchetypesAndTypeVarsWithUnresolved(convertType);
convertType = replaceTypeParametersWithUnresolved(convertType);
convertType = replaceTypeVariablesWithUnresolved(convertType);
// If the conversion type contains no info, drop it.
if (convertType->is<UnresolvedType>() ||