These constant instructions are all TypeInstId already in their type,
and this makes their names match.
Change the name of MakeSingletonInstId as well and update its comment.
Adds a `virtual_index` to `SemIR::Function` used to determine which
vtable slot
to use when calling the given function.
Then use that to lower the function call to use the vtable and
specifically the
relative vtable ABI to match the vtable entries.
We frequently want to operate on singletons. Per discussion, drop
`Singleton` to make the code shorter.
This started off as wanting to write `inst_id.is_error()`, but the
dependency relationship between ids.h and singleton_insts.h would
require some kind of delayed evaluation to allow the implementation to
remain in headers (which I suspect is helpful to have for inlining). I
could have added something like `IsErrorInst`, forward declared in ids.h
and defined in singleton_insts.h (which would always be included by
typed_insts.h), but the template approach felt like a decent balance
between (a) removing the boilerplate `::SingletonInstId`, (b)
understandability, (c) still visually mirroring if we immediately return
a singleton, and (d) flexibility for more than just `ErrorInst`. But TBH
I'd probably still have written `is_error()` if it didn't require
addressing the cross-header cycle.
Then I tried `SemIR::InstId::Is<SemIR::ErrorInst>`, which generally
worked with types but generated the complaint that it didn't shorten
*all* singleton uses. So pulling back on `::Is`, and instead just
dropping `Singleton`.
After #5280 there are a few more typed instructions that have an `InstId
type_inst_id` that always holds a type value. These are converted to
`TypeInstId` to encode this fact in the type system. The
`ConvertAggregateElement()` function in convert.cpp is now able to
receive `TypeInstId` for a couple arguments as well.
Additionally, the `type_inst_id` field of `StructTypeField` is made into
a `TypeInstId`.
The `TupleType::elements_id` is renamed to `TupleType::type_elements_id`
to try record the fact that it's an InstBlock of type value
instructions. We don't introduce a TypeInstBlockId at this time, but it
might be nice to make blocks of TypeInstIds in the future.
To assist in working with a block of InstId that are type values, two
additional helpers are added to the TypeStore:
- GetBlockAsTypeInstIds which turns an `ArrayRef<InstId>` into a range
of `TypeInstId`
- GetBlockAsTypeIds which turns an `ArrayRef<InstId>` into a range of
`TypeId`
We use these helpers in places that iterate over the
`TupleType::type_elements_id`.
In preparation for shifting from `TypeId`s potentially representing
attached types to always representing unattached types, using
[terminology suggested on
Discord](https://discord.com/channels/655572317891461132/963846118964350976/1359286326779973712).
This change causes us to track slightly more type spelling information
through SemIR.
One change that has significant impact on the SemIR output is that we
now build a `struct_type` instruction in each class representing the
types of the fields, including the spelling used for those types. This
is now no longer always identical to the corresponding canonical
`struct_type` for the object representation, so it's built separately
and owned by the class.
Also remove `TypeBlock` support entirely, as its only use was
representing `TupleType`s, which now use an `InstBlock`.
I'd split out the decl-specific handlers so that import_ref.cpp could
also call them. However, with the current model for imports and
constants, we shouldn't use them there. As a consequence, merge them
back into individual files for greater consistency with other helper
functions (and better visibility when making related code changes).
This addresses the const reliance of ResolvePrevInstForMerge by checking
the imported instruction, testing with `alias` name conflicts. Given the
need to examine structure, the helper function feels like it now gets in
the way, so I'm just removing it.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This doesn't actually track whether a declaration is `extern`. It does,
however:
- Factor out and expand merge support for classes, sharing handling with
functions.
- This makes the ClassRedefinition diagnostic redundant, as the
redeclaration checking overlaps.
- Add partial `extern` handling to class handling; just some
verifications of correct use.
- Factor out `extern` on member handling for sharing with `fn`.
- Fixes a bug in import_ref where a class's definition_id wasn't
assigned when defining.
This changes how a redefinition is handled (replaced, rather than
merged). I don't know whether that's ideal, but I think it results in
easy-to-understand consequences, and it's more consistent with how `fn`
works.
There's enough work here that this felt like a decent cut point,
particularly as the amount of work to actually add `extern` tracking
will be significant.