Skip to content

Commit 458fae7

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 (cherry picked from commit 71372bc)
1 parent 820ec90 commit 458fae7

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

lib/Sema/CSDiagnostics.cpp

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

24432443
Optional<ContextualTypePurpose> CTP;
24442444
// Easy case were failure has been identified as contextual already.
2445-
if (locator->isLastElement<LocatorPathElt::ContextualType>()) {
2446-
CTP = getContextualTypePurpose();
2445+
if (auto contextualTy =
2446+
locator->getLastElementAs<LocatorPathElt::ContextualType>()) {
2447+
CTP = contextualTy->getPurpose();
24472448
} else {
24482449
// Here we need to figure out where where `nil` is located.
24492450
// 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
@@ -379,15 +379,16 @@ ContextualMismatch *ContextualMismatch::create(ConstraintSystem &cs, Type lhs,
379379
/// and the contextual type.
380380
static Optional<std::tuple<ContextualTypePurpose, Type, Type>>
381381
getStructuralTypeContext(const Solution &solution, ConstraintLocator *locator) {
382-
if (locator->findLast<LocatorPathElt::ContextualType>()) {
382+
if (auto contextualTypeElt =
383+
locator->findLast<LocatorPathElt::ContextualType>()) {
383384
assert(locator->isLastElement<LocatorPathElt::ContextualType>() ||
384385
locator->isLastElement<LocatorPathElt::FunctionArgument>());
385386

386387
auto &cs = solution.getConstraintSystem();
387388
auto anchor = locator->getAnchor();
388389
auto contextualType = cs.getContextualType(anchor);
389390
auto exprType = cs.getType(anchor);
390-
return std::make_tuple(cs.getContextualTypePurpose(anchor), exprType,
391+
return std::make_tuple(contextualTypeElt->getPurpose(), exprType,
391392
contextualType);
392393
} else if (auto argApplyInfo = solution.getFunctionArgApplyInfo(locator)) {
393394
return std::make_tuple(CTP_CallArgument,

lib/Sema/CSGen.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3612,8 +3612,10 @@ static bool generateWrappedPropertyTypeConstraints(
36123612
cs.addConstraint(ConstraintKind::Equal, wrapperType, initializerType, locator);
36133613
} else {
36143614
// The former wrappedValue type must be equal to the current wrapper type
3615-
cs.addConstraint(ConstraintKind::Equal, wrapperType, wrappedValueType,
3616-
cs.getConstraintLocator(locator, LocatorPathElt::ContextualType()));
3615+
cs.addConstraint(
3616+
ConstraintKind::Equal, wrapperType, wrappedValueType,
3617+
cs.getConstraintLocator(locator, LocatorPathElt::ContextualType(
3618+
CTP_ComposedPropertyWrapper)));
36173619
cs.setContextualType(typeExpr, TypeLoc::withoutLoc(wrappedValueType),
36183620
CTP_ComposedPropertyWrapper);
36193621
}

lib/Sema/CSSimplify.cpp

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

57515751
// Single expression function with implicit `return`.
5752-
if (elt->is<LocatorPathElt::ContextualType>()) {
5753-
auto anchor = locator.getAnchor();
5754-
auto contextualInfo = getContextualTypeInfo(anchor);
5755-
assert(contextualInfo &&
5756-
"Found contextual type locator without additional information");
5757-
if (contextualInfo->purpose == CTP_ReturnSingleExpr) {
5752+
if (auto contextualType = elt->getAs<LocatorPathElt::ContextualType>()) {
5753+
if (contextualType->isFor(CTP_ReturnSingleExpr)) {
57585754
increaseScore(SK_FunctionConversion);
57595755
return getTypeMatchSuccess();
57605756
}
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)