Commit Graph
12 Commits
Author SHA1 Message Date
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