<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-ast-decl.h, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2025-10-13T14:14:45+00:00</updated>
<entry>
<title>Fix segfault on arrays of structs containing parameter blocks (#8555)</title>
<updated>2025-10-13T14:14:45+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2025-10-13T14:14:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=96df31a9fa53e3d897a2b7c4eef021f37f421c91'/>
<id>urn:sha1:96df31a9fa53e3d897a2b7c4eef021f37f421c91</id>
<content type='text'>
Closes https://github.com/shader-slang/slang/issues/8154 However there
is further design work to do on implementing the "NonAddressableType"
suggestion</content>
</entry>
<entry>
<title>Use symbol alias instead of wrapper synthesis to implement link-time types. (#8603)</title>
<updated>2025-10-07T00:21:37+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-07T00:21:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6af3381f47e3c22e1657c0e0064fa466e8bde0f6'/>
<id>urn:sha1:6af3381f47e3c22e1657c0e0064fa466e8bde0f6</id>
<content type='text'>
This change achieves link-time type resolution with a different
mechanism.

For `extern struct Foo : IFoo = FooImpl;`,
instead of synthesizing a wrapper type `Foo` that has a `FooImpl inner`
field and dispatches all interface method calls to `inner.method()`,
this PR completely removes this synthesis step, and instead just lower
such `extern`/`export` types as `IRSymbolAlias` instructions that is
just a reference to the type being wrapped.

Then we extend the linker logic to clone the referenced symbol instead
of the SymbolAlias insts itself during linking.

By doing so, we greatly simply the logic need to support link-time
types, and achieves higher robustness by not having to deal with many
AST synthesis scenarios.

Closes #8554.

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>A new approach to AST node deduplication (#8072)</title>
<updated>2025-08-06T19:48:02+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-08-06T19:48:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=352576546bf192b06e425e922d305f0a7d0845fb'/>
<id>urn:sha1:352576546bf192b06e425e922d305f0a7d0845fb</id>
<content type='text'>
* A new approach to AST node deduplication

Background
----------

The Slang compiler currently relies on the idea that AST nodes derived from `Val` are always deduplicated based on their opcode and operands.
Deduplication requires caching, and we thus have to determine the right scope at which to allocate and cache different `Val`s.

We need to ensure that `Val`s that refer to declarations/nodes in a specific compilation session/linkage are not cached in a scope that will outlive that session/linkage (or else the cache will contain garbage pointers).
Conversely, we also need to ensure that any `Val`s that are referred to by something like a builtin module's AST will remain alive at least as long as that module/AST, and that every compilation session/linkage that refers to that module will find that `Val` cached if they try to create an equivalent one.

The existing approach to deduplication has some subtleties:

* A builtin module like the core module needs to be fully loaded (using the `ASTBuilder` for the global session) before any other compilation session might construct `Val`s referring to nodes in the AST of that module.

* The various declarations/types/values cached on the `SharedASTBuilder` need to be created before any user-defined compilation occurs, to ensure that all of the relevant `Val`s are created on the global session's AST builder (see `Session::finalizeSharedASTBuilder`).

* Related to all of the above: the deduplication cache on a non-top-level `ASTBuilder` is initialized by copying the cache from the top-level (global session) `ASTBuilder` on creation. Any subsequent allocations on the global-session `ASTBuilder` will not be visible to the linkage-level `ASTBuilder`. This led to weird things like the *options parsing* logic for `-load-core-module` reaching in and performing a manual copy of the cache from the global session to a linkage to try to restore the invariants.

* Notably, the deduplication logic doesn't actually care if two different linkages create distinct `Val`s that represent the same thing, so long as nothing in the AST of a builtin module will refer to that thing. E.g., if the builtin modules never mention `Ptr&lt;String&gt;`, then two different linkages that both refer to that type will likely construct distinct `Val`s to represent it. Thus the deduplication is not as complete as some might assume.

The subtle ordering considerations when creating `Val`s related to builtin modules has proved to be a sticking point for implementing on-demand deserialization of the builtin modules (in order to improve startup times).

Overview
--------

This change implements a new approach that hopefully makes it easier to ensure correctness, even in the case where AST nodes for builtin modules and `Val`s that refer to those nodes sometimes get created after other compilation has been performed.
The key points of the new approach are:

* `ASTBuilder`s are now explicitly (rather than just implicitly) linked into a hierarchy. Currently the compiler codebase will only create a two-level hierarchy: the `ASTBuilder` for a global session is the parent to all of the `ASTBuilder`s created for `Linkage`s. The expectation is that the code can and will generalize to more levels of nesting.

* When a request is made to create a `Val` (or find it in a cache), there is a single `ASTBuilder` that is determined to be responsible for owning that `Val` for its lifetime. The logic involved is comparable to the way that the `IRBuilder` decides where to insert a "hoistable" (deduplicated) instruction, with the simplification that we are dealing with a tree instead of a CFG.

Details
-------

* `Session::finalizeASTBuilder()` is gone, because it is no longer needed

* The logic in the `ASTBuilder` constructor and in `slang-options.cpp` that was manually copying the `m_cachedNodes` from the global-session `ASTBuilder` over to a linkage's `ASTBuilder` is removed, since it is no longer needed.

* Made every AST node (`NodeBase`) carry a pointer to the `ASTBuilder` that created it. This is wasteful, but makes it easier to be sure the implementation will work.

* Introduced a class `RootASTBuilder`, derived from `ASTBuilder` to represent the root of a given hierarchy of AST builders.

* Every non-root `ASTBuilder` is now constructed with a pointer to its parent builder.

* Changed it so that instead of allocating a `SharedASTBuilder` and then passing it in to create one or more `ASTBuilder`s, the shared AST builder state is more of an implementation detail of the `ASTBuilder` type, and is automatically allocated behind the scenes as part of creating an `ASTBuilder`.

* The inline (defined in header) `ASTBuilder::_getOrCreateImpl()` now just does a first-pass check for an existing cached `Val` and, if it doesn't find one, delegates to `ASTBuilder::_getOrCreateImplSlowPath()`, which encapsulates the logic for the cache-miss case (even if that logic is just two lines).

* The `ASTBuilder::_findAppropriateASTBuilderForVal()` method inspects a `ValNodeDesc` to determine the "deepest" of the AST builders among its operands (falling back to the root AST builder if there are no relevant operands).

* The `ASTBuilder::_getOrCreateValDirectly()` is intended for use when the correct AST builder to use for caching/allocation has already been identified.

* Moved the caching of generic arguments for "default substitutions" out of `ASTBuilder` and onto `GenericDecl` itself. Note that the naming of the old field (`m_cachedGenericDefaultArgs`) was unclear about the fact that this is related to "default substitutions" (where each generic parameter is fed an argument that refers to the parameter itself), and has *nothing* to do with any default argument values that might be set on the generic parameters.

* Changed the global session (`Session`) so that instead of storing pointers to both the root/builtin `ASTBuilder` *and* the corresponding `SharedASTBuilder`, it just retains a pointer to the root `ASTBuilder`. This is consistent with the move toward making the `SharedASTBuilder` just an implementation detail.

Possible Future Work
--------------------

* In theory this change should unblock on-demand AST deserialization, so it would be good to get back to those changes once this new approach lands.

* Many AST node subclasses end up storing their own `ASTBuilder` pointers, which are likely now redundant with the one in `NodeBase`. These should be eliminated where possible.

* A lot of code for AST-related manipulations has been changed over time to require an `ASTBuilder` to be passed in, but at this point such a builder should always be derive-able so long as the operation has at least one non-null AST node available to it.

* Most of the accessors that are currently on `SharedASTBuilder` can/should be migrated to just be on `ASTBuilder`, where they can use the data from the `SharedASTBuilder` as part of their implementation. Ideally most code should only nee to interface with `ASTBuilder`s directly, and will never need to talk to the `SharedASTBuilder`.

* This change cleaned up some of the ownership hierarchy, and made it so that the global session only retains a pointer to the root AST builder (and not the shared state as well). A logical follow-on for that would be to make the `Linkage` more properly own (and thus allocate) its own AST builder (and other related objects), and have the global session only store a pointer to the root linkage (and not point to the various sub-objects directly).

* The `Linkage` and `SourceManager` types have their own form of parent/child hierarchy (restricted to two levels), and could be generalized in a way that is similar to what this change does for `ASTBuilder`. Support for a hierarchy of `Linkage`s could be a powerful tool for end users, if we expose it in the right way.

* format code

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Prelink ForceInlined functions during lowering. (#7812)</title>
<updated>2025-07-17T23:04:20+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-07-17T23:04:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=094d1ba7cd1eb5f09be05b2e57b5fbd3041cca38'/>
<id>urn:sha1:094d1ba7cd1eb5f09be05b2e57b5fbd3041cca38</id>
<content type='text'>
* Prelink ForceInlined functions during lowering.

* Fixes and cleanups.

* Fix warning.

* Fix crash.</content>
</entry>
<entry>
<title>Improve lookup performance. (#7798)</title>
<updated>2025-07-17T06:43:06+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-07-17T06:43:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=020a16072923a66ae0985be618fd32310aa87242'/>
<id>urn:sha1:020a16072923a66ae0985be618fd32310aa87242</id>
<content type='text'>
* Improve lookup performance.

* Cleanup.

* Improve autocompletion latency.</content>
</entry>
<entry>
<title>extend fiddle to allow custom lua splices in more places (#7559)</title>
<updated>2025-07-01T19:03:41+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2025-07-01T19:03:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5120c1cd072548654c9ce79fa85426a5e48736c4'/>
<id>urn:sha1:5120c1cd072548654c9ce79fa85426a5e48736c4</id>
<content type='text'>
* Add fkYAML submodule

* Generate slang-ir-inst-defs.h from slang-ir-inst-defs.yaml

* generate ir-inst-defs.h

* neaten things

* neaten inst def parser

* add rapidyaml submodule

* remove fkyaml

* remove fkyaml submodule

* remove use of ir-inst-defs.h

* format and warnings

* fix wasm build

* tidy

* remove rapidyaml

* Extend fiddle to allow custom splices in more places

* Use lua to describe ir insts

* fix

* neaten

* neaten

* neaten

* spelling

* neaten

* comment comment out assert

* merge</content>
</entry>
<entry>
<title>Add support for on-demand AST deserialization (#7482)</title>
<updated>2025-06-19T00:11:16+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-06-19T00:11:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=3ed77615924dc41b8b2f286d4ac646f625cd946c'/>
<id>urn:sha1:3ed77615924dc41b8b2f286d4ac646f625cd946c</id>
<content type='text'>
Note that this change does not actually *enable* on-demand deserialization of ASTs, because doing so is incompatible with the current compiler architecture where we have both an `ASTBuilder` and a `SharedASTBuilder`, and there are important invariants about how all AST nodes related to the core module must be created before those of any module using the core module.

Instead, this change simply adds the *infrastructure* for on-demand deserialization, and ensures that those code paths get used at runtime, but actually "demands" all of the nodes in a given serialized AST immediately as part of the deserialization process.

Important notes about the implementation approach:

* PR #7242 ensured that all of the code accessing the direct member declarations of a `ContainerDecl` went through a small(-ish) set of accessor methods. This change takes advantage of that work by further abstracting the storage of the direct member declarations out in a type, `ContainerDeclDirectMemberDecls`, which makes it easy to add custom serialization logic for just that type.

* The `ContainerDeclDirectMemberDecls` type also stores two pointers (one a `RefPtr` and the other a plain pointer) that are only used in the case where the members of a given `ContainerDecl` are being accessed through on-demand deserialization. This can be queried using the `isUsingOnDemandDeserialization()` method but any code accessing a `ContainerDecl` through the intended public API should never need to care about that detail.

* Many of the accessor methods that were added in PR #7242 now branch on whether `isUsingOnDemandDeserialization()` is set. The normal code path is unchanged, and the implementation logic for the on-demand-deserialization case is largely held in `slang-serialize-ast.cpp`, to keep it close to the definitions of the serialized data structures themselves.

* A few types in the `slang-ast-*.h` headers have had `FIDDLE()` annotations added to them, so that they can be used to synthesize some of the serialization logic that was previously hand-written.

* The `_registerBuiltinDeclsRec()` function (which is used to scan the built-in module ASTs for the various "magic" declarations that the `SharedASTBuilder` needs to know about) was factored a bit to support the way that registration needs to behave differently in the case of loading a serialized module (if we kept using the existing recursive search, then it would force every declaration in the core module to be loaded right away). The new `_collectBuiltinDeclsThatNeedRegistrationRec()` function mirrors the overall traversal pattern to produce a flat list that gets included in the serialized AST module. Note in particular that we no longer call `registerBuiltinDecls()` from within `_readBuiltinModule()`.

* The interface of the `Module` type was slightly expanded so that there is a more complete API for accessing the declarations exported from the module. Previously they could only be queried by their mangled name, but the new API also allows the entire list to be iterated over. The `ensureLookupAcceleratorBuilt()` method factors out the logic for building those data structures for a module. Note that in the case where on-demand deserialization is being used for a module, the `findExportedDeclByMandledName()` query will use serialized data directly, rather than build the lookup accelerators as C++ data structures (this is required if we are to avoid immediately deserializing all of the (exported) declarations in the core module as soon as it is loaded).

* A few methods related to loading serialized modules (e.g., `loadSerializedModule()`) have been updated so that along with a pointer to the serialized `ModuleChunk` (which, for those who aren't aware, is a pointer directly into the serialized bytes of the module file), they receive an `ISlangBlob` that refers to the entire blob holding the serialized data (which the `ModuleChunk` is part of). Passing this pointer down allows code running under these methods to retain a reference-counted pointer to the blob to stop the memory of the serialized module from being released until deserialization has been completed.

* The data types defined in `slang-fossil.h` have been overhauled significantly:

  * The most important change that is relevant to this work is the introduction of the `Fossilized&lt;T&gt;` template, which is used to statically map a "live" C++ type `T` to its binary fossilized representation. The `slang-fossil.h` file provides infrastructure allowing `Fossilized&lt;T&gt;` to be specialized for user-defined types, and also provides the necessary mappings for the core types like strings, arrays, and dictionaries.

  * A key point is that in C++ code, one can take a value of some type `Foo`, serialize it using a `Fossil::SerialWriter`, get a pointer to that serialized data, and then directly cast it to a `Fossilized&lt;Foo&gt;*` and navigate the serialized data directly (without deserializing it back into a `Foo`). For that process to work, any specialization of `Fossilized&lt;T&gt;` must be sure to match the layout that will be produced by the `serialize()` implementation for `T`, when writing to a `Fossil::SerialWriter`.

  * Another key change in the public interface of `slang-fossil.h` is that dynamically-typed traversal of the data used to be handled just with `FossilizedValRef`, but now uses a few different types. The `Fossil::ValRef&lt;T&gt;` and `Fossil::AnyValRef` types are used to capture the use cases that want reference-like behavior (basically a `Fossil::ValRef&lt;T&gt;` can be thought of as sort of like a `T&amp;`), while `Fossil::ValPtr&lt;T&gt;` and `Fossil::AnyValPtr` are used for cases that want pointer like behavior (akin to `T*`).

* Then there are related changes in `slang-serialize-fossil.*`:

  * The implementation of `Fossil::SerialReader` has been changed to use `Fossil::AnyValPtr` in most places where it formerly used `FossilizedValRef`. Using pointers (that can be null) instead of a weird kind of pseudo-reference (that could still be null) to traverse things was making the code harder to follow than it ought to be, in terms of understanding the levels of indirection in various places.

  * Some of the state that was previously in `Fossil::SerialReader` has been split into `Fossil::ReadContext`. This type allows multiple `Fossil::SerialReader`s to be created to read from the same serialized blob(s), while maintaining a persistent mapping from fossilized data pointers to live object pointers. The `ReadContext` also maintains the work list of deferred deserialization actions waiting to be performed, and only flushes that list when the last currently-open `SerialReader` is about to go out of scope.

* In order to support the split of `Fossil::SerialReader` described above (and also to clean up something that didn't quite feel right in the original serialization design) the base serialization framework in `slang-serialize.h` has been tweaked so that a `Serializer` now wraps *two* pointers instead of just one. The first pointer continues to be an implementation of `ISerializerImpl`, which handles the actual reading/writing of data, while the other pointer is an explicit "context" pointer for operations that need additional user-defined context.

* Similar to the changes made to the accessors for direct member declarations in a `ContainerDecl`, the `Module::findExportedDeclByMangledName()` method was updated to conditionally execute a different code path in the case of a module that has been loaded from serialized data.

* Some improvements have been made to the fiddle tool:

  * Most importantly, the error-handling logic around Lua script execution has been cleaned up to better match correct Lua idiom. Native functions exposed to the Lua scripts have been changed to just use `lua_call` instead of `lua_pcall`, so rather than attempt to intercept Lua errors they will just automatically propagate them.

  * All Lua-related errors are caught at the top level, and reported in a way that uses the source location of the fiddle template that was being evaluated when the error was raised. In most cases, a Lua error should be accompanied by a stack trace of the Lua evluation state. The file paths and line numbers given should be accurate, but aren't directly double-clickable in the Visual Studio output panel, because they use a different format (a good future change might be to process the Lua stack trace and rewrite it into a format that is better for our needs).

  * Fixed a subtle bug where having "raw" content (parts of the template that should neither be evaluated nor emitted into the output) that consisted of only whitespace could result in a template being translated to invalid Lua code.

* The bulk of the change is, unsurprisingly, in `slang-serialize-ast.cpp`.

  * This file has been refactored enough to look like a complete rewrite. A lot of work has been put into comments that describe the overall approach being taken, so hopefully it can be understood even by somebody who wasn't familiar with the previous code. Some of these are just plain cleanups, rather than being directly related to on-demand serialization.

  * Where possible, the code for reading and writing types that needed custom serialization has been moved so that the read/write functions are next to one another, making it easier to visually confirm that the serialized representations match on the read and write sides.

  * Where possible, the serialization logic for all types (not just the AST nodes, as was the case before) is being generated via fiddle.

  * Rather than just defining `serialize()` overloads for each of the relevant types, the code now defines `Fossilized&lt;...&gt;` specializations for these types as well, to enable statically-typed in-memory traversal of the serialized data. Note, however, that for the most part the `Fossilized&lt;...&gt;` representation types are *not* being used by the code (really only the `ASTModuleInfo` and `ContainerDeclDirectMemberDeclsInfo` types are traversed directly). This can be considered more as work to prove out the design of the `Fossil&lt;...&gt;` template approach, and it may or may not end up being relevant in the future.

  * The trivial bit of work to enable on-demand deserialization is in `ASTSerialReadContext::handleContainerDeclDirectMemberDecls()` where, rather than recursively reading the contained declarations, the method effectively just grabs the current cursor of the `Fossil::SerialReader` (which is pointed into the fossilized data) and stashes it into the `ContainerDeclDirectMemberDecls`, along with a `RefPtr` to the `ASTSerialReadContext` itself. Those stashed pointers are what enables the accessors on `ContaienrDeclDirectMemberDecls` to look up information on-demand.

  * The more interesting bits of the approach mostly come at the end of the file, where the accessor operations for on-demand deserialization are implemented. Once all the relevant work has been done to write the data structures, and produce `Fossilized&lt;...&gt;` types with the right layout, the work itself may seem almost trivial: a little bit of array iteration, and a little bit of binary-search lookup.

  * As a reminder, all of this infrastructure for on-demand deserialization is now in place and able to be invoked by the rest of the compiler, but declarations are currently all being loaded eagerly. The `SLANG_DISABLE_ON_DEMAND_AST_DESERIALIZATION` macro is being used to enable a small bit of extra logic in `ASTSerialReadContext::_cleanUpASTNode` so that the "cleanup" on a just-deserialized `ContainerDecl` includes eagerly querying its list of direct member declarations, which will cause them to be recursively deserialized.</content>
</entry>
<entry>
<title>Allow interface methods to have default implementations. (#7439)</title>
<updated>2025-06-14T05:13:00+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-06-14T05:13:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=6a23949f07f4eba38086b656e7073ce3bf8cd2fe'/>
<id>urn:sha1:6a23949f07f4eba38086b656e7073ce3bf8cd2fe</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Mediate access to ContainerDecl members (#7242)</title>
<updated>2025-06-09T18:22:51+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-06-09T18:22:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=bfae49d853e0f9b6f9de495b13bcd1642ca4a285'/>
<id>urn:sha1:bfae49d853e0f9b6f9de495b13bcd1642ca4a285</id>
<content type='text'>
Most of what this change does is straightforward: take all the places in the code that used to operate directly on `ContainerDecl::members` and related fields, and instead have them call into a smaller set of accessor methods defined on `ContainerDecl`.

The primary motivation for making this change is that in order to implement on-demand loading of members from serialized AST modules, we need a way to identify and intercept the "demand" for those members.

On-demand loading benefits from having all accesses to the members of a `ContainerDecl` be as narrow as possible.
If a part of the code only need a member at a specific index, it should say so.
If it only needs access to members with a specific name, or a given subclass of `Decl`, then it should say so.

A secondary motivation for this change is that there have recently been several changes that added complexity and special cases by introducing code that operated on (and *mutated*) the member list of a container decl in ways that the existing code had never done before.

Any code that mutates the member list of a `ContainerDecl` needs to be sure to not disrupt the invariants that the lookup acceleration structures currently rely on.
One of the recent changes added a declaration-to-index map to the set of acceleration structures (with different validation/invalidation behavior than the others...) while other recent changes would remove or insert declarations in ways that could change the indices of other declarations in the same container.
It is not clear if any of these pieces of code were aware of the others, and the invariants that might be expected or broken along the way.

This change bottlenecks the vast majority of accesses to the members of a `ContainerDecl` through the following operations:

* Getting a `List` of all of the direct member declarations of a container

* Get the number of direct member declarations, and accessing them by index.

* Looking up the list of direct member declarations with a given name.

* Adding a new direct member declaration to the end of the list.

Some other operations are layered on top of those (e.g., getting a list of all the direct member declarations of a given C++ class).
These layered operations are still centralized on the `ContainerDecl`, with the intention that we *can* change them to be non-layered implementations if we ever need to for performance (e.g., by building a lookup structure for finding member declarations by their type).

The exceptional cases of access/mutation on the direct members of a `ContainerDecl` have also been encapsulated, but rather than expose what would risk appearing like general-purpose accessors (e.g., `removeDecl(d)`, `setDecl(index)`, etc.), these operations have been explicitly named after the specific use case that they serve in the codebase today, to discourage others from using them for more kinds of operations we'd rather not support.
These operations have also been given parameter signatures that match their use cases, to make it so that even somebody determined to abuse them would have to invent suitable arguments out of thin air.

In the case of the declaration-to-index mapping, this change eliminates that acceleration structure, in favor or slightly more complicated (and possibly inefficient, yes) code at the use site.

Over time, it would be good to closely scrutinize each of the use cases that requires more complicated interaction with the members of a `ContainerDecl`, to see whether any of them can be reframed in terms of the more basic operations, or if there is some clean abstraction we can introduce to make operations that mutate the member list feel like... hacky.</content>
</entry>
<entry>
<title>Language version + tuple syntax. (#7230)</title>
<updated>2025-05-29T15:05:57+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-05-29T15:05:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=faf042ecc3e688a1a3ffbe1ac44d18dd7ddf441a'/>
<id>urn:sha1:faf042ecc3e688a1a3ffbe1ac44d18dd7ddf441a</id>
<content type='text'>
* Language version + tuple syntax.

* Fix compile error.

* regenerate documentation Table of Contents

* Fix.

* regenerate command line reference

* Fix.

* Fix.

* Fix more test failures.

* revert empty line change,

* Retrigger CI

* #version-&gt;#lang

* Update source/core/slang-type-text-util.cpp

Co-authored-by: ArielG-NV &lt;159081215+ArielG-NV@users.noreply.github.com&gt;

* Remove comments.

* Fix parsing logic.

* Fix parser.

* Fix parser.

* update test comment

* Update options.

* regenerate documentation Table of Contents

* regenerate command line reference

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;
Co-authored-by: ArielG-NV &lt;159081215+ArielG-NV@users.noreply.github.com&gt;</content>
</entry>
</feed>
