@@ -3007,12 +3007,9 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
30073007 return getTypeMatchFailure(locator);
30083008 }
30093009
3010- bool forClosureInArgumentPosition = false;
3011- if (auto last = locator.last()) {
3012- forClosureInArgumentPosition =
3013- last->is<LocatorPathElt::ApplyArgToParam>() &&
3014- isa<ClosureExpr>(locator.trySimplifyToExpr());
3015- }
3010+ bool forClosureInArgumentPosition =
3011+ locator.endsWith<LocatorPathElt::ApplyArgToParam>() &&
3012+ isa<ClosureExpr>(locator.trySimplifyToExpr());
30163013
30173014 // Since it's possible to infer `async` from the body of a
30183015 // closure, score for sync -> async mismatch is increased
@@ -4255,12 +4252,10 @@ ConstraintSystem::matchTypesBindTypeVar(
42554252 // to a particular type e.g. `l-value` or `inout`.
42564253 auto fixReferenceMismatch = [&](TypeVariableType *typeVar,
42574254 Type type) -> bool {
4258- if (auto last = locator.last()) {
4259- if (last->is<LocatorPathElt::ContextualType>()) {
4260- auto *fix = IgnoreContextualType::create(*this, typeVar, type,
4261- getConstraintLocator(locator));
4262- return !recordFix(fix);
4263- }
4255+ if (locator.endsWith<LocatorPathElt::ContextualType>()) {
4256+ auto *fix = IgnoreContextualType::create(*this, typeVar, type,
4257+ getConstraintLocator(locator));
4258+ return !recordFix(fix);
42644259 }
42654260
42664261 return false;
@@ -4561,8 +4556,7 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
45614556 // `let _: Bool = try? foo()` and `foo()` produces `Int`
45624557 // we should diagnose it as type mismatch instead of missing unwrap.
45634558 bool possibleContextualMismatch = [&]() {
4564- auto last = locator.last();
4565- if (!(last && last->is<LocatorPathElt::ContextualType>()))
4559+ if (!locator.endsWith<LocatorPathElt::ContextualType>())
45664560 return false;
45674561
45684562 // If the contextual type is optional as well, it's definitely a
@@ -4695,8 +4689,7 @@ repairViaOptionalUnwrap(ConstraintSystem &cs, Type fromType, Type toType,
46954689 // variable e.g. `T?`, there can be no optional mismatch
46964690 // because `T` could be bound to an optional of any depth.
46974691 if (isa<OptionalEvaluationExpr>(anchor) && toUnwraps > 0) {
4698- auto last = locator.last();
4699- if (last && last->is<LocatorPathElt::ContextualType>() &&
4692+ if (locator.endsWith<LocatorPathElt::ContextualType>() &&
47004693 toObjectType->is<TypeVariableType>())
47014694 return false;
47024695 }
@@ -6664,13 +6657,11 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
66646657 // producing diagnostics for both missing conformance and
66656658 // invalid element type.
66666659 if (shouldAttemptFixes()) {
6667- if (auto last = locator.last()) {
6668- if (last->is<LocatorPathElt::SequenceElementType>() &&
6669- desugar1->is<DependentMemberType>() &&
6670- !desugar1->hasTypeVariable()) {
6671- recordPotentialHole(typeVar2);
6672- return getTypeMatchSuccess();
6673- }
6660+ if (locator.endsWith<LocatorPathElt::SequenceElementType>() &&
6661+ desugar1->is<DependentMemberType>() &&
6662+ !desugar1->hasTypeVariable()) {
6663+ recordPotentialHole(typeVar2);
6664+ return getTypeMatchSuccess();
66746665 }
66756666 }
66766667
@@ -6911,35 +6902,33 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
69116902 ConstraintLocatorBuilder location{locator};
69126903 // Look through all value-to-optional promotions to allow
69136904 // conversions like Double -> CGFloat?? and vice versa.
6914- if (auto last = location.last()) {
6915- // T -> Optional<T>
6916- if (last->is<LocatorPathElt::OptionalPayload>()) {
6917- SmallVector<LocatorPathElt, 4> path;
6918- auto anchor = location.getLocatorParts(path);
6919-
6920- // An attempt at Double/CGFloat conversion through
6921- // optional chaining. This is not supported at the
6922- // moment because solution application doesn't know
6923- // how to map Double to/from CGFloat through optionals.
6924- if (isExpr<OptionalEvaluationExpr>(anchor)) {
6925- if (!shouldAttemptFixes())
6926- return getTypeMatchFailure(locator);
6905+ // T -> Optional<T>
6906+ if (location.endsWith<LocatorPathElt::OptionalPayload>()) {
6907+ SmallVector<LocatorPathElt, 4> path;
6908+ auto anchor = location.getLocatorParts(path);
6909+
6910+ // An attempt at Double/CGFloat conversion through
6911+ // optional chaining. This is not supported at the
6912+ // moment because solution application doesn't know
6913+ // how to map Double to/from CGFloat through optionals.
6914+ if (isExpr<OptionalEvaluationExpr>(anchor)) {
6915+ if (!shouldAttemptFixes())
6916+ return getTypeMatchFailure(locator);
69276917
6928- conversionsOrFixes.push_back(ContextualMismatch::create(
6929- *this, nominal1, nominal2, getConstraintLocator(locator)));
6930- break;
6931- }
6918+ conversionsOrFixes.push_back(ContextualMismatch::create(
6919+ *this, nominal1, nominal2, getConstraintLocator(locator)));
6920+ break;
6921+ }
69326922
6933- // Drop all of the applied `value-to-optional` promotions.
6934- path.erase(llvm::remove_if(
6935- path,
6936- [](const LocatorPathElt &elt) {
6937- return elt.is<LocatorPathElt::OptionalPayload>();
6938- }),
6939- path.end());
6923+ // Drop all of the applied `value-to-optional` promotions.
6924+ path.erase(llvm::remove_if(
6925+ path,
6926+ [](const LocatorPathElt &elt) {
6927+ return elt.is<LocatorPathElt::OptionalPayload>();
6928+ }),
6929+ path.end());
69406930
6941- location = getConstraintLocator(anchor, path);
6942- }
6931+ location = getConstraintLocator(anchor, path);
69436932 }
69446933
69456934 // Support implicit Double<->CGFloat conversions only for
@@ -8122,12 +8111,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
81228111 // as well, and if so, avoid producing a fix here, because
81238112 // contextual mismatch mentions the source/destination
81248113 // types of the assignment.
8125- if (auto last = locator.last()) {
8126- if (last->is<LocatorPathElt::FunctionResult>() &&
8127- hasFixFor(getConstraintLocator(anchor,
8128- LocatorPathElt::FunctionArgument())))
8129- return SolutionKind::Solved;
8130- }
8114+ if (locator.endsWith<LocatorPathElt::FunctionResult>() &&
8115+ hasFixFor(
8116+ getConstraintLocator(anchor, LocatorPathElt::FunctionArgument())))
8117+ return SolutionKind::Solved;
81318118
81328119 auto srcType = getType(assignment->getSrc());
81338120 auto dstType = getType(assignment->getDest());
@@ -8450,9 +8437,7 @@ static ConstraintFix *maybeWarnAboutExtraneousCast(
84508437 SmallVector<Type, 4> toOptionals,
84518438 ConstraintSystem::TypeMatchOptions flags,
84528439 ConstraintLocatorBuilder locator) {
8453-
8454- auto last = locator.last();
8455- if (last && last->is<LocatorPathElt::GenericArgument>())
8440+ if (locator.endsWith<LocatorPathElt::GenericArgument>())
84568441 return nullptr;
84578442
84588443 // Both types have to be fixed.
@@ -11906,11 +11891,9 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint(
1190611891
1190711892 // When locator points to a KeyPathDynamicMemberLookup, reject the
1190811893 // key path application.
11909- auto last = locator.last();
11910- if (last && last->isKeyPathDynamicMember()) {
11894+ if (locator.endsWith<LocatorPathElt::KeyPathDynamicMember>())
1191111895 return SolutionKind::Error;
11912- }
11913-
11896+
1191411897 if (keyPathTy->isAnyKeyPath()) {
1191511898 // Read-only keypath, whose projected value is upcast to `Any?`.
1191611899 // The root type can be anything.
@@ -14157,12 +14140,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1415714140 // an l-value, it has to have an increased impact because it's either
1415814141 // a function - which is completely incorrect, or it's a get-only
1415914142 // subscript, which requires changes to declaration to become mutable.
14160- if (auto last = locator.last()) {
14161- impact += (last->is<LocatorPathElt::FunctionResult>() ||
14162- last->is<LocatorPathElt::SubscriptMember>())
14163- ? 1
14164- : 0;
14165- }
14143+ impact += (locator.endsWith<LocatorPathElt::FunctionResult>() ||
14144+ locator.endsWith<LocatorPathElt::SubscriptMember>())
14145+ ? 1
14146+ : 0;
1416614147
1416714148 return recordFix(fix, impact) ? SolutionKind::Error : SolutionKind::Solved;
1416814149 }
0 commit comments