diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index daf2b8c759f..a847e54d14b 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1809,14 +1809,20 @@ bool ExtensionDecl::isWrittenWithConstraints() const { typeSig->getRequirementsWithInverses(typeReqs, typeInverseReqs); // If the (non-inverse) requirements are different between the extension and - // the original type, it's written with constraints. Note that - // the extension can only add requirements, so we need only check the size - // (not the specific requirements). - if (extReqs.size() > typeReqs.size()) { + // the original type, it's written with constraints. + if (extReqs.size() != typeReqs.size()) { return true; } - assert(extReqs.size() == typeReqs.size()); + // In case of equal number of constraints, we have to check the specific + // requirements. Extensions can end up with fewer requirements than the type + // extended, due to a same-type requirement in the extension. + // + // This mirrors the 'same' check in `ASTMangler::gatherGenericSignatureParts` + for (size_t i = 0; i < extReqs.size(); i++) { + if (extReqs[i] != typeReqs[i]) + return true; + } // If the type has no inverse requirements, there are no extra constraints // to write. diff --git a/validation-test/execution/issue-72719.swift b/validation-test/execution/issue-72719.swift new file mode 100644 index 00000000000..2f45c87be74 --- /dev/null +++ b/validation-test/execution/issue-72719.swift @@ -0,0 +1,17 @@ +// RUN: %target-swift-frontend -interpret %s +// REQUIRES: executable_test + +// This only reproduced if you provide the -interpret flag! +// https://github.com/apple/swift/issues/72719 + +protocol D {} +struct U: D, Equatable {} +class Q {} +class R {} +extension R where E == U { + struct S {} + static func a(_: T) -> R { + let x = Q>() + fatalError() + } +}