@@ -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
@@ -4318,11 +4356,19 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
4318
4356
initializer, LocatorPathElt::ContextualType (CTP_Initialization));
4319
4357
4320
4358
Type patternType;
4359
+ bool forExprPattern = false ;
4321
4360
if (auto pattern = target.getInitializationPattern ()) {
4322
- patternType = cs.generateConstraints (
4361
+ auto *semanticPattern =
4362
+ pattern->getSemanticsProvidingPattern (/* allowTypedPattern*/ false );
4363
+ forExprPattern = isa<ExprPattern>(semanticPattern);
4364
+ auto ty = cs.generateConstraints (
4323
4365
pattern, locator, target.shouldBindPatternVarsOneWay (),
4324
4366
target.getInitializationPatternBindingDecl (),
4325
4367
target.getInitializationPatternBindingIndex ());
4368
+ if (!ty)
4369
+ return true ;
4370
+
4371
+ patternType = *ty;
4326
4372
} else {
4327
4373
patternType = cs.createTypeVariable (locator, TVO_CanBindToNoEscape);
4328
4374
}
@@ -4331,9 +4377,15 @@ static bool generateInitPatternConstraints(ConstraintSystem &cs,
4331
4377
return cs.generateWrappedPropertyTypeConstraints (
4332
4378
wrappedVar, cs.getType (target.getAsExpr ()), patternType);
4333
4379
4334
- // Add a conversion constraint between the types.
4335
- cs.addConstraint (ConstraintKind::Conversion, cs.getType (target.getAsExpr ()),
4336
- patternType, locator, /* isFavored*/ true );
4380
+ // Add a constraint between the types. For ExprPatterns, we want an equality
4381
+ // constraint, because we want to propagate the type of the initializer directly
4382
+ // into the implicit '~=' call. We'll then allow conversions when matching that as
4383
+ // an argument. This avoids producing bad diagnostics where we try and apply fixes
4384
+ // to the conversion outside of the call.
4385
+ auto kind = forExprPattern ? ConstraintKind::Equal
4386
+ : ConstraintKind::Conversion;
4387
+ cs.addConstraint (kind, cs.getType (target.getAsExpr ()),
4388
+ patternType, locator, /* isFavored*/ true );
4337
4389
4338
4390
return false ;
4339
4391
}
@@ -4481,7 +4533,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4481
4533
// Collect constraints from the element pattern.
4482
4534
auto elementLocator = cs.getConstraintLocator (
4483
4535
sequenceExpr, ConstraintLocator::SequenceElementType);
4484
- Type initType =
4536
+ auto initType =
4485
4537
cs.generateConstraints (pattern, elementLocator,
4486
4538
target.shouldBindPatternVarsOneWay (), nullptr , 0 );
4487
4539
if (!initType)
@@ -4500,7 +4552,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4500
4552
// resolving `optional object` constraint which is sometimes too eager.
4501
4553
cs.addConstraint (ConstraintKind::Conversion, nextType,
4502
4554
OptionalType::get (elementType), elementTypeLoc);
4503
- cs.addConstraint (ConstraintKind::Conversion, elementType, initType,
4555
+ cs.addConstraint (ConstraintKind::Conversion, elementType, * initType,
4504
4556
elementLocator);
4505
4557
}
4506
4558
@@ -4526,7 +4578,7 @@ generateForEachStmtConstraints(ConstraintSystem &cs,
4526
4578
4527
4579
// Populate all of the information for a for-each loop.
4528
4580
forEachStmtInfo.elementType = elementType;
4529
- forEachStmtInfo.initType = initType;
4581
+ forEachStmtInfo.initType = * initType;
4530
4582
target.setPattern (pattern);
4531
4583
target.getForEachStmtInfo () = forEachStmtInfo;
4532
4584
return target;
@@ -4706,7 +4758,7 @@ bool ConstraintSystem::generateConstraints(
4706
4758
4707
4759
// Generate constraints to bind all of the internal declarations
4708
4760
// and verify the pattern.
4709
- Type patternType = generateConstraints (
4761
+ auto patternType = generateConstraints (
4710
4762
pattern, locator, /* shouldBindPatternVarsOneWay*/ true ,
4711
4763
target.getPatternBindingOfUninitializedVar (),
4712
4764
target.getIndexOfUninitializedVar ());
@@ -4735,25 +4787,13 @@ Expr *ConstraintSystem::generateConstraints(
4735
4787
return generateConstraintsFor (*this , expr, dc);
4736
4788
}
4737
4789
4738
- Type ConstraintSystem::generateConstraints (
4790
+ Optional< Type> ConstraintSystem::generateConstraints (
4739
4791
Pattern *pattern, ConstraintLocatorBuilder locator,
4740
4792
bool bindPatternVarsOneWay, PatternBindingDecl *patternBinding,
4741
4793
unsigned patternIndex) {
4742
4794
ConstraintGenerator cg (*this , nullptr );
4743
- auto ty = cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4744
- patternBinding, patternIndex);
4745
- assert (ty);
4746
-
4747
- // Gather the ExprPatterns, and form a conjunction for their expressions.
4748
- SmallVector<ExprPattern *, 4 > exprPatterns;
4749
- pattern->forEachNode ([&](Pattern *P) {
4750
- if (auto *EP = dyn_cast<ExprPattern>(P))
4751
- exprPatterns.push_back (EP);
4752
- });
4753
- if (!exprPatterns.empty ())
4754
- generateConstraints (exprPatterns, getConstraintLocator (pattern));
4755
-
4756
- return ty;
4795
+ return cg.getTypeForPattern (pattern, locator, bindPatternVarsOneWay,
4796
+ patternBinding, patternIndex);
4757
4797
}
4758
4798
4759
4799
bool ConstraintSystem::generateConstraints (StmtCondition condition,
0 commit comments