Skip to content

Commit 0c58138

Browse files
committed
[Sema] Avoid using UnresolvedType in PatternTypeRequest
Return PlaceholderType instead of UnresolvedType, meaning we now treat the following cases the same: ``` let x1 = foo let x2: _ = foo ```
1 parent 1c4132f commit 0c58138

File tree

8 files changed

+17
-13
lines changed

8 files changed

+17
-13
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/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/SyntacticElementTarget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ SyntacticElementTarget::forInitialization(Expr *initializer, DeclContext *dc,
141141
// Determine the contextual type for the initialization.
142142
TypeLoc contextualType;
143143
if (!(isa<OptionalSomePattern>(pattern) && !pattern->isImplicit()) &&
144-
patternType && !patternType->is<UnresolvedType>()) {
144+
patternType && !patternType->is<PlaceholderType>()) {
145145
contextualType = TypeLoc::withoutLoc(patternType);
146146

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

lib/Sema/TypeCheckPattern.cpp

Lines changed: 2 additions & 2 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
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,7 @@ const PatternBindingEntry *PatternBindingEntryRequest::evaluate(
516516

517517
// If the pattern contains some form of unresolved type, we'll need to
518518
// check the initializer.
519-
if (patternType->hasUnresolvedType() ||
520-
patternType->hasPlaceholder() ||
521-
patternType->hasUnboundGenericType()) {
519+
if (patternType->hasPlaceholder() || patternType->hasUnboundGenericType()) {
522520
if (TypeChecker::typeCheckPatternBinding(binding, entryNumber,
523521
patternType)) {
524522
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

test/Sema/placeholder_type.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ let arr = [_](repeating: "hi", count: 3)
1313
func foo(_ arr: [_] = [0]) {} // expected-error {{type placeholder not allowed here}}
1414

1515
let foo = _.foo // expected-error {{type placeholder not allowed here}}
16-
let zero: _ = .zero // expected-error {{cannot infer contextual base in reference to member 'zero'}}
16+
let zero: _ = .zero // expected-error {{reference to member 'zero' cannot be resolved without a contextual type}}
1717

1818
struct S<T> {
1919
var x: T

0 commit comments

Comments
 (0)