Skip to content

Commit 2a13b1d

Browse files
committed
[Type checker] Stop coercing patterns while type-checking them.
Detangle the "type check" and "coerce" phases somewhat for pattern type checking, as a precursor to making the former more functional.
1 parent 7fa84b5 commit 2a13b1d

File tree

4 files changed

+11
-18
lines changed

4 files changed

+11
-18
lines changed

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3045,7 +3045,6 @@ bool TypeChecker::typeCheckForEachBinding(DeclContext *dc, ForEachStmt *stmt) {
30453045
InitType, options)) {
30463046
return nullptr;
30473047
}
3048-
30493048
Stmt->setPattern(pattern);
30503049

30513050
// Get the conformance of the sequence type to the Sequence protocol.

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -741,23 +741,7 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
741741
case PatternKind::Typed: {
742742
auto resolution = TypeResolution::forContextual(dc);
743743
TypedPattern *TP = cast<TypedPattern>(P);
744-
bool hadError = validateTypedPattern(resolution, TP, options);
745-
746-
// If we have unbound generic types, don't apply them below; instead,
747-
// the caller will call typeCheckBinding() later.
748-
if (P->getType()->hasUnboundGenericType())
749-
return hadError;
750-
751-
Pattern *subPattern = TP->getSubPattern();
752-
if (TypeChecker::coercePatternToType(subPattern, resolution, P->getType(),
753-
options|TypeResolutionFlags::FromNonInferredPattern,
754-
TP->getTypeLoc()))
755-
hadError = true;
756-
else {
757-
TP->setSubPattern(subPattern);
758-
TP->setType(subPattern->getType());
759-
}
760-
return hadError;
744+
return validateTypedPattern(resolution, TP, options);
761745
}
762746

763747
// A wildcard or name pattern cannot appear by itself in a context

lib/Sema/TypeCheckStorage.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,15 @@ PatternBindingEntryRequest::evaluate(Evaluator &eval,
251251
binding->diagnose(diag::inferred_opaque_type,
252252
binding->getInit(entryNumber)->getType());
253253
}
254+
} else {
255+
// Coerce the pattern to the computed type.
256+
auto resolution = TypeResolution::forContextual(binding->getDeclContext());
257+
if (TypeChecker::coercePatternToType(pattern, resolution,
258+
pattern->getType(), options)) {
259+
binding->setInvalid();
260+
pattern->setType(ErrorType::get(Context));
261+
return &pbe;
262+
}
254263
}
255264

256265
// If the pattern binding appears in a type or library file context, then

test/decl/var/variables.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ func test21057425() -> (Int, Int) {
107107

108108
// rdar://problem/21081340
109109
func test21081340() {
110+
func foo() { }
110111
let (x: a, y: b): () = foo() // expected-error{{tuple pattern has the wrong length for tuple type '()'}}
111112
}
112113

0 commit comments

Comments
 (0)