Skip to content
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

Store the conforming type within an abstract ProtocolConformanceRef #80225

Merged

Conversation

DougGregor
Copy link
Member

An "abstract" ProtocolConformanceRef is a conformance of a type parameter or archetype to a given protocol. Previously, we would only store the protocol requirement itself---but not track the actual conforming type, requiring clients of ProtocolConformanceRef to keep track of this information separately.

Record the conforming type as part of an abstract ProtocolConformanceRef, so that clients will be able to recover it later. This is handled by a uniqued AbstractConformance structure, so that ProtocolConformanceRef itself stays one pointer.

There remain a small number of places where we create an abstract ProtocolConformanceRef with a null type. We'll want to chip away at those and establish some stronger invariants on the abstract conformance in the future.

@DougGregor
Copy link
Member Author

@swift-ci please smoke test

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

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

Awesome, thank you! This will enable some nice cleanups, optimizations, and even a bug fix for SILCloner's handling of opaque archetypes. I have some bikeshed naming comments, but it looks good otherwise.

@@ -158,6 +178,9 @@ class ProtocolConformanceRef {
return ProtocolConformanceRef(UnionType::getFromOpaqueValue(value));
}

/// Retrieve the conforming type.
Type getConformingType() const;
Copy link
Contributor

Choose a reason for hiding this comment

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

ProtocolConformance just calls this getType(), lets use that name

@@ -158,6 +178,9 @@ class ProtocolConformanceRef {
return ProtocolConformanceRef(UnionType::getFromOpaqueValue(value));
}

/// Retrieve the conforming type.
Type getConformingType() const;

/// Return the protocol requirement.
ProtocolDecl *getRequirement() const;
Copy link
Contributor

Choose a reason for hiding this comment

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

And if you rename this to getProtocol(), again for consistency with ProtocolConformance, I will forever be grateful

@@ -4533,7 +4533,7 @@ void ASTMangler::appendAnyProtocolConformance(
return;

auto path = genericSig->getConformancePath(conformingType,
conformance.getAbstract());
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add a FIXME here to remind ourselves that the conformingType parameter to this function is no longer necessary

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure.

@@ -293,25 +301,40 @@ ProtocolConformanceRef::getAssociatedConformance(Type conformingType,
conformingType->is<UnresolvedType>() ||
conformingType->is<PlaceholderType>());

return ProtocolConformanceRef(protocol);
return ProtocolConformanceRef::forAbstract(conformingType, protocol);
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I forgot about this spot!

Copy link
Contributor

Choose a reason for hiding this comment

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

The above conformingType assert should eventually be in forAbstract() itself -- but maybe not yet

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I want to get the refactoring in place first, then crank up the assertions until we can start simplifying.

@@ -5379,7 +5379,11 @@ static void ensureRequirementsAreSatisfied(ASTContext &ctx,

auto outerIsolation = conformance->getIsolation();
ProtocolConformanceRef(assocConf).forEachIsolatedConformance(
[&](ProtocolConformance *isolatedConformance) {
[&](ProtocolConformanceRef isolatedConformanceRef) {
if (!isolatedConformanceRef.isConcrete())
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be a pack conformance?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, we look through them for this callback. I'll be back in this code shortly.


// Figure out which arena this should go in.
RecursiveTypeProperties properties;
if (conformingType)
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are the remaining callers that pass a null Type?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know of any, but I want the assertions in place before I take this out.

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

@@ -2117,6 +2117,12 @@ namespace decls_block {
BCFixed<2> // the builtin conformance kind
>;

using AbstractConformanceLayout = BCRecordLayout<
Copy link
Contributor

Choose a reason for hiding this comment

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

You forgot to bump the module format

Copy link
Member Author

Choose a reason for hiding this comment

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

My local tree was out of date and I bumped it in exactly the same way you did in #80107 :)

@DougGregor
Copy link
Member Author

We got no signal from the macOS run due to other issues at the time. A commit with the (new) module format bump + addressing Slava's review comments is coming shortly.

@DougGregor DougGregor force-pushed the conforming-type-in-abstract-conformance branch from 3a8875a to ed1e683 Compare March 23, 2025 17:19
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please test source compatibility

An "abstract" ProtocolConformanceRef is a conformance of a type
parameter or archetype to a given protocol. Previously, we would only
store the protocol requirement itself---but not track the actual
conforming type, requiring clients of ProtocolConformanceRef to keep
track of this information separately.

Record the conforming type as part of an abstract ProtocolConformanceRef,
so that clients will be able to recover it later. This is handled by a uniqued
AbstractConformance structure, so that ProtocolConformanceRef itself stays one
pointer.

There remain a small number of places where we create an abstract
ProtocolConformanceRef with a null type. We'll want to chip away at
those and establish some stronger invariants on the abstract conformance
in the future.
@DougGregor
Copy link
Member Author

Source compatibility failures were UPASS, ignoring.

@DougGregor DougGregor force-pushed the conforming-type-in-abstract-conformance branch from ed1e683 to 731f584 Compare March 24, 2025 03:56
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor DougGregor enabled auto-merge March 24, 2025 03:56
@DougGregor DougGregor merged commit 83db811 into swiftlang:main Mar 24, 2025
3 checks passed
@DougGregor DougGregor deleted the conforming-type-in-abstract-conformance branch March 24, 2025 08:38
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.

2 participants