Skip to content

Enable RequirementMachine for the standard library's protocol signatures #41200

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
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
49 changes: 27 additions & 22 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8388,7 +8388,7 @@ AbstractGenericSignatureRequest::evaluate(
auto gsbResult = buildViaGSB();

if (!rqmResult.getPointer() && !gsbResult.getPointer())
return gsbResult;
return rqmResult;

if (!rqmResult.getPointer()->isEqual(gsbResult.getPointer())) {
llvm::errs() << "RequirementMachine generic signature minimization is broken:\n";
Expand All @@ -8398,7 +8398,7 @@ AbstractGenericSignatureRequest::evaluate(
abort();
}

return gsbResult;
return rqmResult;
}
}
}
Expand Down Expand Up @@ -8558,7 +8558,7 @@ InferredGenericSignatureRequest::evaluate(
auto gsbResult = buildViaGSB();

if (!rqmResult.getPointer() && !gsbResult.getPointer())
return gsbResult;
return rqmResult;

if (!rqmResult.getPointer()->isEqual(gsbResult.getPointer())) {
llvm::errs() << "RequirementMachine generic signature minimization is broken:\n";
Expand All @@ -8568,7 +8568,7 @@ InferredGenericSignatureRequest::evaluate(
abort();
}

return gsbResult;
return rqmResult;
}
}
}
Expand Down Expand Up @@ -8630,6 +8630,27 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
ArrayRef<Requirement>());
};

auto compare = [&](ArrayRef<Requirement> rqmResult,
ArrayRef<Requirement> gsbResult) {
if (proto->getParentModule()->isStdlibModule() &&
(proto->getName().is("Collection") ||
proto->getName().is("StringProtocol"))) {
if (rqmResult.size() > gsbResult.size())
return false;
} else {
if (rqmResult.size() != gsbResult.size())
return false;
}

return std::equal(rqmResult.begin(),
rqmResult.end(),
gsbResult.begin(),
[](const Requirement &lhs,
const Requirement &rhs) {
return lhs.getCanonical() == rhs.getCanonical();
});
};

