diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index a87eb36f4ffc1..28a607d344db5 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3576,12 +3576,35 @@ void LocatableType::Profile(llvm::FoldingSetNodeID &id, SourceLoc loc, // Simple accessors. Type ErrorType::get(const ASTContext &C) { return C.TheErrorType; } +static Type replacingTypeVariablesAndPlaceholders(Type ty) { + if (!ty || !ty->hasTypeVariableOrPlaceholder()) + return ty; + + auto &ctx = ty->getASTContext(); + + return ty.transformRec([&](Type ty) -> std::optional { + if (!ty->hasTypeVariableOrPlaceholder()) + return ty; + + // Match the logic in `Solution::simplifyType` and use UnresolvedType. + // FIXME: Ideally we'd get rid of UnresolvedType and just use a fresh + // PlaceholderType, but we don't currently support placeholders with no + // originators. + auto *typePtr = ty.getPointer(); + if (isa(typePtr) || isa(typePtr)) + return ctx.TheUnresolvedType; + + return std::nullopt; + }); +} + Type ErrorType::get(Type originalType) { + // The original type is only used for printing/debugging, and we don't support + // solver-allocated ErrorTypes. As such, fold any type variables and + // placeholders into UnresolvedTypes, which print as placeholders. + originalType = replacingTypeVariablesAndPlaceholders(originalType); + ASSERT(originalType); - // We don't currently support solver-allocated error types, if we want - // this in the future we'll need to adjust `Solution::simplifyType` to fold - // them into regular ErrorTypes. Additionally, any clients of - // `typesSatisfyConstraint` will need to be taught not to pass such types. ASSERT(!originalType->getRecursiveProperties().isSolverAllocated() && "Solver-allocated error types not supported"); diff --git a/lib/AST/TypeSubstitution.cpp b/lib/AST/TypeSubstitution.cpp index 403801d5e878f..11bf4c8537c03 100644 --- a/lib/AST/TypeSubstitution.cpp +++ b/lib/AST/TypeSubstitution.cpp @@ -446,13 +446,8 @@ Type TypeSubstituter::transformDependentMemberType(DependentMemberType *dependen auto result = conformance.getTypeWitness(assocType, IFS.getOptions()); if (result->is()) { - // Substitute the base type for the original ErrorType for type printing. - // Avoid doing this if the substitutions introduce type variables or - // placeholders since ErrorTypes can't be solver-allocated currently (and - // type variables aren't helpful when printing anyway). auto substBase = origBase.subst(IFS); - if (!substBase->hasTypeVariableOrPlaceholder()) - return DependentMemberType::get(ErrorType::get(substBase), assocType); + return DependentMemberType::get(ErrorType::get(substBase), assocType); } return result; } diff --git a/validation-test/compiler_crashers_2/cccd6394993ea4a2.swift b/validation-test/compiler_crashers_2_fixed/cccd6394993ea4a2.swift similarity index 57% rename from validation-test/compiler_crashers_2/cccd6394993ea4a2.swift rename to validation-test/compiler_crashers_2_fixed/cccd6394993ea4a2.swift index 45e16469a28b4..8e5de4b4d3764 100644 --- a/validation-test/compiler_crashers_2/cccd6394993ea4a2.swift +++ b/validation-test/compiler_crashers_2_fixed/cccd6394993ea4a2.swift @@ -1,3 +1,3 @@ // {"signature":"swift::ErrorType::get(swift::Type)"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s @convention(c) _->Int