@@ -2442,7 +2442,7 @@ namespace {
2442
2442
// / for the types of each variable declared within the pattern, along
2443
2443
// / with a one-way constraint binding that to the type to which the
2444
2444
// / variable will be ascribed or inferred.
2445
- Type getTypeForPattern (
2445
+ Optional< Type> getTypeForPattern (
2446
2446
Pattern *pattern, ConstraintLocatorBuilder locator,
2447
2447
bool bindPatternVarsOneWay,
2448
2448
PatternBindingDecl *patternBinding = nullptr ,
@@ -2466,14 +2466,21 @@ namespace {
2466
2466
locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2467
2467
bindPatternVarsOneWay);
2468
2468
2469
- return setType (ParenType::get (CS.getASTContext (), underlyingType));
2469
+ if (!underlyingType)
2470
+ return None;
2471
+
2472
+ return setType (ParenType::get (CS.getASTContext (), *underlyingType));
2470
2473
}
2471
2474
case PatternKind::Binding: {
2472
2475
auto *subPattern = cast<BindingPattern>(pattern)->getSubPattern ();
2473
2476
auto type = getTypeForPattern (subPattern, locator,
2474
2477
bindPatternVarsOneWay);
2478
+
2479
+ if (!type)
2480
+ return None;
2481
+
2475
2482
// Var doesn't affect the type.
2476
- return setType (type);
2483
+ return setType (* type);
2477
2484
}
2478
2485
case PatternKind::Any: {
2479
2486
Type type;
@@ -2653,6 +2660,9 @@ namespace {
2653
2660
2654
2661
Type type = TypeChecker::typeCheckPattern (contextualPattern);
2655
2662
2663
+ if (!type)
2664
+ return None;
2665
+
2656
2666
// Look through reference storage types.
2657
2667
type = type->getReferenceStorageReferent ();
2658
2668
@@ -2664,16 +2674,19 @@ namespace {
2664
2674
auto *subPattern = cast<TypedPattern>(pattern)->getSubPattern ();
2665
2675
// Determine the subpattern type. It will be convertible to the
2666
2676
// ascribed type.
2667
- Type subPatternType = getTypeForPattern (
2677
+ auto subPatternType = getTypeForPattern (
2668
2678
subPattern,
2669
2679
locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2670
2680
bindPatternVarsOneWay);
2671
2681
2682
+ if (!subPatternType)
2683
+ return None;
2684
+
2672
2685
// NOTE: The order here is important! Pattern matching equality is
2673
2686
// not symmetric (we need to fix that either by using a different
2674
2687
// constraint, or actually making it symmetric).
2675
2688
CS.addConstraint (
2676
- ConstraintKind::Equal, openedType, subPatternType,
2689
+ ConstraintKind::Equal, openedType, * subPatternType,
2677
2690
locator.withPathElement (LocatorPathElt::PatternMatch (pattern)));
2678
2691
2679
2692
// FIXME [OPAQUE SUPPORT]: the distinction between where we want opaque
@@ -2693,12 +2706,15 @@ namespace {
2693
2706
auto &tupleElt = tuplePat->getElement (i);
2694
2707
2695
2708
auto *eltPattern = tupleElt.getPattern ();
2696
- Type eltTy = getTypeForPattern (
2709
+ auto eltTy = getTypeForPattern (
2697
2710
eltPattern,
2698
2711
locator.withPathElement (LocatorPathElt::PatternMatch (eltPattern)),
2699
2712
bindPatternVarsOneWay);
2700
2713
2701
- tupleTypeElts.push_back (TupleTypeElt (eltTy, tupleElt.getLabel ()));
2714
+ if (!eltTy)
2715
+ return None;
2716
+
2717
+ tupleTypeElts.push_back (TupleTypeElt (*eltTy, tupleElt.getLabel ()));
2702
2718
}
2703
2719
2704
2720
return setType (TupleType::get (tupleTypeElts, CS.getASTContext ()));
@@ -2707,12 +2723,15 @@ namespace {
2707
2723
case PatternKind::OptionalSome: {
2708
2724
auto *subPattern = cast<OptionalSomePattern>(pattern)->getSubPattern ();
2709
2725
// The subpattern must have optional type.
2710
- Type subPatternType = getTypeForPattern (
2726
+ auto subPatternType = getTypeForPattern (
2711
2727
subPattern,
2712
2728
locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2713
2729
bindPatternVarsOneWay);
2714
2730
2715
- return setType (OptionalType::get (subPatternType));
2731
+ if (!subPatternType)
2732
+ return None;
2733
+
2734
+ return setType (OptionalType::get (*subPatternType));
2716
2735
}
2717
2736
2718
2737
case PatternKind::Is: {
@@ -2742,12 +2761,14 @@ namespace {
2742
2761
subPattern,
2743
2762
locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2744
2763
bindPatternVarsOneWay);
2764
+ if (!subPatternType)
2765
+ return None;
2745
2766
2746
2767
// NOTE: The order here is important! Pattern matching equality is
2747
2768
// not symmetric (we need to fix that either by using a different
2748
2769
// constraint, or actually making it symmetric).
2749
2770
CS.addConstraint (
2750
- ConstraintKind::Equal, castType, subPatternType,
2771
+ ConstraintKind::Equal, castType, * subPatternType,
2751
2772
locator.withPathElement (LocatorPathElt::PatternMatch (pattern)));
2752
2773
}
2753
2774
return setType (isType);
@@ -2811,6 +2832,9 @@ namespace {
2811
2832
TypeResolverContext::InExpression, patternMatchLoc);
2812
2833
}();
2813
2834
2835
+ if (!parentType)
2836
+ return None;
2837
+
2814
2838
// Perform member lookup into the parent's metatype.
2815
2839
Type parentMetaType = MetatypeType::get (parentType);
2816
2840
CS.addValueMemberConstraint (parentMetaType, enumPattern->getName (),
@@ -2838,13 +2862,13 @@ namespace {
2838
2862
// When there is a subpattern, the member will have function type,
2839
2863
// and we're matching the type of that subpattern to the parameter
2840
2864
// types.
2841
- Type subPatternType = getTypeForPattern (
2865
+ auto subPatternType = getTypeForPattern (
2842
2866
subPattern,
2843
2867
locator.withPathElement (LocatorPathElt::PatternMatch (subPattern)),
2844
2868
bindPatternVarsOneWay);
2845
2869
2846
2870
SmallVector<AnyFunctionType::Param, 4 > params;
2847
- decomposeTuple (subPatternType, params);
2871
+ decomposeTuple (* subPatternType, params);
2848
2872
2849
2873
// Remove parameter labels; they aren't used when matching cases,
2850
2874
// but outright conflicts will be checked during coercion.
@@ -2877,10 +2901,24 @@ namespace {
2877
2901
}
2878
2902
2879
2903
case PatternKind::Expr: {
2880
- // We generate constraints for ExprPatterns in a separate pass. For
2881
- // now, just create a type variable.
2882
- return setType (CS.createTypeVariable (CS.getConstraintLocator (locator),
2883
- TVO_CanBindToNoEscape));
2904
+ auto *EP = cast<ExprPattern>(pattern);
2905
+ Type patternTy = CS.createTypeVariable (CS.getConstraintLocator (locator),
2906
+ TVO_CanBindToNoEscape);
2907
+
2908
+ auto target = SyntacticElementTarget::forExprPattern (EP);
2909
+
2910
+ if (CS.preCheckTarget (target, /* replaceInvalidRefWithErrors=*/ true ,
2911
+ /* leaveClosureBodyUnchecked=*/ false )) {
2912
+ return None;
2913
+ }
2914
+ CS.setType (EP->getMatchVar (), patternTy);
2915
+
2916
+ if (CS.generateConstraints (target))
2917
+ return None;
2918
+
2919
+ CS.setTargetFor (EP, target);
2920
+ CS.setExprPatternFor (EP->getSubExpr (), EP);
2921
+ return setType (patternTy);
2884
2922
}
2885
2923
}
2886
2924
@@ -4328,11 +4366,19 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
4328
4366
initializer, LocatorPathElt::ContextualType (CTP_Initialization));
4329
4367
4330
4368
Type patternType;
4369
+ bool forExprPattern = false ;
4331
4370
if (auto pattern = target.getInitializationPattern ()) {
4332
- patternType = cs.generateConstraints (
4371
+ auto *semanticPattern =
4372
+ pattern->getSemanticsProvidingPattern (/* allowTypedPattern*/ false );
4373
+ forExprPattern = isa<ExprPattern>(semanticPattern);
4374
+ auto ty = cs.generateConstraints (
4333
4375
pattern, locator, target.shouldBindPatternVarsOneWay (),
4334
4376
target.getInitializationPatternBindingDecl (),
4335
4377
target.getInitializationPatternBindingIndex ());
4378
+ if (!ty)
4379
+ return true ;
4380
+
4381
+ patternType = *ty;
4336
4382
} else {
4337
4383
patternType = cs.createTypeVariable (locator, TVO_CanBindToNoEscape);
4338
4384
}
@@ -4341,9 +4387,15 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
4341
4387
return cs.generateWrappedPropertyTypeConstraints (
4342
4388
wrappedVar, cs.getType (target.getAsExpr ()), patternType);
4343
4389
4344
- // Add a conversion constraint between the types.
4345
- cs.addConstraint (ConstraintKind::Conversion, cs.getType (target.getAsExpr ()),
4346
- patternType, locator, /* isFavored*/ true );
4390
+ // Add a constraint between the types. For ExprPatterns, we want an equality
4391
+ // constraint, because we want to propagate the type of the initializer
4392
+ // directly into the implicit '~=' call. We'll then allow conversions when
4393
+ // matching that as an argument. This avoids producing bad diagnostics where
4394
+ // we try and apply fixes to the conversion outside of the call.
4395
+ auto kind = forExprPattern ? ConstraintKind::Equal
4396
+ : ConstraintKind::Conversion;
4397
+ cs.addConstraint (kind, cs.getType (target.getAsExpr ()), patternType, locator,
4398
+ /* isFavored*/ true );
4347
4399
4348
4400
return false ;
4349
4401
}
@@ -4491,7 +4543,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4491
4543
// Collect constraints from the element pattern.
4492
4544
auto elementLocator = cs.getConstraintLocator (
4493
4545
sequenceExpr, ConstraintLocator::SequenceElementType);
4494
- Type initType =
4546
+ auto initType =
4495
4547
cs.generateConstraints (pattern, elementLocator,
4496
4548
target.shouldBindPatternVarsOneWay (), nullptr , 0 );
4497
4549
if (!initType)
@@ -4510,7 +4562,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4510
4562
// resolving `optional object` constraint which is sometimes too eager.
4511
4563
cs.addConstraint (ConstraintKind::Conversion, nextType,
4512
4564
OptionalType::get (elementType), elementTypeLoc);
4513
- cs.addConstraint (ConstraintKind::Conversion, elementType, initType,
4565
+ cs.addConstraint (ConstraintKind::Conversion, elementType, * initType,
4514
4566
elementLocator);
4515
4567
}
4516
4568
@@ -4536,7 +4588,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4536
4588
4537
4589
// Populate all of the information for a for-each loop.
4538
4590
forEachStmtInfo.elementType = elementType;
4539
- forEachStmtInfo.initType = initType;
4591
+ forEachStmtInfo.initType = * initType;
4540
4592
target.setPattern (pattern);
4541
4593
target.getForEachStmtInfo () = forEachStmtInfo;
4542
4594
return target;
@@ -4716,7 +4768,7 @@ bool ConstraintSystem::generateConstraints(
4716
4768
4717
4769
// Generate constraints to bind all of the internal declarations
4718
4770
// and verify the pattern.
4719
- Type patternType = generateConstraints (
4771
+ auto patternType = generateConstraints (
4720
4772
pattern, locator, /* shouldBindPatternVarsOneWay*/ true ,
4721
4773
target.getPatternBindingOfUninitializedVar (),
4722
4774
target.getIndexOfUninitializedVar ());
@@ -4745,25 +4797,13 @@ Expr *ConstraintSystem::generateConstraints(
4745
4797
return generateConstraintsFor (*this , expr, dc);
4746
4798
}
4747
4799
4748
- Type ConstraintSystem::generateConstraints (
4800
+ Optional< Type> ConstraintSystem::generateConstraints (
4749
4801
Pattern *pattern, ConstraintLocatorBuilder locator,
4750
4802
bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
4751
4803
unsigned patternIndex) {
4752
4804
ConstraintGenerator cg (*this , nullptr );
4753
- auto ty = cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4754
- patternBinding, patternIndex);
4755
- assert (ty);
4756
-
4757
- // Gather the ExprPatterns, and form a conjunction for their expressions.
4758
- SmallVector<ExprPattern *, 4 > exprPatterns;
4759
- pattern->forEachNode ([&](Pattern *P) {
4760
- if (auto *EP = dyn_cast<ExprPattern>(P))
4761
- exprPatterns.push_back (EP);
4762
- });
4763
- if (!exprPatterns.empty ())
4764
- generateConstraints (exprPatterns, getConstraintLocator (pattern));
4765
-
4766
- return ty;
4805
+ return cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4806
+ patternBinding, patternIndex);
4767
4807
}
4768
4808
4769
4809
bool ConstraintSystem::generateConstraints (StmtCondition condition,
0 commit comments