switch (ctx.LangOpts.RequirementMachineProtocolSignatures) {
case RequirementMachineMode::Disabled:
return buildViaGSB();
Expand All @@ -8641,23 +8662,7 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
auto rqmResult = buildViaRQM();
auto gsbResult = buildViaGSB();

// For now, only compare conformance requirements, since those are the
// important ones from the ABI perspective.
SmallVector<Requirement, 2> rqmConformances;
for (auto req : rqmResult) {
if (req.getKind() == RequirementKind::Conformance)
rqmConformances.push_back(req);
}
SmallVector<Requirement, 2> gsbConformances;
for (auto req : gsbResult) {
if (req.getKind() == RequirementKind::Conformance)
gsbConformances.push_back(req);
}

if (rqmConformances.size() != gsbConformances.size() ||
!std::equal(rqmConformances.begin(),
rqmConformances.end(),
gsbConformances.begin())) {
if (!compare(rqmResult, gsbResult)) {
llvm::errs() << "RequirementMachine protocol signature minimization is broken:\n";
llvm::errs() << "Protocol: " << proto->getName() << "\n";

Expand All @@ -8672,7 +8677,7 @@ RequirementSignatureRequest::evaluate(Evaluator &evaluator,
abort();
}

return gsbResult;
return rqmResult;
}
}
}
5 changes: 5 additions & 0 deletions stdlib/cmake/modules/SwiftSource.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,11 @@ function(_compile_swift_files
list(APPEND swift_flags "-Xfrontend" "-sil-verify-all")
endif()

# The standard library and overlays are built with -requirement-machine-protocol-signatures=verify.
if(SWIFTFILE_IS_STDLIB)
list(APPEND swift_flags "-Xfrontend" "-requirement-machine-protocol-signatures=verify")
endif()

# The standard library and overlays are built resiliently when SWIFT_STDLIB_STABLE_ABI=On.
if(SWIFTFILE_IS_STDLIB AND SWIFT_STDLIB_STABLE_ABI)
list(APPEND swift_flags "-enable-library-evolution")
Expand Down
3 changes: 3 additions & 0 deletions test/Generics/concrete_conformances_in_protocol.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-protocol-signatures=verify 2>&1 | %FileCheck %s

// rdar://problem/88135912
// XFAIL: *

protocol P {
associatedtype T
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ Subscript MutableCollection.subscript(_:) has generic signature change from <Sel
// FixedWidthInteger instead.
Func SignedInteger.&+(_:_:) has been removed
Func SignedInteger.&-(_:_:) has been removed

// The GenericSignatureBuilder would produce redundant same-type requirements in the minimized signature; these are now gone.

Protocol Collection has generic signature change from <Self : Swift.Sequence, Self.Element == Self.SubSequence.Element, Self.Index : Swift.Comparable, Self.Index == Self.Indices.Element, Self.Indices : Swift.Collection, Self.Indices == Self.Indices.SubSequence, Self.SubSequence : Swift.Collection, Self.SubSequence == Self.SubSequence.SubSequence, Self.Indices.Element == Self.Indices.Index, Self.Indices.Index == Self.SubSequence.Index, Self.SubSequence.Index == Self.Indices.Indices.Element, Self.Indices.Indices.Element == Self.Indices.Indices.Index, Self.Indices.Indices.Index == Self.SubSequence.Indices.Element, Self.SubSequence.Indices.Element == Self.SubSequence.Indices.Index, Self.SubSequence.Indices.Index == Self.SubSequence.Indices.Indices.Element, Self.SubSequence.Indices.Indices.Element == Self.SubSequence.Indices.Indices.Index> to <Self : Swift.Sequence, Self.Element == Self.SubSequence.Element, Self.Index : Swift.Comparable, Self.Index == Self.Indices.Element, Self.Indices : Swift.Collection, Self.Indices == Self.Indices.SubSequence, Self.SubSequence : Swift.Collection, Self.SubSequence == Self.SubSequence.SubSequence, Self.Indices.Element == Self.Indices.Index, Self.Indices.Index == Self.SubSequence.Index>

Protocol StringProtocol has generic signature change from <Self : Swift.BidirectionalCollection, Self : Swift.Comparable, Self : Swift.ExpressibleByStringInterpolation, Self : Swift.Hashable, Self : Swift.LosslessStringConvertible, Self : Swift.TextOutputStream, Self : Swift.TextOutputStreamable, Self.Element == Swift.Character, Self.Index == Swift.String.Index, Self.StringInterpolation == Swift.DefaultStringInterpolation, Self.SubSequence : Swift.StringProtocol, Self.UTF16View : Swift.BidirectionalCollection, Self.UTF8View : Swift.Collection, Self.UnicodeScalarView : Swift.BidirectionalCollection, Self.UTF16View.Element == Swift.UInt16, Self.UTF16View.Index == Swift.String.Index, Self.UTF8View.Element == Swift.UInt8, Self.UTF8View.Index == Swift.String.Index, Self.UnicodeScalarView.Element == Swift.Unicode.Scalar, Self.UnicodeScalarView.Index == Swift.String.Index, Self.SubSequence.UTF16View.Index == Swift.String.Index, Self.SubSequence.UTF8View.Index == Swift.String.Index, Self.SubSequence.UnicodeScalarView.Index == Swift.String.Index> to <Self : Swift.BidirectionalCollection, Self : Swift.Comparable, Self : Swift.ExpressibleByStringInterpolation, Self : Swift.Hashable, Self : Swift.LosslessStringConvertible, Self : Swift.TextOutputStream, Self : Swift.TextOutputStreamable, Self.Element == Swift.Character, Self.Index == Swift.String.Index, Self.StringInterpolation == Swift.DefaultStringInterpolation, Self.SubSequence : Swift.StringProtocol, Self.UTF16View : Swift.BidirectionalCollection, Self.UTF8View : Swift.Collection, Self.UnicodeScalarView : Swift.BidirectionalCollection, Self.UTF16View.Element == Swift.UInt16, Self.UTF16View.Index == Swift.String.Index, Self.UTF8View.Element == Swift.UInt8, Self.UTF8View.Index == Swift.String.Index, Self.UnicodeScalarView.Element == Swift.Unicode.Scalar, Self.UnicodeScalarView.Index == Swift.String.Index>
6 changes: 6 additions & 0 deletions test/api-digester/stability-stdlib-abi-without-asserts.test
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,10 @@ Enum Never has added a conformance to an existing protocol Identifiable
Func SignedInteger.&+(_:_:) has been removed
Func SignedInteger.&-(_:_:) has been removed

// The GenericSignatureBuilder would produce redundant same-type requirements in the minimized signature; these are now gone.

Protocol Collection has generic signature change from <Self : Swift.Sequence, Self.Element == Self.SubSequence.Element, Self.Index : Swift.Comparable, Self.Index == Self.Indices.Element, Self.Indices : Swift.Collection, Self.Indices == Self.Indices.SubSequence, Self.SubSequence : Swift.Collection, Self.SubSequence == Self.SubSequence.SubSequence, Self.Indices.Element == Self.Indices.Index, Self.Indices.Index == Self.SubSequence.Index, Self.SubSequence.Index == Self.Indices.Indices.Element, Self.Indices.Indices.Element == Self.Indices.Indices.Index, Self.Indices.Indices.Index == Self.SubSequence.Indices.Element, Self.SubSequence.Indices.Element == Self.SubSequence.Indices.Index, Self.SubSequence.Indices.Index == Self.SubSequence.Indices.Indices.Element, Self.SubSequence.Indices.Indices.Element == Self.SubSequence.Indices.Indices.Index> to <Self : Swift.Sequence, Self.Element == Self.SubSequence.Element, Self.Index : Swift.Comparable, Self.Index == Self.Indices.Element, Self.Indices : Swift.Collection, Self.Indices == Self.Indices.SubSequence, Self.SubSequence : Swift.Collection, Self.SubSequence == Self.SubSequence.SubSequence, Self.Indices.Element == Self.Indices.Index, Self.Indices.Index == Self.SubSequence.Index>

Protocol StringProtocol has generic signature change from <Self : Swift.BidirectionalCollection, Self : Swift.Comparable, Self : Swift.ExpressibleByStringInterpolation, Self : Swift.Hashable, Self : Swift.LosslessStringConvertible, Self : Swift.TextOutputStream, Self : Swift.TextOutputStreamable, Self.Element == Swift.Character, Self.Index == Swift.String.Index, Self.StringInterpolation == Swift.DefaultStringInterpolation, Self.SubSequence : Swift.StringProtocol, Self.UTF16View : Swift.BidirectionalCollection, Self.UTF8View : Swift.Collection, Self.UnicodeScalarView : Swift.BidirectionalCollection, Self.UTF16View.Element == Swift.UInt16, Self.UTF16View.Index == Swift.String.Index, Self.UTF8View.Element == Swift.UInt8, Self.UTF8View.Index == Swift.String.Index, Self.UnicodeScalarView.Element == Swift.Unicode.Scalar, Self.UnicodeScalarView.Index == Swift.String.Index, Self.SubSequence.UTF16View.Index == Swift.String.Index, Self.SubSequence.UTF8View.Index == Swift.String.Index, Self.SubSequence.UnicodeScalarView.Index == Swift.String.Index> to <Self : Swift.BidirectionalCollection, Self : Swift.Comparable, Self : Swift.ExpressibleByStringInterpolation, Self : Swift.Hashable, Self : Swift.LosslessStringConvertible, Self : Swift.TextOutputStream, Self : Swift.TextOutputStreamable, Self.Element == Swift.Character, Self.Index == Swift.String.Index, Self.StringInterpolation == Swift.DefaultStringInterpolation, Self.SubSequence : Swift.StringProtocol, Self.UTF16View : Swift.BidirectionalCollection, Self.UTF8View : Swift.Collection, Self.UnicodeScalarView : Swift.BidirectionalCollection, Self.UTF16View.Element == Swift.UInt16, Self.UTF16View.Index == Swift.String.Index, Self.UTF8View.Element == Swift.UInt8, Self.UTF8View.Index == Swift.String.Index, Self.UnicodeScalarView.Element == Swift.Unicode.Scalar, Self.UnicodeScalarView.Index == Swift.String.Index>

// *** DO NOT DISABLE OR XFAIL THIS TEST. *** (See comment above.)