| Age | Commit message (Collapse) | Author |
|
* Allow generic type deduction from ParameterBlock arguments.
* Fix test.
* Update expected failure list.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Default (zero'd) values with `-zero-initialize` flag
Adds `-zero-initialize` flag to set values to a __default() expression if they are missing a initExpr.
* address review and ensure __default calls ctor + zero's fields.
1. We must keep zero-initialize in SemanticsDeclHeaderVisitor. This is done because else a ctor will be initialized before we can set struct fields to `__default`.
2. IRDefaultCtorDecoration was added to track default ctor's with parent struct.
3. ParentAggTypeModifier was added to track ChildOfStruct->IRType for sharing data such as with functions. This is required to ensure we associate a lowered function with a lowered struct type
* Removed decoration to track defaultCtor in favor of field.
This was done since decorations are checked for IR objects, storing auxillary info does not work here as a result if usable object.
* address some review comments
Since `IDefaultInitializable` is taking a considerabley larger amount of time than anticipated I am pushing some of the other fixes requested. I did not remove the "IRStruct storing a default Ctor" hack yet.
mostly renamed/adjusted tests to work as intended
added test to ensure we don't synthisize a junk `= 0` when not in `zero initialize` mode
removed member in favor of sharedContext+dictionary.
* a working but incorrect impl
* default init without any IR hacks (fully working aside from generic/containored-types)
* Finish zero init code
1. IDefaultInitializer interface was added. If conforming, your type may be zero-initialized. To Conform a `__init()` is required
2. `[OnlyAutoInitIfForced]` was added. This attribute states that a default initializer should only be implicitly called if forced by the compiler (`zero-initialize` for example). This allows types which implicitly/explicitly conform to IDefaultInitialize to have optional auto-init behavior (which is Slang's default for user structs) to be disabled.
* note about `[OnlyAutoInitIfForced]`. This is required for std-lib to not automatically resolve init-expressions for std-lib, but it has the added benifit of allowing user made structs/classes to control the default behavior of initializing
* fix ErrType assumption
* testing why dx12 fails local but passes CI
* push vector changes to generic test
* push syntax adjustment, still figuring out what is wrong with cuda.
* remove debug changes & adjust style
* fix field-init expressions with structs initializers
don't init a static in a ctor. This would be illegal code and wrong code (init list in lower-to-ir)
* minor adjustments temporarily while the rest of the issue is discussed
* fix
* implement IDefaultInitializable
* remove a unneeded whitespace change
* fix type checking error
should be checking if a valid type is `Type`, not `BasicExpressionType`
* needs to be DeclRefType, not Type
* fix langguage server error
* change findinheritance for correctness + cleanup
* remove return false
verified the issue was `findInheritance`
* push attempt at language server fix
* still trying to fix inheritance
* added extension support, remove redundant code
Did not address all review comments yet, want to see if CI also passes my changes
* undo a change which caused CI to fail
* change logic + DefaultConstructExpr
setup code to use defaultConstructExpr when possible to construct a default without overhead of invoke/related
also changed code so parent's defaultInitializable propegates to derived member
* 1. fix error in `isSubtype` 2. add flag to isSubtype
`subtypeInheritanceIsNotFullyResolved` was added since we may not be done the lookup stage but still require `isSubtype` checking to verify usage of inheritance while working with inheritance. In This case we will just skip `ensureLookup` and "caching" (since we don't have a cache invalidation system, nor need)
* fix bug in logic + add test to better catch the bug
* address comment + isSubTypeOption + wrapper type test,
* fix wrong code adjustment
I checked on the CI and realized I caused a failure, mistake was made not negating some code
* syntax, class naming capital
* remove stdlib default initialize changes, replace with `__default()` for init
* remove redundant code + fix defaultConstruct emitting
previously defaultConstruct emitting was crashing due to having generics unresolved. By not resolving the default construct immediately, everything works.
* remove a coment
* add test to ensure static variables dont `init` inside a struct's `__init`
* fix Ptr members breaking struct use
* address review and add -zero-initialize test
`-zero-initialize` test was added to be sure debug pointers are not broken with default init values
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
|
|
|
* Improve generic type argument inference.
* Fix.
* Fix.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Initial support for generic interfaces.
* Cleanup.
* Add generic syntax for interfaces.
* Add `IArray`.
* Fix.
* Fix.
* Fix.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Incur l-value conversion cost during overload resolution.
* Fix compile error.
* cleanup.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
|
|
* Add test for generic param inference bug for nested generics
* Change description & simplify test
* Add expected file
* Check parent decl before unifying type parameters
|
|
* Support implciit casted swizzled lvalue.
* Fix warnings.
* Fix.
* fix comment.
* Prefer mangled linkage name for global params.
* Update tests.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Redesign DeclRef + Deduplicate Val.
* Update project files
* Fix warning.
* Fix.
* Fix.
* Remove `Val::_equalsImplOverride`.
* Rmove `Val::_getHashCodeOverride`.
* Remove `semanticVisitor` param from `resolve`.
* Cleanups.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Simplify lookup.
* Various bug fixes.
* Report type dictionary size in perf benchmark.
* Remove type duplication.
* increase initial dict size.
* Bug fix.
* Fix bugs.
* Fixup.
* Revert type legalization looping.
* Fix specialization pass.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Create and cache flattened inheritance lists
The basic change here is to have a cached lookup that can map a `Type`,
or a `DeclRef` that might refer to a type or `extension`, to a list of
the *facets* that comprise it.
The notion of a *facet* here is similar to what the C++ standard calls
"sub-objects".
A declared type like a `struct` has:
* a facet for its own direct members
* one facet for each of its (transitive) base `struct` types
* one facet for each `interface` it conforms to
* one facet for each `extension` that applies to that type
The set of facets for a type is de-duplicated (so that "diamond"
inheritance patterns don't cause issues) and deterministically ordered,
using a variation of the C3 linearization algorithm.
The creation of a linearized list of facets should help the compiler
implementation in two key places:
* Testing if a type implements an interface (or inherits from a base
type) should now only take time linear in the number of (transitive)
bases of that type. We can simply scan the linearized facet list to
see if it contains a facet corresponding to the given base.
* Looking up the members of a type (or a value of a given type) should
be greatly simplified, since all of the members can be found in a
single linear scan of the facet list. In addition, those facets will
be ordered so that facets for "more derived" types will precede those
for "less derived" types, so that shadowing in the case of overrides
should be easier to implement.
This change only implements the first of these two improvements, since
there is already a *lot* of churn involved.
Notes and caveats:
* The handling of conjunction types (e.g., `IFoo & IBar`) complicates
the implementation, both because the simple approach to subtype
testing alluded to above is no longer complete, and also because
we need to be more careful about what forms of subtype witnesses
we construct, so that we can maintain the currently-required invariant
that two witnesses are only equal if they have matching structure.
* We don't implement the full/"proper" C3 algorithm here because it has
some failure cases that we'd still like to support. In particular if
we have both `IX : IA, IB` and `IY : IB, IA`, the C3 algorithm says it
is illegal to have `IZ : IX, IY` because the two bases it inherits
from disagree on the relative ordering of `IA` and `IB` in their
own linearizations. Handling such cases may make our implementation
less efficient, and it will also require testing of those corner
caes.
* When it comes time to revamp the implementation of lookup, we will
need to deal with the fact that a single linear list (seemingly)
cannot give us sufficient information to decide which of two members
of the same name should shadow the other, or if there is an ambiguity.
Or rather, it *can* give us that information if we are willing to
accept some very user-unfriendly behavior and simply say that
declarations earlier in the linearization always shadow later
declarations, even if the facets involved are not related by an
inheritance relationship of any kind.
* In order to remove one kind of vicious circularity from the approach,
the linearization that we are computing for `extension` declarations
will not be sufficient for lookups in the body of such an `extension`.
A future change may need to have support for creating and caching
two distinct linearizations for each `extension`: one that is to be
used when that `extension` is pulled into the linearization for a
type that it applies to, and another for when lookup will be performed
in the context of the `extension` itself.
* This change does *not* include the simple expedient of adding a direct
cache for subtype tests to the `SharedSemanticsContext`, although
adding such a cache would be a simple matter.
* This change introduces more deduplication for subtype witnesses,
which should enable more deduplication for other `Val`s (including
`Type`s), but it does not introduce any assumptions that equal
`Val`s or `Type`s must have identical pointer representations.
* Eventually we may find that, similar to the situation with `Type`s,
we will want to have a split between surface-level and canonicalized
versions of other `Val`s, including subtype witnesses.
* Fix clang error.
* remove debugging code.
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
|
* Make DeclRefBase a Val, and DeclRef<T> a helper class.
* Fixes.
* Workaround gcc parser issue.
* Revert NodeOperand change.
* Fix.
* Fix clang incomplete class complains.
* Fix code review.
* Small cleanups and improvements.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Bottleneck DeclRef creation through ASTBuilder.
* Fix clang error.
* Fix.
* Fix.
* More fix.
* Rebase on top of tree.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
|
|
* Fix type checking crash in language server.
* Fix loop var hoisting logic.
Fixes #2903.
* fix.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* MVP for higher order functions
* Add shader subgroup partitioned glsl intrinsics
* Implement parsing and checking for tuple types
Currently there is no way to do anything useful with them from the source language however
* neaten
* Correct precedence of function type parsing
* neaten
* higher order function tests
* function types of any arity
* Inference for higher order functions
* Add second test for unsynchronized params
* regenerate vs projects
* dx11 -> dx12 for saturated cooperations tests
* Disable saturated cooperation tests on vulkan
They fail on release builds in CI, not essential for the higher order function work however
* remove saturated-cooperation tests
* Remove unnecessary assert and clarify control flow in AddDeclRefOverloadCandidates
* Add Tuple type name mangling
* Use functype keyword to introduce function types
* Add more inference tests for hof
---------
Co-authored-by: Yong He <yonghe@outlook.com>
|
|
|
|
* Diagnose on attempt to specialize with interface type.
Fixes ##1445.
* Enable fixed test.
* Fix test.
* Fix.
---------
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
* Modified the new type system to support generic differentiable types and added support for differentiating overloaded functions.
* Changed a few asserts to release asserts to avoid unreferenced variable errors
* Fixed a naming issue with TypeWitnessBreadcumb::Flavor::Decl
* Added logic to avoid tracking differentiable types if the module does not use auto-diff or define differentiable types.
* Moved the auto-diff passes to after the specialization step, added a more complex generics test
* Added a generics stress test and fixed AST-side logic. IR side needs some more work
* Added differential getter and setter logic, fixed multiple issues with DifferentiableTypeDictionary, added support for loops and conditions
* Changed differential getters to use pointer types, added getter type checking
* Fixed some bugs related to diff type registration and differential getters
* Removed some superfluous code
* Removed some more unused code.
* Fixed an issue with witness substitution
* Minor fix
Co-authored-by: Yong He <yonghe@outlook.com>
|
|
A commonly requested feature is to be able to supply only some
of the arguments to a generic explicitly, while allowing the rest
to be inferred. A common example is a function that performs some
kind of conversion:
To convert<To, From>( From fromValue ) { .... }
A user would like to be able to call this operation like:
int i = convert<int>( 1.0f );
but the current Slang type checker requires all or none of the generic
arguments be supplied. Supplying all of the arguments is tedious:
int i = convert<int, float>( 1.0f );
In this case, the `float` type argument is redundant and could be
inferred from context. However, if the user tries to omit the generic
argument list:
int i = convert( 1.0f );
The current type-checker cannot infer the `int` type argument (even if
one might claim it *should* infer based on the desired result type).
This change adds support for the `convert<int>(...)` case, by allowing
a generic to be applied to a prefix of its explicit arguments, and then
inferring the remaining arguments from contextual information when that
"partially applied" generic is applied to value-level arguments.
Most of the changes are just plumbing: adding the notion of a partially
applied generic and then supporting them during overload resolution.
A single test case is included that covers the `convert`-style use case.
It is likely that more testing is needed to cover failure modes of this
feature.
|
|
* wip: dedup AST type nodes and cache lookup.
* Fix.
* Remove profiling.
* Fixes.
Co-authored-by: Yong He <yhe@nvidia.com>
|
|
The basic feature here is the ability to use the `&` operator to produce the conjunction/intersection of two interfaces. That is, you can have interfaces:
interface IFirst { int getFirst(); }
interface ISecond { int getSecoond(); }
and if you need a generic function where the type parameter `T` must conform to *both* of these interfaces, you express that by constraining the parameter to the intersection of the interfaces:
void someFunction<T : IFirst & ISecond>(T value) { ... }
Without this feature, the main alternative an application would have is to define an intermediate interface, like:
interface IBoth : IFirst, ISecond {}
Forcing users to deal with an intermediate interface creates more work for type authors (they need to remember to inherit from the right combined interface(s)), or for `extension` authors (when you add `ISecond` to a type that used to just support `IFirst`, you had better also add `IBoth`). In the worst case, a family of N related "leaf" interfaces would give rise to an exponential number of intermediate interfaces to represnt the possible combinations.
A conjunction like `IFirst & ISecond` is officially its own type, and can be used to declare a type alias:
typealias IBoth = IFirst & ISecond;
This change only includes the first pass of work on this feature, so there are several caveats to be aware of:
* Using a conjunction as part of an inheritance clause is not yet supported (e.g., `struct X : IFirst & ISecond`). This is true even if the conjunction was introduced by an intermediate `typealias`
* The `&` syntax introduced here is only parsed in places where only a type (not an expression) is possible. This means you cannot do things like cast to a conjunction with `(IFirst & ISecond)(someValue)`.
* This work *should* apply to conjunctions of more than two interfaces (like `IA & IB & IC`) but that has not yet been tested
* In the long run it may be sensible to allow conjunctions that use concrete types, but we really ought to have the semantic checking logic rule that out for now.
* During testing, I encountered compiler crashes when trying to use this feature together with `property` declarations. Further investigation and debugging is called for.
* The handling of conjunction types is currently incomplete, in that there are many equivalences the compiler does not yet understand. For example, it is clear that `IA & IB` is equivalent to `IB & IA`, but the compiler currently does not understand this and will treat them as different types. A deeper implementation approach is called for.
* Conjunctions are currently only supported for generic type parameter constraints, when performing full specialization. Use of conjunctions for existential-type value parameters or with dynamic dispatch is not yet supported.
|
|
* Add a ASTBuilder to a Module
Only construct on valid ASTBuilder (was being called on nullptr on occassion)
* Add nodes to ASTBuilder.
* Compiles with RefPtr removed from AST node types.
* Initialize all AST node pointer variables in headers to nullptr;
* Initialize AST node variables as nullptr.
Make ASTBuilder keep a ref on node types.
Make SyntaxParseCallback returns a NodeBase
* Don't release canonicalType on dtor (managed by ASTBuilder).
* Give ASTBuilders a name and id, to help in debugging.
For now destroy the session TypeCache, to stop it holding things released when the compile request destroys ASTBuilders.
* Moved the TypeCheckingCache over to Linkage from Session.
* NodeBase no longer derived from RefObject.
* Only add/dtor nodes that need destruction.
First pass compile on linux.
|
|
* First steps toward inheritance for struct types
This change adds the ability for a `struct` type to declare a base type that is another `struct`:
```hlsl
struct Base
{
int baseMember;
}
struct Derived : Base
{
int derivedMember;
}
```
The semantics of the feature are that code like the above desugars into code like:
```hlsl
struct Base
{
int baseMember;
}
struct Derived
{
Base _base;
int derivedMember;
}
```
At points where a member from the base type is being projected out, or the value is being implicitly cast to the base type, the compiler transforms the code to reference the implicitly-generated `_base` member. That means code like this:
```hlsl
void f(Base b);
...
Derived d = ...;
int x = d.baseMember;
f(d);
```
gets transformed into a form like this:
```hlsl
void f(Base b);
...
Derived d = ...;
int x = d._base.baseMember;
f(d._base);
```
Note that as a result of this choice, the behavior when passing a `Derived` value to a function that expects a `Base` (including to inherited member functions) is that of "object shearing" from the C++ world: the called function can only "see" the `Base` part of the argument, and any operations performed on it will behave as if the value was indeed a `Base`. There is no polymorphism going on because Slang doesn't currently have `virtual` methods.
In an attempt to work toward inheritance being a robust feature, this change adds a bunch of more detailed logic for checking the bases of various declarations:
* An `interface` declaration is only allowed to inherit from other `interface`s
* An `extension` declaration can only introduce inheritance from `interface`s
* A `struct` declaration can only inherit from at most one other `struct`, and that `struct` must be the first entry in the list of bases
This change also adds a mechanism to control whether a `struct` or `interface` in one module can inherit from a `struct` or `interface` declared in another module:
* If the base declaration is marked `[open]`, then the inheritance is allowed
* If the base declaration is marked `[sealed]`, then the inheritance is allowed
* If it is not marked otherwise, a `struct` is implicitly `[sealed]`
* If it is not marked otherwise, an `interface` is implicitly `[open]`
These seem like reasonable defaults. In order to safeguard the standard library a bit, the interfaces for builtin types have been marked `[sealed]` to make sure that a user cannot declare a `struct` and then mark it as a `BuiltinFloatingPointType`. This step should bring us a bit closer to being able to document and expose these interfaces for built-in types so that users can write code that is generic over them.
There are some big caveats with this work, such that it really only represents a stepping-stone toward a usable inheritance feature. The most important caveats are:
* If a `Derived` type tries to conform to an interface, such that one or more interface requirements are satisfied with members inherited from the `Base` type, that is likely to cause a crash or incorrect code generation.
* If a `Derived` type tries to inherit from a `Base` type that conforms to one or more interfaces, the witness table generated for the conformance of `Derived` to that interface is likely to lead to a crash or incorrect code generation.
It is clear that solving both of those issues will be necessary before we can really promote `struct` inheritance as a feature for users to try out.
* fixup: trying to appease clang error
* fixups: review feedback
|
|
* Small improvements to documentation and code around DiagnosticSink
* Made methods/functions in slang-syntax.h be lowerCamel
Removed some commented out source (was placed elsewhere in code)
* Making AST related methods and function lowerCamel.
Made IsLeftValue -> isLeftValue.
|
|
* Compiles.
* Small tidy up around session/ASTBuilder.
* Tests are now passing.
* Fix Visual Studio project.
* Fix using new X to use builder when protectedness of Ctor is not enough.
Substitute->substitute
* Add some missing ast nodes created outside of ASTBuilder.
* Compile time check that ASTBuilder is making an AST type.
* Moced findClasInfo and findSyntaxClass (essentially the same thing) to SharedASTBuilder from Session.
|
|
* Fields from upper to lower case in slang-ast-decl.h
* Lower camel field names in slang-ast-stmt.h
* Fix fields in slang-ast-expr.h
* slang-ast-type.h make fields lowerCamel.
* slang-ast-base.h members functions lowerCamel.
* Method names in slang-ast-type.h to lowerCamel.
* GetCanonicalType -> getCanonicalType
* Substitute -> substitute
* Equals -> equals
ToString -> toString
* ParentDecl -> parentDecl
Members -> members
|
|
The semantic checking logic was all inside `slang-check.cpp` and as a result this was a monster file that was extremely hard to follow. This change splits `slang-check.cpp` into several smaller files, although some of the resulting files are still quite large.
This change attempts to be a copy-paste job as much as possible and does *not* perform any cleanup on naming, structure, duplication, etc. in the code it deal with. No function bodies or signatures have been touched.
|