-
Notifications
You must be signed in to change notification settings - Fork 177
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
Add ability to specialize generic references to functions, types and more #4909
Add ability to specialize generic references to functions, types and more #4909
Conversation
+ Lookup methods and members (by string) on types + Fix issue with looking up non-static members through the scope operator '::' + `GenericReflection`: Cast a decl to generic to access unspecialized generic parameter names and constraints + `GenericReflection`: Use `getGenericContainer()` from function, variable or type to access the 'nearest' generic parent along with specialization info + `GenericReflection::getConcreteType` and `GenericReflection::getConcreteIntVal`: to get the concrete type of a param in the context of the reflection object + `GenericReflection::getOuterGenericContainer` to go up one level and get the outer generic declarations (if there are more than one enclosing generic scopes) + `DeclReflection::getParent`: go to parent declaration. + Change `VariableReflection` to be a `DeclRef` rather than a decl (allows us to return properly substituted types for methods, members, and more)
…5/slang into more-reflection-api
…5/slang into more-reflection-api
…more This PR adds the following end-points: - `specializeGeneric()` method that can be called on a generic reflection to substitute arguments for generic type and value parameters. It returns another generic reflection, but this time with the appropriate substitution. - `applySpecializations()` method to then copy these specializations onto an existing type or function reflection. - `isSubType()` to check if a type is a subtype of another type (useful to check if a type is differentiable by checking `IDifferentiable`) This PR also: - Adds `DeclReflection::Kind::Namespace` so that namespace containers are correctly reflected when walking the decl-tree. the name can be obtained through `getName()` but there's no need to cast to a namespace (since there's nothing else we can do with a namespace decl) - Fixes an issue with name-based lookups that fail if a type or function is referenced without specializations. Its helpful to be able to form a reference to a function with default substitutions, so that we can we can specialize it later (either directly, or via argument types).
include/slang.h
Outdated
SlangReflectionGenericArg const* args, | ||
ISlangBlob** outDiagnostics); | ||
|
||
SLANG_API bool spReflection_IsSubType( |
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.
isSubType
include/slang.h
Outdated
return (GenericReflection*)spReflectionGeneric_applySpecializations((SlangReflectionGeneric*)this, (SlangReflectionGeneric*)generic); | ||
} | ||
|
||
/*GenericReflection* specializeGenericTypeParameter( |
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.
delete?
source/slang/slang-check-decl.cpp
Outdated
@@ -7119,6 +7119,99 @@ namespace Slang | |||
|
|||
return args; | |||
} | |||
|
|||
SubstitutionSet makeSubstitutionFromIncompleteSet( |
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.
You can call SemanticsVisitor::inferGenericArguments
, which implement the same logic. Let's try not duplicate the logic here.
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 this specific function is different from inferGenericArguments
. We want to use it for specializeGeneric
which operates on struct types as well as callables, where we are provided specific argument substitutions for the generic parameters directly (not the arg types of the callables).
I plan on providing a separate function FunctionReflection::specializeWithArgTypes(...)
that will invoke inferGenericArguments
directly.
Alternatively, I can change up inferGenericArguments
to also support struct types. With generic interfaces, we probably need to enforce constraints across the arguments of the same generic.
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.
inferGenericArguments
is not only for function calls but for types as well.
Basically if you have S<T:IFoo, int N = 4>
and you pass in S<FooImpl>
, inferGenericArguments
will give you S<FooImpl, 4, FooImpl : IFoo>
.
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 guess for here, you want to reuse or factor out checkGenericAppWithCheckedArgs
, which eventually will call into inferGenericArguments
.
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.
Rerote this method with checkGenericAppWithCheckedArgs
+ added support for bool type args.
I think this is a good suggestion, since the new version should work seamlessly with variadics.
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.
We can delete this now?
…ore-reflection-api
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.
Looks good, but we need to remove makeSubstitutionFromIncompleteSet
.
return result; | ||
} | ||
|
||
bool ComponentType::isSubType(Type* subType, Type* superType) | ||
{ | ||
SharedSemanticsContext sharedSemanticsContext( |
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.
At somepoint it may make sense to hold a semantic visitor on the linkage, because it will become extensive to rebuild the type inheritance list for all referenced types everytime isSubType
is called. These are cached on the semantic visitor and we should probably reuse it to speed up these reflection queries.
This PR adds the following end-points:
specializeGeneric()
method that can be called on a generic reflection to substitute arguments for generic type and value parameters. It returns another generic reflection, but this time with the appropriate substitution.applySpecializations()
method to then copy these specializations onto an existing type or function reflection.isSubType()
to check if a type is a subtype of another type (useful to check if a type is differentiable by checkingIDifferentiable
)This PR also:
DeclReflection::Kind::Namespace
so that namespace containers are correctly reflected when walking the decl-tree. the name can be obtained throughgetName()
but there's no need to cast to a namespace (since there's nothing else we can do with a namespace decl)Fixes: #4787, #4800