Commit Graph
38 Commits
Author SHA1 Message Date
Richard Smith a74ca9071b Remove all remaining uses of TypeIds as instruction operands. (#5280)
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`.
2025-04-10 20:53:42 +00:00
Richard SmithandDana Jansens bba32900c3 Preserve type sugar in ArrayType, ConstType, and PointerType. (#5235)
Each of these types takes another type as an operand. Instead of storing
that other type as a `TypeId`, store it as an `InstId` so that we can
track how it was written, not only its canonical form.

The canonical constant values of these types continue to store the
canonical constant values of their operands, as normal.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-03 21:14:03 +00:00
Richard Smith 265968b396 Make evaluation of symbolic bindings simpler and more uniform (#5215)
Factor out logic to evaluate `EntityNameId` instead of duplicating it
between `BindSymbolicName` and `SymbolicBindingPattern`. Remove support
in `SymbolicBindingPattern` for evaluating a pattern to the constant
value of the corresponding binding, which doesn't really make any sense
given that patterns don't generally evaluate to the value that they
matched.

This results in the handling for `SymbolicBindingPattern` being simply
the default handling for an always-constant instruction, so remove the
special case for it entirely and change its constant kind to `Always`.
It's not entirely clear that it makes sense for `SymbolicBindingPattern`
to be treated as a constant when other patterns aren't, but we seem to
be relying on this in various places, so leave it as a constant for now.
Changing it to never be constant will be a smaller change now -- it just
requires changing the `constant_kind`.

The IR changes in the tests are fairly widespread, but mechanical, and
there are two kinds of things changing:

- `symbolic_binding_pattern`s in specifics now evaluate to
`symbolic_binding_pattern`s, not to the argument values. This means in a
few cases we end up with additional `symbolic_binding_pattern`
constants.
- We evaluate the type operand of `symbolic_binding_pattern` now, so an
error in the type will now properly be propagated into an error in the
pattern's constant value.
2025-04-01 20:24:00 +00:00
Geoff Romer d264f14027 Clean up handling of Call params (#5061)
- Explicitly document that `*Param` and `*ParamPattern` insts represent
`Call` parameters.
- Stop wrapping compile-time parameter patterns in `ValueParamPattern`
insts (because they aren't `Call` parameters).
- Document how `MatchContext::results_` relates to the `Call`
parameters, and be more consistent about when it's written to.
- Remove `RuntimeParamIndex::Unknown`: we no longer need to distinguish
"this `Param`'s runtime index is unknown" from "this `Param` isn't a
runtime param", because we no longer use `Param`s at all in the latter
case.
- Rename `RuntimeParamIndex` to `CallParamIndex`.

As a side effect of removing the `ValueParamPattern` insts, this fixes a
minor diagnostic bug where `NoteInitializingParam` didn't identify the
specific parameter that led to a deduction failure, because it expects
generic parameters to only be represented by `SymbolicBindingPattern`s,
but before this change they could be wrapped in `ValueParamPattern`s.
2025-03-04 21:01:59 +00:00
Dana Jansensandzygoloid 24bde46181 Change array syntax from [T; N] to array(T, N) (#4981)
In line with the proposal in #4682, this changes the array syntax to be
array(T, N). `array` is a builtin keyword which must be followed by
parens containing two expressions and a separating comma.

The array type expression is still fully builtin, it does not forward to
a Core.Array library type yet. It merely adds the `ArrayType`
instruction, as was done with the previous syntax.

Followup work will change the instruction to reference to Core.Array,
once the library type exists and can be used directly.

---------

Co-authored-by: zygoloid <richard@metafoo.co.uk>
2025-02-20 22:42:47 +00:00
Richard Smith c6d35e1c4a Rename template constant -> concrete constant. (#4939)
This implements a direction decided in a
[recent
discussion](https://docs.google.com/document/d/1Iut5f2TQBrtBNIduF4vJYOKfw7MbS8xH_J01_Q4e6Rk/edit?resourcekey=0-mc_vh5UzrzXfU4kO-3tOjA&tab=t.0#heading=h.mas1g68xx9ct)
to switch away from "template constant" when naming a constant that
doesn't depend on any generic parameters, because that creates confusion
with template-dependent constant values that depend on a template
parameter.
2025-02-12 21:24:51 +00:00
Jon Ross-Perkins 6b5eb1a101 Id::Invalid -> Id::None (#4834)
High level, replacing `Id::Invalid` with `Id::None` and `Id::is_valid`
with `Id::has_value` for clarity, as discussed
[here](https://discord.com/channels/655572317891461132/655578254970716160/1331664574545395794).
The `IntId` refactoring is needed together with `AnyIdBase` because it's
also used with `ValueStore`.

Note, trying to be careful not to rewrite `EnumBase::InvalidIndex`, or
`is_valid` in general (e.g., `IdKind::is_valid`).

I've tried to sequence commits here:

1. Automatic replacements:

- `((?:Id|Index)(?: |::|\(|Base(?:\(|::)))Invalid((?:Index)?\W)` ->
`$1None$2`
  - `<invalid>` -> `<none>`
  - `InvalidNodeId` -> `NoneNodeId`
  - `/\*invalid\*/` -> `/*none*/`
  - `id((?:_|\(\))(?:\.|->))is_valid` -> `id$1has_value`

2. Manual edits:

  - In `int.h` and `int_test.cpp`
    - `IntT` has `is_value`, which I'm renaming to `is_embedded_value`.
    - Manual edits to comments in this file.
  - `AnyIdBase` and `IdBase`
- Declaration of `is_valid` -> `has_value`, `InvalidIndex` ->
`NoneIndex`.
  - In `ids.h` and `ids.cpp`
    - `is_valid` -> `has_value`
- `// An explicitly invalid ID.` -> `// An ID with no value.`; similar
for index
    - Various math on `InvalidIndex` -> `NoneIndex`
    - Various mentions of "valid" in comments
  - In `value_store.h`, for `IdT::Invalid`, plus one comment
- In `impl.h` and `tokenized_buffer.h`, we had different initialization
of `::None` values (versus `ids.h` syntax) that I fixed manually.
  - Spot checks to compile
- Particularly where `is_valid` replacements didn't catch spots due to
different naming.

3. Autoupdate tests

4. verbose.carbon (NOAUTOUPDATE)

5. Comment spot checks

Note there are probably other mentions of "Invalid" that should be swept
up, but I'd like to argue for merging and separating out remaining
cleanup since this is so sweeping (and likely to hit merge conflicts
from churn). We'll probably have lingering mentions of "invalid" for a
bit regardless, just because there are uses of "invalid" in non-Id APIs.
2025-01-22 23:15:00 +00:00
Geoff RomerandRichard Smith 13434f0e8a Model var as a pattern operator (#4720)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-01-17 17:51:34 +00:00
Geoff RomerandRichard Smith a112cbde5c Model type expressions as regions (#4698)
This is a precondition for enabling the new pattern-matching subsystem
to support binding patterns that have `if` expressions in the type
position.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-12-19 21:41:06 +00:00
Richard Smith eabe9f117a Track complete types required by a generic. (#4652)
When a generic requires a symbolic type to be complete, add a new
`require_complete_type` instruction to the generic eval block. During
monomorphization of such an instruction, require that type to be
complete.
2024-12-10 03:00:28 +00:00
josh11bandJosh L 5d1b39e1f2 More instructions get named (#4615)
Goal is to reduce churn in names in test updates (by churning a lot of
them in this PR).

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-12-03 20:47:53 +00:00
Richard Smith bc395eb889 Represent integer literals as IntLiteral not as i32. (#4532)
When an `IntLiteral` appears as an operand of an `if` expression,
convert it to `i32` for now, so that we don't reject things like `if
cond then 1 else 2` due to having a non-constant value of type
`IntLiteral`.

For tuple indexing expressions such as `(a, b).0`, convert the index to
type `IntLiteral`, not to type `i32`. This isn't strictly necessary to
do in this PR, but avoids the need to provide an `IntLiteral` -> `i32`
implicit conversion for `no_prelude` tests using this syntax.
2024-11-15 23:24:15 +00:00
Richard Smith 980ce6b25a Convert array bounds to IntLiteral. (#4526)
Instead of leaving array bounds as whatever integer type they arrive as,
convert them to the `IntLiteral` type as part of forming an `ArrayType`.
This ensures that array types canonicalize properly even when the bounds
are specified with different types.

Create an empty generic definition for a generic builtin function to
avoid this causing "use of undefined generic function" errors.
2024-11-15 22:09:31 +00:00
4ee65ef58a Reduce the size of formatted SemIR. (#4534)
- Do not include entities imported from files that we are not dumping.
- Do not include constants and import_refs that are not referenced by
something that we are including in the formatted output.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-11-15 21:00:26 +00:00
Jon Ross-Perkins 10e256a241 Name empty tuples distinctly in SemIR. (#4503)
Building on #4502, give empty tuple values a distinct name, and also
explicitly name tuple types (previously values but not types were
named).
2024-11-08 17:14:52 +00:00
Richard Smith db76e81630 Rename IntLiteral to IntValue. (#4475)
This instruction represents integer values, whether they come from
literals or calculations, so it the old name is inaccurate. I also plan
to rename `BigInt` to `IntLiteral` based on recent discussion and this
change aims to avoid confusion stemming from the same name being used
for two different things.

I'm not renaming `FloatLiteral` because recent discussion suggests we
may want distinct `FloatLiteral` versus `FloatValue` representations in
SemIR.
2024-11-02 01:19:39 +00:00
Jon Ross-Perkins d944347e7b Elide prelude components in the IR formatter. (#4453)
This is in particular to avoid churn from changes such as #4370. I think
the import list can be helpful (particularly to understand what the
library is aware of), but it's a different trade-off for the prelude
package due to the implicit imports.
2024-10-30 22:45:26 +00:00
Brymer MenesesandJon Ross-Perkins 89eed4220f Expose indexing as a language interface (#4370)
This PR makes it so that types can implement the `IndexWith` interface
so that they can provide their custom indexing behavior.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-29 21:25:02 +00:00
Geoff Romer b67d03126e Separate inst kind for out params (#4442) 2024-10-24 15:22:32 +00:00
Geoff Romer 9266f867f9 Model the return slot as an output parameter (#4432)
Also fix `Param` insts to have meaningful names in pretty-printing, to
help clarify relationship with return slot.
2024-10-23 16:53:34 +00:00
Geoff RomerandJon Ross-Perkins 9d942f4633 Generate parameter pattern-match IR from pattern IR (#4388)
Also propagate the pattern IR along with the pattern-match IR, and use
it where appropriate.

Strictly speaking, some parts of the pattern-match IR are allocated
eagerly, while traversing the pattern's parse tree, but they still
aren't actually emitted until we traverse the associated pattern insts.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-16 19:15:29 +00:00
Richard Smith efb5d6d25a Assign locations to instructions in a generic eval block. (#4393)
The locations point to the first instruction in the generic that needed
the relevant constant value or type.

For now, this must makes the formatted SemIR a bit more useful, but in
the future it will also provide locations for diagnostics caused by
monomorphization failure.
2024-10-09 19:03:15 +00:00
josh11bandJosh L 49e0c186fc Add comma between the arguments to the bind_symbolic_name instruction (#4358)
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-01 23:58:30 +00:00
Geoff RomerandJon Ross-Perkins dc32aa2690 Initial support for binding patterns in SemIR (#4221)
Introduces the `BindingPattern` and `SymbolicBindingPattern` insts, and
a separate stack of pattern blocks that they are emitted into. The
intent is to generate the corresponding pattern-matching insts (like
`BindName`) from them in a separate pass, but that is deferred to future
PRs.

See
[here](https://docs.google.com/document/d/1U_vQH17V893J9aF1LJXUnFYBNSs2MjKl4bJPaWCB2zo/edit?usp=sharing&resourcekey=0-w0xGYZ0An31Kpz-wvzSXwQ)
for the design this is based on, but note that during review we have
chosen to deviate from that design by putting the patterns in separate
blocks, and omitting the "forward references" from a `BindingPattern` to
its corresponding `BindName`. This in turn necessitates having separate
inst kinds for symbolic and non-symbolic binding patterns.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-25 19:12:58 +00:00
Richard Smith 0354efa1fc Rework how we check calls to support deduced implicit parameters (#4302)
Instead of the `call` instruction having a block with one argument per
explicit argument, preceded optionally by `self` and followed optionally
by a return slot, change the `call` to store only the *runtime*
arguments. Store an index on the runtime parameters to make it easier to
determine the correspondence between arguments and parameters in a call.
Compile-time parameters, whether implicit or explicit, are no longer
included in the call argument list. Instead, they're tracked only in the
`specific_id` on the callee.

For calls to generic classes and generic interfaces, it no longer makes
sense to form a `call` instruction, given that the entirety of the
result is determined by the `specific_id`, which is now formed when
checking the call. Instead, the `call` instruction now only models
function calls, and not calls to other kinds of parameterized entity
names, and we create a `class_type` or `interface_type` instead of a
`call` instruction to model these kinds of calls. Notionally the model
here is that we're following the #3720 approach for calls, but for now
we inline the `Call.Op` function when forming SemIR.

We now also track the enclosing specific for a generic class or generic
interface that appears within an enclosing generic. This is necessary in
order for deduction of the inner generic parameters to not get confused
by the outer generic parameters being absent.

In order to not regress diagnostics, the template argument deduction
mechanism has been extended to specify the name of the parameter we're
deducing against when possible, and call arity mismatch errors are now
diagnosed before performing deduction rather than afterwards.
2024-09-13 21:31:43 +00:00
Richard SmithandJon Ross-Perkins 187a3608df Use As and ImplicitAs interfaces for conversions. (#4209)
Add these interfaces to the core library. For now, they're two separate
interfaces because we don't yet support one interface extending another.

This collapses a lot of the layering in check: for example, the call
building logic depends on implicit conversions, conversions now depend
on the overloaded operator machinery, and that machinery depends on
building calls.

In passing, improve the diagnostics for failing to find a name required
from the prelude. Also convert all the transitively-called code from
`NodeId` to `LocId` given the latter is what the conversion machinery
has available.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-05 23:39:58 +00:00
Jon Ross-PerkinsandRichard Smith 7ded56ef35 Improve namespace handling in imports. (#4153)
This implements a few closely related features:

- Starts merging namespaces discovered inside imports.
- Stores results of cross-package name lookup as an entry inside the
scope.
  - Note this is particularly visible with `i32`.
- Moves more of the imported instructions to the import scope.

Note this is primarily for executing the namespace TODO in check.cpp,
which is removed here.
`testdata/namespace/merging_with_indirections.carbon` tests key
behavior.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-07-24 19:56:17 +00:00
Richard Smith fc8e686607 Rebuild all constants in the eval block. (#4155)
Instead of reusing instructions from the generic entity in the eval
block, rebuild constants in the same way we rebuild types. The previous
attempt to not rebuild these constants assumed that every constant used
in a generic would be built in that generic, and not referenced directly
or referenced from some enclosing scope, which isn't true in practice
and is a fragile assumption in any case.

We could add back some reuse of instructions from the generic -- if we
happen to see the right instruction to build a constant, we could
opportunistically reuse it -- but given the complexity added by doing
so, I'm not pursuing that here.

Now that the eval block for a generic consists of instructions uniquely
owned by that generic, rather than often being shared with another
entity, include the generic in the formatted SemIR output. I'm using the
same scope name for the generic object itself as for the parameterized
class / function / interface, because there are very frequently
references between them and this keeps the IR simpler and more readable,
and avoids needing to invent a second name for the scope.
2024-07-23 21:51:08 +00:00
Jon Ross-PerkinsandGeoff Romer 07c286e3cb Use the package/library name in ImportIRId formatting. (#4154)
Also adds import_ir_scope to namespace formatting. I'd done this as an
aid for #4153, and am splitting it out.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2024-07-22 22:43:36 +00:00
Richard Smith fe359b1a08 Substitute into generic class and interface definitions when we require them to be fully defined. (#4139)
When referring to a constant within a specific, such as a field of a
generic class, use that specific version of the constant's value.
2024-07-17 01:39:25 +00:00
cd7c10b8e2 Rebuild the type of constants during evaluation. (#4138)
When evaluating in a generic context, a constant with a symbolic type
might evaluate to a constant with a concrete type (or a more specific
symbolic type). This can't actually happen yet given the current state
of the toolchain, as far as I can determine, so this is more just a
refactoring for now, but will be relied upon by future generics work.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-07-16 22:58:17 +00:00
Richard Smith 5006838f1c Build an evaluation block for the definition region of a generic. (#4131) 2024-07-16 00:16:48 +00:00
Richard SmithandJon Ross-Perkins efea072be3 Compute specific constant values. (#4128)
When forming a specific (previously called a generic instance), evaluate
the eval block of the generic to determine the values of any constants
used in that specific. The majority of the work here is updating
eval.cpp so that it can use the results of prior evaluations in the same
block when computing later values.

Include the computed results in the formatted SemIR output.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-07-15 23:59:23 +00:00
Richard Smith 7322a1e220 Build a list of dependent constants to recompute in each instance of a generic. (#4110)
For each generic, build a list of instructions describing the
computations we need to do when resolving an instance of the generic:
this is a list of the instance-specific constants and types that the
generic uses. Another way of viewing this list is as a block of Carbon
SemIR code that is evaluated in order to form an instance of the generic
-- this is referenced in the code as the "eval block" for the generic.

For each instruction in the generic whose type or value is a symbolic
constant, replace that type or constant value with a symbolic reference
that says "to find the actual type or value, look at index N in the list
of values for the generic instance".

For an instruction with a symbolic constant value, we can just add that
instruction to our list. For an instruction with a symbolic constant
type, however, we may not have a corresponding instruction computing the
type within the generic and may need to build a new instruction, but
will reuse one where possible. In the case where we build a new
instruction, we use the existing substitution code to build the type
within the eval block.

For now, this transformation is only done in the declaration region of
the generic, not in the definition region. Also, we map back from the
symbolic references to the underlying constant value in a few places
where we will eventually need to do a lookup into a generic instance, in
order to avoid regressing the tests.
2024-07-08 22:29:37 +00:00
Jon Ross-Perkins 5ebcbae2e8 Add a location to indirect imports. (#4098)
By adding an `ImportDecl` instruction, this creates something that can
be referenced through `ImportIRInst`.
packages/no_prelude/implicit_imports_entities.carbon is getting a test
of this (import_conflict and import_conflict_reverse).

Also re-packs ImportIR from 24 bytes to 16 on 64-bit, since I'm touching
everywhere that makes one anyways.
2024-07-03 17:34:39 +00:00
Richard SmithandJon Ross-Perkins 19c5596fd8 Build Generic objects for generic classes and interfaces. (#4086)
In `ClassType`s and `InterfaceType`s, track a `GenericInstanceId` for
the instance rather than just the argument list.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-06-27 20:22:10 +00:00
Richard Smith e7b0529957 Create a Generic object to represent a generic. (#4081)
Build a `Generic` object for generic functions. This object tracks the
generic parameters that are in scope for the generic entity. Eventually
it will track other information about the generic too.

Add basic SemIR formatting support for generic functions.
2024-06-26 20:13:26 +00:00
Richard Smith a699480dc9 Treat constants with symbolic type as being symbolic. (#4082)
When constant evaluation produces a known non-symbolic value, treat the
result as a symbolic constant anyway if the type of the value is
symbolic.

We don't yet have many ways to produce a constant that has a known value
but a symbolic type. The added test case is one such way: an array `[T;
0]` initialized from `()` is a symbolic constant only because its type
is symbolic -- we know its value is always `()`. More ways to form such
constants will be appearing soon as we start to support generics: for
example, a method of a generic class has a symbolic type but a known
constant value of `{}`.

When substituting into a symbolic constant, also substitute into its
type.
2024-06-26 18:46:48 +00:00