@@ -938,7 +938,8 @@ class ArgumentFailureTracker : public MatchCallArgumentListener {
938
938
// Match the argument of a call to the parameter.
939
939
ConstraintSystem::TypeMatchResult constraints::matchCallArguments (
940
940
ConstraintSystem &cs, ArrayRef<AnyFunctionType::Param> args,
941
- ArrayRef<AnyFunctionType::Param> params, ConstraintLocatorBuilder locator) {
941
+ ArrayRef<AnyFunctionType::Param> params, ConstraintKind subKind,
942
+ ConstraintLocatorBuilder locator) {
942
943
// Extract the parameters.
943
944
ValueDecl *callee;
944
945
bool hasCurriedSelf;
@@ -971,12 +972,6 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
971
972
// assignment operators.
972
973
auto *anchor = locator.getAnchor ();
973
974
assert (anchor && " locator without anchor expression?" );
974
- bool isOperator = (isa<PrefixUnaryExpr>(anchor) ||
975
- isa<PostfixUnaryExpr>(anchor) || isa<BinaryExpr>(anchor));
976
-
977
- ConstraintKind subKind = (isOperator
978
- ? ConstraintKind::OperatorArgumentConversion
979
- : ConstraintKind::ArgumentConversion);
980
975
981
976
// Check whether argument of the call at given position refers to
982
977
// parameter marked as `@autoclosure`. This function is used to
@@ -2218,7 +2213,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2218
2213
auto desugar2 = type2->getDesugaredType ();
2219
2214
2220
2215
// If the types are obviously equivalent, we're done.
2221
- if (desugar1->isEqual (desugar2))
2216
+ if (desugar1->isEqual (desugar2) &&
2217
+ !isa<InOutType>(desugar2))
2222
2218
return getTypeMatchSuccess ();
2223
2219
2224
2220
// Local function that should be used to produce the return value whenever
@@ -2527,11 +2523,15 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2527
2523
ConstraintLocator::LValueConversion));
2528
2524
2529
2525
case TypeKind::InOut:
2530
- // If the RHS is an inout type, the LHS must be an @lvalue type.
2531
- if (kind == ConstraintKind::BindParam ||
2532
- kind >= ConstraintKind::OperatorArgumentConversion)
2526
+ if (kind == ConstraintKind::BindParam)
2533
2527
return getTypeMatchFailure (locator);
2534
2528
2529
+ if (kind == ConstraintKind::OperatorArgumentConversion) {
2530
+ conversionsOrFixes.push_back (
2531
+ RemoveAddressOf::create (*this , getConstraintLocator (locator)));
2532
+ break ;
2533
+ }
2534
+
2535
2535
return matchTypes (cast<InOutType>(desugar1)->getObjectType (),
2536
2536
cast<InOutType>(desugar2)->getObjectType (),
2537
2537
ConstraintKind::Bind, subflags,
@@ -2557,9 +2557,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2557
2557
auto opaque1 = cast<OpaqueTypeArchetypeType>(desugar1);
2558
2558
auto opaque2 = cast<OpaqueTypeArchetypeType>(desugar2);
2559
2559
2560
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2561
- if (!type1->is <LValueType>()
2562
- && opaque1->getDecl () == opaque2->getDecl ()) {
2560
+ if (opaque1->getDecl () == opaque2->getDecl ()) {
2563
2561
conversionsOrFixes.push_back (ConversionRestrictionKind::DeepEquality);
2564
2562
}
2565
2563
break ;
@@ -2573,15 +2571,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2573
2571
auto rootOpaque1 = dyn_cast<OpaqueTypeArchetypeType>(nested1->getRoot ());
2574
2572
auto rootOpaque2 = dyn_cast<OpaqueTypeArchetypeType>(nested2->getRoot ());
2575
2573
if (rootOpaque1 && rootOpaque2) {
2576
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2577
2574
auto interfaceTy1 = nested1->getInterfaceType ()
2578
2575
->getCanonicalType (rootOpaque1->getGenericEnvironment ()
2579
2576
->getGenericSignature ());
2580
2577
auto interfaceTy2 = nested2->getInterfaceType ()
2581
2578
->getCanonicalType (rootOpaque2->getGenericEnvironment ()
2582
2579
->getGenericSignature ());
2583
- if (!type1->is <LValueType>()
2584
- && interfaceTy1 == interfaceTy2
2580
+ if (interfaceTy1 == interfaceTy2
2585
2581
&& rootOpaque1->getDecl () == rootOpaque2->getDecl ()) {
2586
2582
conversionsOrFixes.push_back (ConversionRestrictionKind::DeepEquality);
2587
2583
break ;
@@ -2600,7 +2596,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2600
2596
// T1 is convertible to T2 (by loading the value). Note that we cannot get
2601
2597
// a value of inout type as an lvalue though.
2602
2598
if (type1->is <LValueType>() && !type2->is <InOutType>()) {
2603
- return matchTypes (type1->getRValueType (), type2,
2599
+ return matchTypes (type1->getWithoutSpecifierType (), type2,
2604
2600
kind, subflags, locator);
2605
2601
}
2606
2602
}
@@ -2657,7 +2653,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2657
2653
// We can remove this special case when we implement operator hiding.
2658
2654
if (!type1->is <LValueType>() &&
2659
2655
kind != ConstraintKind::OperatorArgumentConversion) {
2660
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2661
2656
conversionsOrFixes.push_back (
2662
2657
ConversionRestrictionKind::HashableToAnyHashable);
2663
2658
}
@@ -2720,16 +2715,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
2720
2715
if (!type1->is <LValueType>() && kind >= ConstraintKind::Subtype) {
2721
2716
// Array -> Array.
2722
2717
if (isArrayType (desugar1) && isArrayType (desugar2)) {
2723
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2724
2718
conversionsOrFixes.push_back (ConversionRestrictionKind::ArrayUpcast);
2725
2719
// Dictionary -> Dictionary.
2726
2720
} else if (isDictionaryType (desugar1) && isDictionaryType (desugar2)) {
2727
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2728
2721
conversionsOrFixes.push_back (
2729
2722
ConversionRestrictionKind::DictionaryUpcast);
2730
2723
// Set -> Set.
2731
2724
} else if (isSetType (desugar1) && isSetType (desugar2)) {
2732
- assert (!type2->is <LValueType>() && " Unexpected lvalue type!" );
2733
2725
conversionsOrFixes.push_back (
2734
2726
ConversionRestrictionKind::SetUpcast);
2735
2727
}
@@ -5649,9 +5641,26 @@ ConstraintSystem::simplifyApplicableFnConstraint(
5649
5641
5650
5642
TypeMatchOptions subflags = getDefaultDecompositionOptions (flags);
5651
5643
5652
- // If the types are obviously equivalent, we're done.
5653
- if (type1.getPointer () == desugar2)
5654
- return SolutionKind::Solved;
5644
+ SmallVector<LocatorPathElt, 2 > parts;
5645
+ Expr *anchor = locator.getLocatorParts (parts);
5646
+ bool isOperator = (isa<PrefixUnaryExpr>(anchor) ||
5647
+ isa<PostfixUnaryExpr>(anchor) ||
5648
+ isa<BinaryExpr>(anchor));
5649
+
5650
+ auto hasInOut = [&]() {
5651
+ for (auto param : func1->getParams ())
5652
+ if (param.isInOut ())
5653
+ return true ;
5654
+ return false ;
5655
+ };
5656
+
5657
+ // If the types are obviously equivalent, we're done. This optimization
5658
+ // is not valid for operators though, where an inout parameter does not
5659
+ // have an explicit inout argument.
5660
+ if (type1.getPointer () == desugar2) {
5661
+ if (!isOperator || !hasInOut ())
5662
+ return SolutionKind::Solved;
5663
+ }
5655
5664
5656
5665
// Local function to form an unsolved result.
5657
5666
auto formUnsolved = [&] {
@@ -5684,8 +5693,6 @@ ConstraintSystem::simplifyApplicableFnConstraint(
5684
5693
5685
5694
// Strip the 'ApplyFunction' off the locator.
5686
5695
// FIXME: Perhaps ApplyFunction can go away entirely?
5687
- SmallVector<LocatorPathElt, 2 > parts;
5688
- Expr *anchor = locator.getLocatorParts (parts);
5689
5696
assert (!parts.empty () && " Nonsensical applicable-function locator" );
5690
5697
assert (parts.back ().getKind () == ConstraintLocator::ApplyFunction);
5691
5698
assert (parts.back ().getNewSummaryFlags () == 0 );
@@ -5714,9 +5721,13 @@ ConstraintSystem::simplifyApplicableFnConstraint(
5714
5721
5715
5722
// For a function, bind the output and convert the argument to the input.
5716
5723
if (auto func2 = dyn_cast<FunctionType>(desugar2)) {
5724
+ ConstraintKind subKind = (isOperator
5725
+ ? ConstraintKind::OperatorArgumentConversion
5726
+ : ConstraintKind::ArgumentConversion);
5727
+
5717
5728
// The argument type must be convertible to the input type.
5718
5729
if (::matchCallArguments (
5719
- *this , func1->getParams (), func2->getParams (),
5730
+ *this , func1->getParams (), func2->getParams (), subKind,
5720
5731
outerLocator.withPathElement (ConstraintLocator::ApplyArgument))
5721
5732
.isFailure ())
5722
5733
return SolutionKind::Error;
0 commit comments