Skip to content

Commit 8975d1a

Browse files
authored
Merge pull request swiftlang#84556 from hamishknight/unresolve
[Sema] Remove a couple uses of UnresolvedType
2 parents e0a703b + fb5e356 commit 8975d1a

File tree

13 files changed

+38
-80
lines changed

13 files changed

+38
-80
lines changed

include/swift/AST/Types.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7759,16 +7759,16 @@ class ErrorUnionType final
77597759
};
77607760
DEFINE_EMPTY_CAN_TYPE_WRAPPER(ErrorUnionType, Type)
77617761

7762-
/// PlaceholderType - This represents a placeholder type for a type variable
7763-
/// or dependent member type that cannot be resolved to a concrete type
7764-
/// because the expression is ambiguous. This type is only used by the
7765-
/// constraint solver and transformed into UnresolvedType to be used in AST.
7762+
/// PlaceholderType - In the AST, this represents the type of a placeholder `_`.
7763+
/// In the constraint system, this is opened into a type variable, and uses of
7764+
/// PlaceholderType are instead used to represent holes where types cannot be
7765+
/// inferred.
77667766
class PlaceholderType : public TypeBase {
77677767
// NOTE: If you add a new Type-based originator, you'll need to update the
77687768
// recursive property logic in PlaceholderType::get.
77697769
using Originator =
77707770
llvm::PointerUnion<TypeVariableType *, DependentMemberType *, ErrorType *,
7771-
VarDecl *, ErrorExpr *, TypeRepr *>;
7771+
VarDecl *, ErrorExpr *, TypeRepr *, Pattern *>;
77727772

77737773
Originator O;
77747774

lib/AST/ASTContext.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,13 +3605,9 @@ static Type replacingTypeVariablesAndPlaceholders(Type ty) {
36053605
if (!ty->hasTypeVariableOrPlaceholder())
36063606
return ty;
36073607

3608-
// Match the logic in `Solution::simplifyType` and use UnresolvedType.
3609-
// FIXME: Ideally we'd get rid of UnresolvedType and just use a fresh
3610-
// PlaceholderType, but we don't currently support placeholders with no
3611-
// originators.
36123608
auto *typePtr = ty.getPointer();
36133609
if (isa<TypeVariableType>(typePtr) || isa<PlaceholderType>(typePtr))
3614-
return ctx.TheUnresolvedType;
3610+
return ErrorType::get(ctx);
36153611

36163612
return std::nullopt;
36173613
});
@@ -3620,7 +3616,14 @@ static Type replacingTypeVariablesAndPlaceholders(Type ty) {
36203616
Type ErrorType::get(Type originalType) {
36213617
// The original type is only used for printing/debugging, and we don't support
36223618
// solver-allocated ErrorTypes. As such, fold any type variables and
3623-
// placeholders into UnresolvedTypes, which print as placeholders.
3619+
// placeholders into bare ErrorTypes, which print as placeholders.
3620+
//
3621+
// FIXME: If the originalType is itself an ErrorType we ought to be flattening
3622+
// it, but that's currently load-bearing as it avoids crashing for recursive
3623+
// generic signatures such as in `0120-rdar34184392.swift`. To fix this we
3624+
// ought to change the evaluator to ensure the outer step of a request cycle
3625+
// returns the same default value as the inner step such that we don't end up
3626+
// with conflicting generic signatures on encountering a cycle.
36243627
originalType = replacingTypeVariablesAndPlaceholders(originalType);
36253628

36263629
ASSERT(originalType);

lib/AST/ASTDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6078,6 +6078,8 @@ namespace {
60786078
printRec(DMT, Label::always("dependent_member_type"));
60796079
} else if (isa<TypeRepr *>(originator)) {
60806080
printFlag("type_repr");
6081+
} else if (isa<Pattern *>(originator)) {
6082+
printFlag("pattern");
60816083
} else {
60826084
assert(false && "unknown originator");
60836085
}

lib/AST/ASTPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6235,6 +6235,8 @@ class TypePrinter : public TypeVisitor<TypePrinter, void, NonRecursivePrintOptio
62356235
visit(DMT);
62366236
} else if (isa<TypeRepr *>(originator)) {
62376237
Printer << "type_repr";
6238+
} else if (isa<Pattern *>(originator)) {
6239+
Printer << "pattern";
62386240
} else {
62396241
assert(false && "unknown originator");
62406242
}

lib/Sema/CSGen.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4823,12 +4823,6 @@ generateForEachPreambleConstraints(ConstraintSystem &cs,
48234823
return std::nullopt;
48244824
target.setPattern(pattern);
48254825

4826-
auto contextualPattern = ContextualPattern::forRawPattern(pattern, dc);
4827-
4828-
if (TypeChecker::typeCheckPattern(contextualPattern)->hasError()) {
4829-
return std::nullopt;
4830-
}
4831-
48324826
if (isa<PackExpansionExpr>(forEachExpr)) {
48334827
auto *expansion = cast<PackExpansionExpr>(forEachExpr);
48344828

@@ -4996,10 +4990,6 @@ bool ConstraintSystem::generateConstraints(
49964990
ContextualPattern::forPatternBindingDecl(patternBinding, index);
49974991
Type patternType = TypeChecker::typeCheckPattern(contextualPattern);
49984992

4999-
// Fail early if pattern couldn't be type-checked.
5000-
if (!patternType || patternType->hasError())
5001-
return true;
5002-
50034993
auto *init = patternBinding->getInit(index);
50044994

50054995
if (!init && patternBinding->isDefaultInitializable(index) &&

lib/Sema/SyntacticElementTarget.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,6 @@ SyntacticElementTarget::SyntacticElementTarget(
3636
assert((!contextualInfo.getType() || contextualPurpose != CTP_Unused) &&
3737
"Purpose for conversion type was not specified");
3838

39-
// Take a look at the conversion type to check to make sure it is sensible.
40-
if (auto type = contextualInfo.getType()) {
41-
// If we're asked to convert to an UnresolvedType, then ignore the request.
42-
// This happens when CSDiags nukes a type.
43-
if (type->is<UnresolvedType>() ||
44-
(type->is<MetatypeType>() && type->hasUnresolvedType())) {
45-
contextualInfo.typeLoc = TypeLoc();
46-
contextualPurpose = CTP_Unused;
47-
}
48-
}
49-
5039
kind = Kind::expression;
5140
expression.expression = expr;
5241
expression.dc = dc;
@@ -141,7 +130,7 @@ SyntacticElementTarget::forInitialization(Expr *initializer, DeclContext *dc,
141130
// Determine the contextual type for the initialization.
142131
TypeLoc contextualType;
143132
if (!(isa<OptionalSomePattern>(pattern) && !pattern->isImplicit()) &&
144-
patternType && !patternType->is<UnresolvedType>()) {
133+
patternType && !patternType->is<PlaceholderType>()) {
145134
contextualType = TypeLoc::withoutLoc(patternType);
146135

147136
// Only provide a TypeLoc if it makes sense to allow diagnostics.

lib/Sema/TypeCheckPattern.cpp

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
866866
// If we're type checking this pattern in a context that can provide type
867867
// information, then the lack of type information is not an error.
868868
if (options & TypeResolutionFlags::AllowUnspecifiedTypes)
869-
return Context.TheUnresolvedType;
869+
return PlaceholderType::get(Context, P);
870870

871871
Context.Diags.diagnose(P->getLoc(), diag::cannot_infer_type_for_pattern);
872872
if (auto named = dyn_cast<NamedPattern>(P)) {
@@ -946,7 +946,7 @@ Type PatternTypeRequest::evaluate(Evaluator &evaluator,
946946
return ErrorType::get(Context);
947947
}
948948

949-
return Context.TheUnresolvedType;
949+
return PlaceholderType::get(Context, P);
950950
}
951951
llvm_unreachable("bad pattern kind!");
952952
}
@@ -1736,41 +1736,18 @@ Pattern *TypeChecker::coercePatternToType(
17361736
/// contextual type.
17371737
void TypeChecker::coerceParameterListToType(ParameterList *P,
17381738
AnyFunctionType *FN) {
1739-
1740-
// Local function to check if the given type is valid e.g. doesn't have
1741-
// errors, type variables or unresolved types related to it.
1742-
auto isValidType = [](Type type) -> bool {
1743-
return !(type->hasError() || type->hasUnresolvedType());
1744-
};
1745-
1746-
// Local function to check whether type of given parameter
1747-
// should be coerced to a given contextual type or not.
1748-
auto shouldOverwriteParam = [&](ParamDecl *param) -> bool {
1749-
return !isValidType(param->getTypeInContext());
1750-
};
1751-
1752-
auto handleParameter = [&](ParamDecl *param, Type ty, bool forceMutable) {
1753-
if (forceMutable)
1754-
param->setSpecifier(ParamDecl::Specifier::InOut);
1755-
1756-
// If contextual type is invalid and we have a valid argument type
1757-
// trying to coerce argument to contextual type would mean erasing
1758-
// valuable diagnostic information.
1759-
if (isValidType(ty) || shouldOverwriteParam(param)) {
1760-
param->setInterfaceType(ty->mapTypeOutOfContext());
1761-
}
1762-
};
1763-
17641739
// Coerce each parameter to the respective type.
17651740
ArrayRef<AnyFunctionType::Param> params = FN->getParams();
17661741
for (unsigned i = 0, e = P->size(); i != e; ++i) {
17671742
auto &param = P->get(i);
17681743
assert(param->getArgumentName().empty() &&
17691744
"Closures cannot have API names");
1770-
1771-
handleParameter(param,
1772-
params[i].getParameterType(),
1773-
params[i].isInOut());
17741745
assert(!param->isDefaultArgument() && "Closures cannot have default args");
1746+
1747+
if (params[i].isInOut())
1748+
param->setSpecifier(ParamDecl::Specifier::InOut);
1749+
1750+
param->setInterfaceType(
1751+
params[i].getParameterType()->mapTypeOutOfContext());
17751752
}
17761753
}

lib/Sema/TypeCheckStmt.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -905,10 +905,6 @@ typeCheckPatternBindingStmtConditionElement(StmtConditionElement &elt,
905905
// provide type information.
906906
auto contextualPattern = ContextualPattern::forRawPattern(pattern, dc);
907907
Type patternType = TypeChecker::typeCheckPattern(contextualPattern);
908-
if (patternType->hasError()) {
909-
typeCheckPatternFailed();
910-
return true;
911-
}
912908

913909
// If the pattern didn't get a type, it's because we ran into some
914910
// unknown types along the way. We'll need to check the initializer.

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -451,12 +451,6 @@ const PatternBindingEntry *PatternBindingEntryRequest::evaluate(
451451
auto contextualPattern =
452452
ContextualPattern::forPatternBindingDecl(binding, entryNumber);
453453
Type patternType = TypeChecker::typeCheckPattern(contextualPattern);
454-
if (patternType->hasError()) {
455-
swift::setBoundVarsTypeError(pattern, Context);
456-
binding->setInvalid();
457-
pattern->setType(ErrorType::get(Context));
458-
return &pbe;
459-
}
460454

461455
llvm::SmallVector<VarDecl *, 2> vars;
462456
binding->getPattern(entryNumber)->collectVariables(vars);
@@ -516,9 +510,7 @@ const PatternBindingEntry *PatternBindingEntryRequest::evaluate(
516510

517511
// If the pattern contains some form of unresolved type, we'll need to
518512
// check the initializer.
519-
if (patternType->hasUnresolvedType() ||
520-
patternType->hasPlaceholder() ||
521-
patternType->hasUnboundGenericType()) {
513+
if (patternType->hasPlaceholder() || patternType->hasUnboundGenericType()) {
522514
if (TypeChecker::typeCheckPatternBinding(binding, entryNumber,
523515
patternType)) {
524516
binding->setInvalid();

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,8 +753,10 @@ Pattern *resolvePattern(Pattern *P, DeclContext *dc, bool isStmtCondition);
753753
///
754754
/// \returns the type of the pattern, which may be an error type if an
755755
/// unrecoverable error occurred. If the options permit it, the type may
756-
/// involve \c UnresolvedType (for patterns with no type information) and
756+
/// involve \c PlaceholderType (for patterns with no type information) and
757757
/// unbound generic types.
758+
/// TODO: We ought to expose hooks that let callers open the
759+
/// PlaceholderTypes directly, similar to type resolution.
758760
Type typeCheckPattern(ContextualPattern pattern);
759761

760762
/// Attempt to simplify an ExprPattern into a BoolPattern or

0 commit comments

Comments
 (0)