Skip to content

[NFC] Adopt TypeBase-isms for GenericSignature #27436

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
Sep 30, 2019

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Sep 30, 2019

Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.

@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 30, 2019

apple/swift-lldb#2022
@swift-ci please test

@@ -388,7 +388,8 @@ ValueDecl *RequirementFailure::getDeclRef() const {
do {
if (auto *parent = DC->getAsDecl()) {
if (auto *GC = parent->getAsGenericContext()) {
if (GC->getGenericSignature() != Signature)
// FIXME: Is this intending an exact match?
if (GC->getGenericSignature().getPointer() != Signature.getPointer())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xedin Should this canonicalize the generic signatures, or are we looking for an exact match here?

Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please!

@jrose-apple
Copy link
Contributor

Nitpick: because there are no subclasses, can you call it GenericSignatureImpl or signature?

@jrose-apple
Copy link
Contributor

Alternately, the indirect one could be GenericSignatureRef, like ProtocolConformanceRef.

@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 30, 2019

I lean towards GenericSignatureImpl to keep noise in the diff down.

Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase.  In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
@CodaFi CodaFi force-pushed the signed-sealed-delivered branch from c9f850a to 5a8d074 Compare September 30, 2019 21:04
@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 30, 2019

@swift-ci please smoke test

@CodaFi CodaFi closed this Sep 30, 2019
@CodaFi CodaFi reopened this Sep 30, 2019
@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 30, 2019

apple/swift-lldb#2022
@swift-ci please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Sep 30, 2019

⛵️

@CodaFi CodaFi merged commit 75670c1 into swiftlang:master Sep 30, 2019
@CodaFi CodaFi deleted the signed-sealed-delivered branch September 30, 2019 22:50
@@ -541,7 +541,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {

/// allowsOwnership() - Are variables of this type permitted to have
/// ownership attributes?
bool allowsOwnership(GenericSignature *sig=nullptr);
bool allowsOwnership(GenericSignatureImpl *sig = nullptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this a GenericSignature?

@@ -4376,15 +4377,15 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
return nullptr;
}

if (derivedClass->getGenericSignature() == nullptr &&
if (derivedClass->getGenericSignature().isNull() &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no implicit conversion to bool?

ctx.evaluator,
AbstractGenericSignatureRequest{
derivedClass->getGenericSignature(),
derivedClass->getGenericSignature().getPointer(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unwrapping should not be necessary

@@ -446,7 +446,7 @@ Type ASTBuilder::createImplFunctionType(
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
Optional<Demangle::ImplFunctionResult<Type>> errorResult,
ImplFunctionTypeFlags flags) {
GenericSignature *genericSig = nullptr;
GenericSignature genericSig = GenericSignature();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be default initialized

@@ -215,7 +215,7 @@ GenericEnvironment::mapConformanceRefIntoContext(
ProtocolConformanceRef conformance) const {
auto contextConformance = conformance.subst(conformingInterfaceType,
QueryInterfaceTypeSubstitutions(this),
LookUpConformanceInSignature(*getGenericSignature()));
LookUpConformanceInSignature(getGenericSignature().getPointer()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More interfaces to clean up

@slavapestov
Copy link
Contributor

I think we can go further here and make GenericSignature like SubstitutionMap. Instead of forwarding method calls from GenericSignature to GenericSignatureImpl with operator-> we can implement the methods on GenericSignature itself. This way we can also implement meaningful behavior for the empty value -- just treat it as a signature with no parameters and no requirements. This would in turn simplify away lots of null checks all over the place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants