Skip to content

Commit b0a2bd6

Browse files
authored
Merge pull request #84715 from xedin/rdar-159401910
[Diagnostics] Fix a few issues with existential type mismatches
2 parents 84cda6d + 15c5662 commit b0a2bd6

File tree

3 files changed

+51
-11
lines changed

3 files changed

+51
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8750,7 +8750,36 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
87508750
return SolutionKind::Solved;
87518751
}
87528752

8753-
return matchExistentialTypes(type, protocol, kind, flags, locator);
8753+
auto result = matchExistentialTypes(type, protocol, kind, flags, locator);
8754+
8755+
if (shouldAttemptFixes() && result.isFailure()) {
8756+
auto *loc = getConstraintLocator(locator);
8757+
8758+
ArrayRef<LocatorPathElt> path = loc->getPath();
8759+
while (!path.empty()) {
8760+
if (!path.back().is<LocatorPathElt::InstanceType>())
8761+
break;
8762+
8763+
path = path.drop_back();
8764+
}
8765+
8766+
if (path.size() != loc->getPath().size()) {
8767+
loc = getConstraintLocator(loc->getAnchor(), path);
8768+
}
8769+
8770+
ConstraintFix *fix = nullptr;
8771+
if (loc->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
8772+
fix = AllowArgumentMismatch::create(*this, type, protocol, loc);
8773+
} else if (loc->isLastElement<LocatorPathElt::ContextualType>()) {
8774+
fix = ContextualMismatch::create(*this, type, protocol, loc);
8775+
}
8776+
8777+
if (fix) {
8778+
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
8779+
}
8780+
}
8781+
8782+
return result;
87548783
}
87558784

87568785
void ConstraintSystem::recordSynthesizedConformance(
@@ -9124,6 +9153,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
91249153
continue;
91259154
}
91269155

9156+
// Matching existentials could introduce constraints with `instance type`
9157+
// element at the end if the confirming type wasn't fully resolved.
9158+
if (path.back().is<LocatorPathElt::InstanceType>()) {
9159+
path.pop_back();
9160+
continue;
9161+
}
9162+
91279163
break;
91289164
}
91299165

@@ -9217,7 +9253,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
92179253
}
92189254
}
92199255

9220-
if (loc->isLastElement<LocatorPathElt::MemberRefBase>()) {
9256+
if (path.back().is<LocatorPathElt::MemberRefBase>()) {
92219257
auto *fix = ContextualMismatch::create(*this, protocolTy, type, loc);
92229258
if (!recordFix(fix))
92239259
return SolutionKind::Solved;
@@ -9227,7 +9263,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
92279263
// for example to `AnyHashable`.
92289264
if ((kind == ConstraintKind::ConformsTo ||
92299265
kind == ConstraintKind::NonisolatedConformsTo) &&
9230-
loc->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
9266+
path.back().is<LocatorPathElt::ApplyArgToParam>()) {
92319267
auto *fix = AllowArgumentMismatch::create(*this, type, protocolTy, loc);
92329268
return recordFix(fix, /*impact=*/2) ? SolutionKind::Error
92339269
: SolutionKind::Solved;

test/Constraints/existential_metatypes.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,20 @@ func parameterizedExistentials() {
120120
pt = ppt // expected-error {{cannot assign value of type 'any PP4<Int>.Type' to type 'any P4<Int>.Type'}}
121121
}
122122

123+
// https://github.com/swiftlang/swift/issues/83991
124+
123125
func testNestedMetatype() {
124126
struct S: P {}
125127

126-
func bar<T>(_ x: T) -> T.Type { type(of: x) }
127-
func foo(_ x: P.Type.Type) { }
128+
func bar<T>(_ x: T) -> T.Type { }
129+
func metaBar<T>(_ x: T) -> T.Type.Type { }
130+
func foo1(_ x: P.Type) {}
131+
func foo2(_ x: P.Type.Type) { }
128132

129-
// Make sure we don't crash.
130-
foo(bar(S.self))
133+
foo1(bar(S.self)) // expected-error {{argument type 'S.Type' does not conform to expected type 'P'}}
131134

132-
// FIXME: Bad diagnostic
133-
// https://github.com/swiftlang/swift/issues/83991
134-
foo(bar(0)) // expected-error {{failed to produce diagnostic for expression}}
135+
// Make sure we don't crash.
136+
foo2(bar(S.self))
137+
foo2(bar(0)) // expected-error {{cannot convert value of type 'Int' to expected argument type 'any P.Type'}}
138+
foo2(metaBar(0)) // expected-error {{argument type 'Int' does not conform to expected type 'P'}}
135139
}

test/Generics/inverse_generics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,5 +538,5 @@ func testYap(_ y: Yapping<NC>) {
538538
protocol Veggie: ~Copyable {}
539539
func generalized(_ x: Any.Type) {}
540540
func testMetatypes(_ t: (any Veggie & ~Copyable).Type) {
541-
generalized(t) // expected-error {{cannot convert value of type '(any Veggie & ~Copyable).Type' to expected argument type 'any Any.Type'}}
541+
generalized(t) // expected-error {{argument type 'any Veggie & ~Copyable' does not conform to expected type 'Copyable'}}
542542
}

0 commit comments

Comments
 (0)