Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8750,7 +8750,27 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
return SolutionKind::Solved;
}

return matchExistentialTypes(type, protocol, kind, flags, locator);
auto result = matchExistentialTypes(type, protocol, kind, flags, locator);

if (shouldAttemptFixes() && result.isFailure()) {
auto *loc = getConstraintLocator(locator);

if (loc->isLastElement<LocatorPathElt::InstanceType>())
loc = getConstraintLocator(loc->getAnchor(), loc->getPath().drop_back());

ConstraintFix *fix = nullptr;
if (loc->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
fix = AllowArgumentMismatch::create(*this, type, protocol, loc);
} else if (loc->isLastElement<LocatorPathElt::ContextualType>()) {
fix = ContextualMismatch::create(*this, type, protocol, loc);
}

if (fix) {
return recordFix(fix) ? SolutionKind::Error : SolutionKind::Solved;
}
}

return result;
}

void ConstraintSystem::recordSynthesizedConformance(
Expand Down Expand Up @@ -9124,6 +9144,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
continue;
}

// Matching existentials could introduce constraints with `instance type`
// element at the end if the confirming type wasn't fully resolved.
if (path.back().is<LocatorPathElt::InstanceType>()) {
path.pop_back();
continue;
}

break;
}

Expand Down Expand Up @@ -9217,7 +9244,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
}
}

if (loc->isLastElement<LocatorPathElt::MemberRefBase>()) {
if (path.back().is<LocatorPathElt::MemberRefBase>()) {
auto *fix = ContextualMismatch::create(*this, protocolTy, type, loc);
if (!recordFix(fix))
return SolutionKind::Solved;
Expand All @@ -9227,7 +9254,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
// for example to `AnyHashable`.
if ((kind == ConstraintKind::ConformsTo ||
kind == ConstraintKind::NonisolatedConformsTo) &&
loc->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
path.back().is<LocatorPathElt::ApplyArgToParam>()) {
auto *fix = AllowArgumentMismatch::create(*this, type, protocolTy, loc);
return recordFix(fix, /*impact=*/2) ? SolutionKind::Error
: SolutionKind::Solved;
Expand Down
14 changes: 8 additions & 6 deletions test/Constraints/existential_metatypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,18 @@ func parameterizedExistentials() {
pt = ppt // expected-error {{cannot assign value of type 'any PP4<Int>.Type' to type 'any P4<Int>.Type'}}
}

// https://github.com/swiftlang/swift/issues/83991

func testNestedMetatype() {
struct S: P {}

func bar<T>(_ x: T) -> T.Type { type(of: x) }
func foo(_ x: P.Type.Type) { }
func foo1(_ x: P.Type) {}
func foo2(_ x: P.Type.Type) { }

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

// FIXME: Bad diagnostic
// https://github.com/swiftlang/swift/issues/83991
foo(bar(0)) // expected-error {{failed to produce diagnostic for expression}}
// Make sure we don't crash.
foo2(bar(S.self))
foo2(bar(0)) // expected-error {{cannot convert value of type 'Int' to expected argument type 'any P.Type'}}
}
2 changes: 1 addition & 1 deletion test/Generics/inverse_generics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -538,5 +538,5 @@ func testYap(_ y: Yapping<NC>) {
protocol Veggie: ~Copyable {}
func generalized(_ x: Any.Type) {}
func testMetatypes(_ t: (any Veggie & ~Copyable).Type) {
generalized(t) // expected-error {{cannot convert value of type '(any Veggie & ~Copyable).Type' to expected argument type 'any Any.Type'}}
generalized(t) // expected-error {{argument type 'any Veggie & ~Copyable' does not conform to expected type 'Copyable'}}
}