Skip to content

Commit 71372bc

Browse files
committed
[Diagnostics] Switch to use contextual purpose associated with locator
`ContextualFailure` is the main beneficiary of additional information associated with `ContextualType` element because it no longer has to query solution for "purpose" of the contextual information. Resolves: rdar://68795727
1 parent 51ff12d commit 71372bc

File tree

5 files changed

+41
-12
lines changed

5 files changed

+41
-12
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,8 +2447,9 @@ bool ContextualFailure::diagnoseConversionToNil() const {
24472447

24482448
Optional<ContextualTypePurpose> CTP;
24492449
// Easy case were failure has been identified as contextual already.
2450-
if (locator->isLastElement<LocatorPathElt::ContextualType>()) {
2451-
CTP = getContextualTypePurpose();
2450+
if (auto contextualTy =
2451+
locator->getLastElementAs<LocatorPathElt::ContextualType>()) {
2452+
CTP = contextualTy->getPurpose();
24522453
} else {
24532454
// Here we need to figure out where where `nil` is located.
24542455
// It could be e.g. an argument to a subscript/call, assignment

lib/Sema/CSDiagnostics.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,11 @@ class ContextualFailure : public FailureDiagnostic {
594594
ConstraintLocator *locator)
595595
: ContextualFailure(
596596
solution,
597-
solution.getConstraintSystem().getContextualTypePurpose(
598-
locator->getAnchor()),
597+
locator->isForContextualType()
598+
? locator->castLastElementTo<LocatorPathElt::ContextualType>()
599+
.getPurpose()
600+
: solution.getConstraintSystem().getContextualTypePurpose(
601+
locator->getAnchor()),
599602
lhs, rhs, locator) {}
600603

601604
ContextualFailure(const Solution &solution, ContextualTypePurpose purpose,

lib/Sema/CSFix.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,15 +391,16 @@ AllowWrappedValueMismatch *AllowWrappedValueMismatch::create(ConstraintSystem &c
391391
/// and the contextual type.
392392
static Optional<std::tuple<ContextualTypePurpose, Type, Type>>
393393
getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
394-
if (locator->findLast<LocatorPathElt::ContextualType>()) {
394+
if (auto contextualTypeElt =
395+
locator->findLast<LocatorPathElt::ContextualType>()) {
395396
assert(locator->isLastElement<LocatorPathElt::ContextualType>() ||
396397
locator->isLastElement<LocatorPathElt::FunctionArgument>());
397398

398399
auto &cs = solution.getConstraintSystem();
399400
auto anchor = locator->getAnchor();
400401
auto contextualType = cs.getContextualType(anchor);
401402
auto exprType = cs.getType(anchor);
402-
return std::make_tuple(cs.getContextualTypePurpose(anchor), exprType,
403+
return std::make_tuple(contextualTypeElt->getPurpose(), exprType,
403404
contextualType);
404405
} else if (auto argApplyInfo = solution.getFunctionArgApplyInfo(locator)) {
405406
return std::make_tuple(CTP_CallArgument,

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5754,12 +5754,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
57545754
}
57555755

57565756
// Single expression function with implicit `return`.
5757-
if (elt->is<LocatorPathElt::ContextualType>()) {
5758-
auto anchor = locator.getAnchor();
5759-
auto contextualInfo = getContextualTypeInfo(anchor);
5760-
assert(contextualInfo &&
5761-
"Found contextual type locator without additional information");
5762-
if (contextualInfo->purpose == CTP_ReturnSingleExpr) {
5757+
if (auto contextualType = elt->getAs<LocatorPathElt::ContextualType>()) {
5758+
if (contextualType->isFor(CTP_ReturnSingleExpr)) {
57635759
increaseScore(SK_FunctionConversion);
57645760
return getTypeMatchSuccess();
57655761
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
2+
// REQUIRES: objc_interop
3+
// REQUIRES: OS=macosx
4+
5+
import SwiftUI
6+
7+
struct UnitVolumeView: View {
8+
var measurement: Measurement<Unit>
9+
10+
var body: some View {
11+
Text("")
12+
}
13+
}
14+
struct UnitView_Previews: PreviewProvider {
15+
static var previews: some View {
16+
let volume: Measurement<Unit> = Measurement<UnitVolume>(value: 200, unit: UnitVolume.milliliters)
17+
// expected-error@-1 {{cannot assign value of type 'Measurement<UnitVolume>' to type 'Measurement<Unit>'}}
18+
// expected-note@-2 {{arguments to generic parameter 'UnitType' ('UnitVolume' and 'Unit') are expected to be equal}}
19+
20+
Group {
21+
ForEach(["en", "de", "fr"], id: \.self) { id in
22+
UnitVolumeView(measurement: volume)
23+
.previewLayout(PreviewLayout.sizeThatFits)
24+
.environment(\.locale, .init(identifier: id))
25+
}
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)