@@ -367,11 +367,15 @@ namespace {
367
367
// /
368
368
// / \param variadicArgs The source indices that are mapped to the variadic
369
369
// / parameter of the resulting tuple, as provided by \c computeTupleShuffle.
370
+ // /
371
+ // / \param typeFromPattern Optionally, the caller can specifiy the pattern
372
+ // / from where the toType is derived, so that we can deliver better fixit.
370
373
Expr *coerceTupleToTuple (Expr *expr, TupleType *fromTuple,
371
374
TupleType *toTuple,
372
375
ConstraintLocatorBuilder locator,
373
376
SmallVectorImpl<int > &sources,
374
- SmallVectorImpl<unsigned > &variadicArgs);
377
+ SmallVectorImpl<unsigned > &variadicArgs,
378
+ Optional<Pattern*> typeFromPattern = None);
375
379
376
380
// / \brief Coerce the given scalar value to the given tuple type.
377
381
// /
@@ -407,7 +411,8 @@ namespace {
407
411
// / \brief Coerce an expression of (possibly unchecked) optional
408
412
// / type to have a different (possibly unchecked) optional type.
409
413
Expr *coerceOptionalToOptional (Expr *expr, Type toType,
410
- ConstraintLocatorBuilder locator);
414
+ ConstraintLocatorBuilder locator,
415
+ Optional<Pattern*> typeFromPattern = None);
411
416
412
417
// / \brief Coerce an expression of implicitly unwrapped optional type to its
413
418
// / underlying value type, in the correct way for an implicit
@@ -1083,10 +1088,13 @@ namespace {
1083
1088
// / \param expr The expression to coerce.
1084
1089
// / \param toType The type to coerce the expression to.
1085
1090
// / \param locator Locator used to describe where in this expression we are.
1091
+ // / \param typeFromPattern Optionally, the caller can specifiy the pattern
1092
+ // / from where the toType is derived, so that we can deliver better fixit.
1086
1093
// /
1087
1094
// / \returns the coerced expression, which will have type \c ToType.
1088
1095
Expr *coerceToType (Expr *expr, Type toType,
1089
- ConstraintLocatorBuilder locator);
1096
+ ConstraintLocatorBuilder locator,
1097
+ Optional<Pattern*> typeFromPattern = None);
1090
1098
1091
1099
// / \brief Coerce the given expression (which is the argument to a call) to
1092
1100
// / the given parameter type.
@@ -3673,6 +3681,56 @@ findDefaultArgsOwner(ConstraintSystem &cs, const Solution &solution,
3673
3681
return nullptr ;
3674
3682
}
3675
3683
3684
+ static bool
3685
+ shouldApplyAddingLabelFixit (TuplePattern *tuplePattern, TupleType *fromTuple,
3686
+ TupleType *toTuple,
3687
+ std::vector<std::pair<SourceLoc, std::string>> &locInsertPairs) {
3688
+ std::vector<TuplePattern*> patternParts;
3689
+ std::vector<TupleType*> fromParts;
3690
+ std::vector<TupleType*> toParts;
3691
+ patternParts.push_back (tuplePattern);
3692
+ fromParts.push_back (fromTuple);
3693
+ toParts.push_back (toTuple);
3694
+ while (!patternParts.empty ()) {
3695
+ TuplePattern *curPattern = patternParts.back ();
3696
+ TupleType *curFrom = fromParts.back ();
3697
+ TupleType *curTo = toParts.back ();
3698
+ patternParts.pop_back ();
3699
+ fromParts.pop_back ();
3700
+ toParts.pop_back ();
3701
+ unsigned n = curPattern->getElements ().size ();
3702
+ if (curFrom->getElements ().size () != n ||
3703
+ curTo->getElements ().size () != n)
3704
+ return false ;
3705
+ for (unsigned i = 0 ; i < n; i ++) {
3706
+ Pattern* subPat = curPattern->getElement (i).getPattern ();
3707
+ const TupleTypeElt &subFrom = curFrom->getElement (i);
3708
+ const TupleTypeElt &subTo = curTo->getElement (i);
3709
+ if ((subFrom.getType ()->getKind () == TypeKind::Tuple) ^
3710
+ (subTo.getType ()->getKind () == TypeKind::Tuple))
3711
+ return false ;
3712
+ auto addLabelFunc = [&]() {
3713
+ if (subFrom.getName ().empty () && !subTo.getName ().empty ()) {
3714
+ llvm::SmallString<8 > Name;
3715
+ Name.append (subTo.getName ().str ());
3716
+ Name.append (" : " );
3717
+ locInsertPairs.push_back ({subPat->getStartLoc (), Name.str ()});
3718
+ }
3719
+ };
3720
+ if (auto subFromTuple = subFrom.getType ()->getAs <TupleType>()) {
3721
+ fromParts.push_back (subFromTuple);
3722
+ toParts.push_back (subTo.getType ()->getAs <TupleType>());
3723
+ patternParts.push_back (static_cast <TuplePattern*>(subPat));
3724
+ addLabelFunc ();
3725
+ } else if (subFrom.getType ()->isEqual (subTo.getType ())) {
3726
+ addLabelFunc ();
3727
+ } else
3728
+ return false ;
3729
+ }
3730
+ }
3731
+ return true ;
3732
+ }
3733
+
3676
3734
// / Produce the caller-side default argument for this default argument, or
3677
3735
// / null if the default argument will be provided by the callee.
3678
3736
static std::pair<Expr *, DefaultArgumentKind>
@@ -3792,7 +3850,8 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple,
3792
3850
TupleType *toTuple,
3793
3851
ConstraintLocatorBuilder locator,
3794
3852
SmallVectorImpl<int > &sources,
3795
- SmallVectorImpl<unsigned > &variadicArgs){
3853
+ SmallVectorImpl<unsigned > &variadicArgs,
3854
+ Optional<Pattern*> typeFromPattern){
3796
3855
auto &tc = cs.getTypeChecker ();
3797
3856
3798
3857
// Capture the tuple expression, if there is one.
@@ -3883,9 +3942,19 @@ Expr *ExprRewriter::coerceTupleToTuple(Expr *expr, TupleType *fromTuple,
3883
3942
// We need to convert the source element to the destination type.
3884
3943
if (!fromTupleExpr) {
3885
3944
// FIXME: Lame! We can't express this in the AST.
3886
- tc.diagnose (expr->getLoc (),
3887
- diag::tuple_conversion_not_expressible,
3888
- fromTuple, toTuple);
3945
+ InFlightDiagnostic diag = tc.diagnose (expr->getLoc (),
3946
+ diag::tuple_conversion_not_expressible,
3947
+ fromTuple, toTuple);
3948
+ if (typeFromPattern) {
3949
+ std::vector<std::pair<SourceLoc, std::string>> locInsertPairs;
3950
+ TuplePattern *tupleP = dyn_cast<TuplePattern>(typeFromPattern.getValue ());
3951
+ if (tupleP && shouldApplyAddingLabelFixit (tupleP, toTuple, fromTuple,
3952
+ locInsertPairs)) {
3953
+ for (auto &Pair : locInsertPairs) {
3954
+ diag.fixItInsert (Pair.first , Pair.second );
3955
+ }
3956
+ }
3957
+ }
3889
3958
return nullptr ;
3890
3959
}
3891
3960
@@ -4238,7 +4307,8 @@ static Type getOptionalBaseType(const Type &type) {
4238
4307
}
4239
4308
4240
4309
Expr *ExprRewriter::coerceOptionalToOptional (Expr *expr, Type toType,
4241
- ConstraintLocatorBuilder locator) {
4310
+ ConstraintLocatorBuilder locator,
4311
+ Optional<Pattern*> typeFromPattern) {
4242
4312
auto &tc = cs.getTypeChecker ();
4243
4313
Type fromType = expr->getType ();
4244
4314
@@ -4287,7 +4357,7 @@ Expr *ExprRewriter::coerceOptionalToOptional(Expr *expr, Type toType,
4287
4357
expr = new (tc.Context ) BindOptionalExpr (expr, expr->getSourceRange ().End ,
4288
4358
/* depth*/ 0 , fromValueType);
4289
4359
expr->setImplicit (true );
4290
- expr = coerceToType (expr, toValueType, locator);
4360
+ expr = coerceToType (expr, toValueType, locator, typeFromPattern );
4291
4361
if (!expr) return nullptr ;
4292
4362
4293
4363
expr = new (tc.Context ) InjectIntoOptionalExpr (expr, toType);
@@ -4743,7 +4813,8 @@ maybeDiagnoseUnsupportedFunctionConversion(TypeChecker &tc, Expr *expr,
4743
4813
}
4744
4814
4745
4815
Expr *ExprRewriter::coerceToType (Expr *expr, Type toType,
4746
- ConstraintLocatorBuilder locator) {
4816
+ ConstraintLocatorBuilder locator,
4817
+ Optional<Pattern*> typeFromPattern) {
4747
4818
auto &tc = cs.getTypeChecker ();
4748
4819
4749
4820
// The type we're converting from.
@@ -4769,7 +4840,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
4769
4840
assert (!failed && " Couldn't convert tuple to tuple?" );
4770
4841
(void )failed;
4771
4842
return coerceTupleToTuple (expr, fromTuple, toTuple, locator, sources,
4772
- variadicArgs);
4843
+ variadicArgs, typeFromPattern );
4773
4844
}
4774
4845
4775
4846
case ConversionRestrictionKind::ScalarToTuple: {
@@ -4876,7 +4947,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
4876
4947
case ConversionRestrictionKind::OptionalToImplicitlyUnwrappedOptional:
4877
4948
case ConversionRestrictionKind::ImplicitlyUnwrappedOptionalToOptional:
4878
4949
case ConversionRestrictionKind::OptionalToOptional:
4879
- return coerceOptionalToOptional (expr, toType, locator);
4950
+ return coerceOptionalToOptional (expr, toType, locator, typeFromPattern );
4880
4951
4881
4952
case ConversionRestrictionKind::ForceUnchecked: {
4882
4953
auto valueTy = fromType->getImplicitlyUnwrappedOptionalObjectType ();
@@ -5175,7 +5246,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
5175
5246
5176
5247
if (toType->getAnyOptionalObjectType () &&
5177
5248
expr->getType ()->getAnyOptionalObjectType ()) {
5178
- return coerceOptionalToOptional (expr, toType, locator);
5249
+ return coerceOptionalToOptional (expr, toType, locator, typeFromPattern );
5179
5250
}
5180
5251
5181
5252
// Coercion to Optional<T>.
@@ -6193,12 +6264,13 @@ Expr *ConstraintSystem::applySolutionShallow(const Solution &solution,
6193
6264
6194
6265
Expr *Solution::coerceToType (Expr *expr, Type toType,
6195
6266
ConstraintLocator *locator,
6196
- bool ignoreTopLevelInjection) const {
6267
+ bool ignoreTopLevelInjection,
6268
+ Optional<Pattern*> typeFromPattern) const {
6197
6269
auto &cs = getConstraintSystem ();
6198
6270
ExprRewriter rewriter (cs, *this ,
6199
6271
/* suppressDiagnostics=*/ false ,
6200
6272
/* skipClosures=*/ false );
6201
- Expr *result = rewriter.coerceToType (expr, toType, locator);
6273
+ Expr *result = rewriter.coerceToType (expr, toType, locator, typeFromPattern );
6202
6274
if (!result)
6203
6275
return nullptr ;
6204
6276
0 commit comments