Skip to content

Always use PackTypes as the substitutions for type parameter packs #63908

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

Closed

Conversation

rjmccall
Copy link
Contributor

The current representation allows these substitutions to be either pack types or directly pack parameters or archetypes. While the latter is a more compact representation, allowing it introduces an ambiguity where identical substitutions (or bound generic types, since there are some assumptions in the code that these are linked) can be canonically represented in multiple ways. It also forces clients to handle both cases, adding unnecessary complexity throughout the compiler.

@rjmccall
Copy link
Contributor Author

@swift-ci Please test

@@ -3302,6 +3302,13 @@ PackType *PackType::getEmpty(const ASTContext &C) {
return cast<PackType>(CanType(C.TheEmptyPackType));
}

PackType *PackType::getSingletonPackExpansion(Type param) {
assert((param->is<GenericTypeParamType>() &&
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want TypeBase::isParameterPack(), since I'm assuming you want to wrap a dependent member type (each T).Foo in a singleton pack also.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's probably useful

}
return Type();
}

SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const {
auto genericSig = getGenericSignature();
return SubstitutionMap::get(genericSig,
Copy link
Contributor

Choose a reason for hiding this comment

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

A more efficient implementation would build a SmallVector of archetypes or packs of pack archetypes, and then always call the primitive SubstitutionMap::get(), but I guess this is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This functor isn't actually used recursively as a substitution function (and we wouldn't generally want to wrap things in packs if it were). It's just initializing a SubstitutionMap and so is called once per generic parameter. Unless it's also used for conformances?

@xedin xedin removed their request for review February 28, 2023 17:47
@rjmccall rjmccall force-pushed the pack-parameters-substitute-to-packs branch from da6d51c to dc3a221 Compare March 1, 2023 22:58
This simplifies the representation and allows clients to handle fewer
cases.  It also removes an ambiguity in the representation which could
lead us to have two canonical types for the same type.

This is definitely not working yet, but I'm not making progress on
it quickly enough to unblock what we need to unblock; it'll have to
be fixed in parallel.
@hborla
Copy link
Member

hborla commented Mar 31, 2023

This was merged via #64166

@hborla hborla closed this Mar 31, 2023
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.

3 participants