@@ -4282,7 +4282,8 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
4282
4282
if (!path.empty()) {
4283
4283
auto last = path.back();
4284
4284
4285
- if (last.is<LocatorPathElt::ApplyArgToParam>()) {
4285
+ if (last.is<LocatorPathElt::ApplyArgToParam>() ||
4286
+ last.is<LocatorPathElt::AutoclosureResult>()) {
4286
4287
auto proto = protoDecl->getDeclaredInterfaceType();
4287
4288
// Impact is 2 here because there are two failures
4288
4289
// 1 - missing conformance and 2 - incorrect argument type.
@@ -4310,6 +4311,15 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
4310
4311
break;
4311
4312
}
4312
4313
4314
+ if ((isExpr<ArrayExpr>(anchor) || isExpr<DictionaryExpr>(anchor)) &&
4315
+ last.is<LocatorPathElt::TupleElement>()) {
4316
+ auto *fix = CollectionElementContextualMismatch::create(
4317
+ *this, type1, type2, getConstraintLocator(anchor, path));
4318
+ if (recordFix(fix, /*impact=*/2))
4319
+ return getTypeMatchFailure(locator);
4320
+ break;
4321
+ }
4322
+
4313
4323
// TODO(diagnostics): If there are any requirement failures associated
4314
4324
// with result types which are part of a function type conversion,
4315
4325
// let's record general conversion mismatch in order for it to capture
@@ -4979,8 +4989,18 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
4979
4989
4980
4990
// First, let's check whether it has been determined that
4981
4991
// it was incorrect to use `?` in this position.
4982
- if (cs.hasFixFor(cs.getConstraintLocator(subExpr), FixKind::RemoveUnwrap))
4992
+ if (cs.hasFixFor(cs.getConstraintLocator(subExpr), FixKind::RemoveUnwrap)) {
4993
+ if (auto *typeVar =
4994
+ fromType->getOptionalObjectType()->getAs<TypeVariableType>()) {
4995
+ // If the optional chain is invalid let's unwrap optional and
4996
+ // re-introduce the constraint to be solved later once both sides
4997
+ // are sufficiently resolved, this would allow to diagnose not only
4998
+ // the invalid unwrap but an invalid conversion (if any) as well.
4999
+ cs.addConstraint(matchKind, typeVar, toType,
5000
+ cs.getConstraintLocator(locator));
5001
+ }
4983
5002
return true;
5003
+ }
4984
5004
4985
5005
auto type = cs.getType(subExpr);
4986
5006
// If the type of sub-expression is optional, type of the
@@ -5775,6 +5795,41 @@ bool ConstraintSystem::repairFailures(
5775
5795
break;
5776
5796
}
5777
5797
5798
+ // There is no subtyping between object types of inout argument/parameter.
5799
+ if (auto argConv = path.back().getAs<LocatorPathElt::ApplyArgToParam>()) {
5800
+ // Attempt conversions first.
5801
+ if (hasAnyRestriction())
5802
+ break;
5803
+
5804
+ // Unwraps are allowed to preserve l-valueness so we can suggest
5805
+ // them here.
5806
+ if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind,
5807
+ conversionsOrFixes, locator))
5808
+ return true;
5809
+
5810
+ auto *loc = getConstraintLocator(locator);
5811
+
5812
+ auto result = matchTypes(lhs, rhs, ConstraintKind::Conversion,
5813
+ TMF_ApplyingFix, locator);
5814
+
5815
+ ConstraintFix *fix = nullptr;
5816
+ if (result.isFailure()) {
5817
+ // If this is a "destination" argument to a mutating operator
5818
+ // like `+=`, let's consider it contextual and only attempt
5819
+ // to fix type mismatch on the "source" right-hand side of
5820
+ // such operators.
5821
+ if (isOperatorArgument(loc) && argConv->getArgIdx() == 0)
5822
+ break;
5823
+
5824
+ fix = AllowArgumentMismatch::create(*this, lhs, rhs, loc);
5825
+ } else {
5826
+ fix = AllowInOutConversion::create(*this, lhs, rhs, loc);
5827
+ }
5828
+
5829
+ conversionsOrFixes.push_back(fix);
5830
+ break;
5831
+ }
5832
+
5778
5833
// If this is a problem with result type of a subscript setter,
5779
5834
// let's re-attempt to repair without l-value conversion in the
5780
5835
// locator to fix underlying type mismatch.
@@ -5794,7 +5849,7 @@ bool ConstraintSystem::repairFailures(
5794
5849
break;
5795
5850
}
5796
5851
5797
- LLVM_FALLTHROUGH ;
5852
+ break ;
5798
5853
}
5799
5854
5800
5855
case ConstraintLocator::ApplyArgToParam: {
@@ -5874,52 +5929,6 @@ bool ConstraintSystem::repairFailures(
5874
5929
if (repairByTreatingRValueAsLValue(lhs, rhs))
5875
5930
break;
5876
5931
5877
- // If the problem is related to missing unwrap, there is a special
5878
- // fix for that.
5879
- if (lhs->getOptionalObjectType() && !rhs->getOptionalObjectType()) {
5880
- // If this is an attempt to check whether optional conforms to a
5881
- // particular protocol, let's do that before attempting to force
5882
- // unwrap the optional.
5883
- if (hasConversionOrRestriction(ConversionRestrictionKind::Existential))
5884
- break;
5885
-
5886
- auto result = matchTypes(lhs->getOptionalObjectType(), rhs, matchKind,
5887
- TMF_ApplyingFix, locator);
5888
-
5889
- if (result.isSuccess()) {
5890
- conversionsOrFixes.push_back(
5891
- ForceOptional::create(*this, lhs, rhs, loc));
5892
- break;
5893
- }
5894
- }
5895
-
5896
- // There is no subtyping between object types of inout argument/parameter.
5897
- if (elt.getKind() == ConstraintLocator::LValueConversion) {
5898
- auto result = matchTypes(lhs, rhs, ConstraintKind::Conversion,
5899
- TMF_ApplyingFix, locator);
5900
-
5901
- ConstraintFix *fix = nullptr;
5902
- if (result.isFailure()) {
5903
- // If this is a "destination" argument to a mutating operator
5904
- // like `+=`, let's consider it contextual and only attempt
5905
- // to fix type mismatch on the "source" right-hand side of
5906
- // such operators.
5907
- if (isOperatorArgument(loc) &&
5908
- loc->findLast<LocatorPathElt::ApplyArgToParam>()->getArgIdx() == 0)
5909
- break;
5910
-
5911
- fix = AllowArgumentMismatch::create(*this, lhs, rhs, loc);
5912
- } else {
5913
- fix = AllowInOutConversion::create(*this, lhs, rhs, loc);
5914
- }
5915
-
5916
- conversionsOrFixes.push_back(fix);
5917
- break;
5918
- }
5919
-
5920
- if (elt.getKind() != ConstraintLocator::ApplyArgToParam)
5921
- break;
5922
-
5923
5932
// If argument in l-value type and parameter is `inout` or a pointer,
5924
5933
// let's see if it's generic parameter matches and suggest adding explicit
5925
5934
// `&`.
@@ -6046,7 +6055,7 @@ bool ConstraintSystem::repairFailures(
6046
6055
6047
6056
if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
6048
6057
locator))
6049
- break ;
6058
+ return true ;
6050
6059
6051
6060
{
6052
6061
auto *calleeLocator = getCalleeLocator(loc);
@@ -6856,9 +6865,28 @@ bool ConstraintSystem::repairFailures(
6856
6865
if (!path.empty() && path.back().is<LocatorPathElt::PackElement>())
6857
6866
path.pop_back();
6858
6867
6859
- if (!path.empty() && path.back().is<LocatorPathElt::AnyRequirement>()) {
6860
- return repairFailures(lhs, rhs, matchKind, flags, conversionsOrFixes,
6861
- getConstraintLocator(anchor, path));
6868
+ if (!path.empty()) {
6869
+ if (path.back().is<LocatorPathElt::AnyRequirement>()) {
6870
+ return repairFailures(lhs, rhs, matchKind, flags, conversionsOrFixes,
6871
+ getConstraintLocator(anchor, path));
6872
+ }
6873
+
6874
+ if (auto argConv = path.back().getAs<LocatorPathElt::ApplyArgToParam>()) {
6875
+ auto argIdx = argConv->getArgIdx();
6876
+ auto paramIdx = argConv->getParamIdx();
6877
+
6878
+ auto *argLoc = getConstraintLocator(anchor, path);
6879
+ if (auto overload = findSelectedOverloadFor(getCalleeLocator(argLoc))) {
6880
+ auto *overloadTy =
6881
+ simplifyType(overload->boundType)->castTo<FunctionType>();
6882
+ auto *argList = getArgumentList(argLoc);
6883
+ ASSERT(argList);
6884
+ conversionsOrFixes.push_back(AllowArgumentMismatch::create(
6885
+ *this, getType(argList->getExpr(argIdx)),
6886
+ overloadTy->getParams()[paramIdx].getPlainType(), argLoc));
6887
+ return true;
6888
+ }
6889
+ }
6862
6890
}
6863
6891
6864
6892
// When the solver sets `TMF_MatchingGenericArguments` it means
@@ -11410,6 +11438,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
11410
11438
// `key path` constraint can't be retired until all components
11411
11439
// are simplified.
11412
11440
addTypeVariableConstraintsToWorkList(memberTypeVar);
11441
+ } else if (locator->getAnchor().is<Expr *>() &&
11442
+ !getSemanticsProvidingParentExpr(
11443
+ getAsExpr(locator->getAnchor()))) {
11444
+ // If there are no contextual expressions that could provide
11445
+ // a type for the member type variable, let's default it to
11446
+ // a placeholder eagerly so it could be propagated to the
11447
+ // pattern if necessary.
11448
+ recordTypeVariablesAsHoles(memberTypeVar);
11413
11449
} else if (locator->isLastElement<LocatorPathElt::PatternMatch>()) {
11414
11450
// Let's handle member patterns specifically because they use
11415
11451
// equality instead of argument application constraint, so allowing
0 commit comments