Skip to content

RequirementMachine: Fix potential 'pollution' from installing an invalid requirement machine #68055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 15 additions & 3 deletions lib/AST/RequirementMachine/HomotopyReduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,10 @@ void RewriteSystem::minimizeRewriteSystem(const PropertyMap &map) {
}

/// Returns flags indicating if the rewrite system has unresolved or
/// conflicting rules in our minimization domain.
/// conflicting rules in our minimization domain. If these flags are
/// set, we do not install this rewrite system in the rewrite context
/// after minimization. Instead, we will rebuild a new rewrite system
/// from the minimized requirements.
GenericSignatureErrors RewriteSystem::getErrors() const {
assert(Complete);
assert(Minimized);
Expand All @@ -668,10 +671,19 @@ GenericSignatureErrors RewriteSystem::getErrors() const {
if (rule.isConflicting() || rule.isRecursive())
result |= GenericSignatureErrorFlags::HasInvalidRequirements;

if (!rule.isRedundant())
if (auto property = rule.isPropertyRule())
if (!rule.isRedundant()) {
if (auto property = rule.isPropertyRule()) {
if (property->getKind() == Symbol::Kind::ConcreteConformance)
result |= GenericSignatureErrorFlags::HasConcreteConformances;

if (property->hasSubstitutions()) {
for (auto t : property->getSubstitutions()) {
if (t.containsUnresolvedSymbols())
result |= GenericSignatureErrorFlags::HasInvalidRequirements;
}
}
}
}
}

return result;
Expand Down
22 changes: 22 additions & 0 deletions test/Generics/rdar113943346.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// RUN: %target-typecheck-verify-swift

struct G<T, U, V> {}

struct Foo<T> {}

// The first extension has the same generic signature as the
// second extension, because we drop the invalid requirement.
//
// But the rewrite system used for minimization with the first
// extension should not be installed in the rewrite context,
// because of this invalid requirement.

extension G where T == Foo<V.Bar>, U == Foo<Int> {}
// expected-error@-1 {{'Bar' is not a member type of type 'V'}}

extension G where U == Foo<Int> {
func f() {
print(T.self)
print(U.self)
}
}