-
Notifications
You must be signed in to change notification settings - Fork 10.5k
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -681,10 +681,37 @@ GenericEnvironment::mapElementTypeIntoPackContext(Type type) const { | |
}, LookUpConformanceInSignature(sig.getPointer())); | ||
} | ||
|
||
namespace { | ||
/// A function suitable for use as a \c TypeSubstitutionFn that produces | ||
/// correct forwarding substitutions for a generic environment. | ||
/// | ||
/// This differs from QueryInterfaceTypeSubstitutions only in that it | ||
/// always produces PackTypes for pack parameters. | ||
class BuildForwardingSubstitutions { | ||
QueryInterfaceTypeSubstitutions Query; | ||
|
||
public: | ||
BuildForwardingSubstitutions(const GenericEnvironment *self) | ||
: Query(self) { } | ||
|
||
Type operator()(SubstitutableType *type) const; | ||
}; | ||
} // end anonymous namespace | ||
|
||
Type BuildForwardingSubstitutions::operator()(SubstitutableType *type) const { | ||
if (auto resultType = Query(type)) { | ||
auto param = type->castTo<GenericTypeParamType>(); | ||
if (!param->isParameterPack()) | ||
return resultType; | ||
return PackType::getSingletonPackExpansion(resultType); | ||
} | ||
return Type(); | ||
} | ||
|
||
SubstitutionMap GenericEnvironment::getForwardingSubstitutionMap() const { | ||
auto genericSig = getGenericSignature(); | ||
return SubstitutionMap::get(genericSig, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
QueryInterfaceTypeSubstitutions(this), | ||
BuildForwardingSubstitutions(this), | ||
MakeAbstractConformanceForGenericType()); | ||
} | ||
|
||
|
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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