@@ -4282,7 +4282,8 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
42824282 if (!path.empty()) {
42834283 auto last = path.back();
42844284
4285- if (last.is<LocatorPathElt::ApplyArgToParam>()) {
4285+ if (last.is<LocatorPathElt::ApplyArgToParam>() ||
4286+ last.is<LocatorPathElt::AutoclosureResult>()) {
42864287 auto proto = protoDecl->getDeclaredInterfaceType();
42874288 // Impact is 2 here because there are two failures
42884289 // 1 - missing conformance and 2 - incorrect argument type.
@@ -4310,6 +4311,15 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
43104311 break;
43114312 }
43124313
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+
43134323 // TODO(diagnostics): If there are any requirement failures associated
43144324 // with result types which are part of a function type conversion,
43154325 // let's record general conversion mismatch in order for it to capture
@@ -4979,8 +4989,18 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
49794989
49804990 // First, let's check whether it has been determined that
49814991 // 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+ }
49835002 return true;
5003+ }
49845004
49855005 auto type = cs.getType(subExpr);
49865006 // If the type of sub-expression is optional, type of the
@@ -5775,6 +5795,41 @@ bool ConstraintSystem::repairFailures(
57755795 break;
57765796 }
57775797
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+
57785833 // If this is a problem with result type of a subscript setter,
57795834 // let's re-attempt to repair without l-value conversion in the
57805835 // locator to fix underlying type mismatch.
@@ -5794,7 +5849,7 @@ bool ConstraintSystem::repairFailures(
57945849 break;
57955850 }
57965851
5797- LLVM_FALLTHROUGH ;
5852+ break ;
57985853 }
57995854
58005855 case ConstraintLocator::ApplyArgToParam: {
@@ -5874,52 +5929,6 @@ bool ConstraintSystem::repairFailures(
58745929 if (repairByTreatingRValueAsLValue(lhs, rhs))
58755930 break;
58765931
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-
59235932 // If argument in l-value type and parameter is `inout` or a pointer,
59245933 // let's see if it's generic parameter matches and suggest adding explicit
59255934 // `&`.
@@ -6046,7 +6055,7 @@ bool ConstraintSystem::repairFailures(
60466055
60476056 if (repairViaOptionalUnwrap(*this, lhs, rhs, matchKind, conversionsOrFixes,
60486057 locator))
6049- break ;
6058+ return true ;
60506059
60516060 {
60526061 auto *calleeLocator = getCalleeLocator(loc);
@@ -6856,9 +6865,28 @@ bool ConstraintSystem::repairFailures(
68566865 if (!path.empty() && path.back().is<LocatorPathElt::PackElement>())
68576866 path.pop_back();
68586867
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+ }
68626890 }
68636891
68646892 // When the solver sets `TMF_MatchingGenericArguments` it means
@@ -11410,6 +11438,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1141011438 // `key path` constraint can't be retired until all components
1141111439 // are simplified.
1141211440 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);
1141311449 } else if (locator->isLastElement<LocatorPathElt::PatternMatch>()) {
1141411450 // Let's handle member patterns specifically because they use
1141511451 // equality instead of argument application constraint, so allowing
0 commit comments