Skip to content

Commit f22ca72

Browse files
committed
[ConstraintSystem] Always verify computed/resolved pattern types before use
While trying to infer type for pattern always take result of `getTypeForPattern` and `resolveTypeInExpressionContext` with a grain of salt because both of these methods produce empty type if type as-written or one of the sub-pattern types is incorrect. Resolves: rdar://problem/60534522
1 parent 20e973d commit f22ca72

File tree

1 file changed

+42
-7
lines changed

1 file changed

+42
-7
lines changed

lib/Sema/CSGen.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,6 +2255,8 @@ namespace {
22552255

22562256
switch (pattern->getKind()) {
22572257
case PatternKind::Paren: {
2258+
auto *paren = cast<ParenPattern>(pattern);
2259+
22582260
// Parentheses don't affect the canonical type, but record them as
22592261
// type sugar.
22602262
if (externalPatternType &&
@@ -2263,13 +2265,14 @@ namespace {
22632265
->getUnderlyingType();
22642266
}
22652267

2266-
return setType(
2267-
ParenType::get(
2268-
CS.getASTContext(),
2269-
getTypeForPattern(
2270-
cast<ParenPattern>(pattern)->getSubPattern(), locator,
2271-
externalPatternType,
2272-
bindPatternVarsOneWay)));
2268+
auto underlyingType =
2269+
getTypeForPattern(paren->getSubPattern(), locator,
2270+
externalPatternType, bindPatternVarsOneWay);
2271+
2272+
if (!underlyingType)
2273+
return Type();
2274+
2275+
return setType(ParenType::get(CS.getASTContext(), underlyingType));
22732276
}
22742277
case PatternKind::Var:
22752278
// Var doesn't affect the type.
@@ -2374,10 +2377,14 @@ namespace {
23742377

23752378
Type type = TypeChecker::typeCheckPattern(contextualPattern);
23762379

2380+
if (!type)
2381+
return Type();
2382+
23772383
// Look through reference storage types.
23782384
type = type->getReferenceStorageReferent();
23792385

23802386
Type openedType = CS.openUnboundGenericType(type, locator);
2387+
assert(openedType);
23812388

23822389
auto *subPattern = cast<TypedPattern>(pattern)->getSubPattern();
23832390
// Determine the subpattern type. It will be convertible to the
@@ -2387,6 +2394,9 @@ namespace {
23872394
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
23882395
openedType, bindPatternVarsOneWay);
23892396

2397+
if (!subPatternType)
2398+
return Type();
2399+
23902400
CS.addConstraint(
23912401
ConstraintKind::Conversion, subPatternType, openedType,
23922402
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
@@ -2429,6 +2439,10 @@ namespace {
24292439
eltPattern,
24302440
locator.withPathElement(LocatorPathElt::PatternMatch(eltPattern)),
24312441
externalEltType, bindPatternVarsOneWay);
2442+
2443+
if (!eltTy)
2444+
return Type();
2445+
24322446
tupleTypeElts.push_back(TupleTypeElt(eltTy, tupleElt.getLabel()));
24332447
}
24342448

@@ -2456,6 +2470,9 @@ namespace {
24562470
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
24572471
externalPatternType, bindPatternVarsOneWay);
24582472

2473+
if (!subPatternType)
2474+
return Type();
2475+
24592476
return setType(OptionalType::get(subPatternType));
24602477
}
24612478

@@ -2464,16 +2481,25 @@ namespace {
24642481

24652482
Type castType =
24662483
resolveTypeReferenceInExpression(isPattern->getCastTypeLoc());
2484+
2485+
if (!castType)
2486+
return Type();
2487+
24672488
castType = CS.openUnboundGenericType(
24682489
castType,
24692490
locator.withPathElement(LocatorPathElt::PatternMatch(pattern)));
24702491

2492+
assert(castType);
2493+
24712494
auto *subPattern = isPattern->getSubPattern();
24722495
Type subPatternType = getTypeForPattern(
24732496
subPattern,
24742497
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
24752498
castType, bindPatternVarsOneWay);
24762499

2500+
if (!subPatternType)
2501+
return Type();
2502+
24772503
// Make sure we can cast from the subpattern type to the type we're
24782504
// checking; if it's impossible, fail.
24792505
CS.addConstraint(
@@ -2506,11 +2532,16 @@ namespace {
25062532
Type parentType =
25072533
resolveTypeReferenceInExpression(enumPattern->getParentType());
25082534

2535+
if (!parentType)
2536+
return Type();
2537+
25092538
parentType = CS.openUnboundGenericType(
25102539
parentType, CS.getConstraintLocator(
25112540
locator, {LocatorPathElt::PatternMatch(pattern),
25122541
ConstraintLocator::ParentType}));
25132542

2543+
assert(parentType);
2544+
25142545
// Perform member lookup into the parent's metatype.
25152546
Type parentMetaType = MetatypeType::get(parentType);
25162547
CS.addValueMemberConstraint(
@@ -2543,6 +2574,10 @@ namespace {
25432574
// types.
25442575
Type subPatternType = getTypeForPattern(
25452576
subPattern, locator, Type(), bindPatternVarsOneWay);
2577+
2578+
if (!subPatternType)
2579+
return Type();
2580+
25462581
SmallVector<AnyFunctionType::Param, 4> params;
25472582
AnyFunctionType::decomposeInput(subPatternType, params);
25482583

0 commit comments

Comments
 (0)