Commit Graph
71 Commits
Author SHA1 Message Date
Richard Smith 2a06c964b5 Fix formatting for imported impls. (#4194)
`impl`s may be defined even if they have no scope if they were imported.
2024-08-07 15:58:53 +00:00
Richard Smith f6ff5b11b5 Distinguish between whether an entity has its own parameter lists and whether it is generic. (#4191)
It's actually possible to get into all four combinations of having
parameter lists versus being generic:

- An entity nested within a generic, such as a member class, can be
generic even if it has no parameters.

- As a corner case, an entity with an *empty* parameter list has
parameter lists, but isn't a generic because it doesn't have any generic
parameters.
2024-08-06 15:50:27 +00:00
Richard Smith 8a8c227163 Track an interface type, not an interface ID, on an associated entity. (#4188)
This prepares us for modeling associated entities of parameterized
interfaces.

We don't use the interface parameters when type-checking `impl`s or uses
of interface members yet, but we do now check interface arguments during
`impl` lookup.
2024-08-05 20:45:14 +00:00
Richard Smith b3fcaf9969 Initial rough support for deducing generic arguments in a call to a generic function. (#4184) 2024-08-02 22:44:51 +00:00
Richard Smith 3c8fc714a8 Import support for generics and specifics (#4179)
Import generics and specifics when they are referenced by imported
entities.

When importing a generic, we import the symbolic constants required by
its eval block, and then rebuild the eval block itself given the list of
constants it needs to compute. This is likely a bit less efficient than
directly importing the contents of the eval block, but avoids needing to
either extend the importer code to be able to import the instructions
that can appear in the eval block or extend the evaluator to cope with
instructions from a different `SemIR::File`.

Importing a symbolic constant is unaffected, and does not yet preserve
the associated generic and index within that generic, so uses of a
generic from an imported IR still don't pick up values from the
specific, but the improved functionality can be seen in the changes to
the SemIR in the testcases.
2024-07-31 23:53:14 +00:00
Richard Smith 07bad72d86 Support for calling non-generic methods in a specific class. (#4156)
Use the specific parameter types for checking, and the specific return
type as the type of the call.
2024-07-24 20:27:01 +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
Jon Ross-Perkins 65d6e3e221 Use verbose formatting of instructions on crash messages. (#4125)
Changes crash messages to start printing verbose forms of instructions,
rather than just the ID. Fixes some indentation issues with stacks. Also
switches unexpected inst formatting, because now there are lots, and
it'd be helpful to know where they are.

This uses a pimpl pattern for Formatter due to the number of member
functions on Formatter. Maybe we should refactor that, but this didn't
feel like a good place to do so.

Note, I have two concerns about this change... to note them here, to
make sure others are considering them when evaluating the
implementation:

1. Some instructions are very verbose to print, as evidenced by the
fn_decl printing (which includes function params) or scope printing
(which includes scope members).
- I'm not sure whether there's a way to simply reduce this, as it seems
essential to the requested printing of instructions.
- Long-term, we may at least want to limit the number of lines printed
here. However, I've already spent a fair amount of time here and I think
it's in a good state to evaluate.
2. Increased complexity in the crash handler may result in crash
messages failing to generate.
- For example, a crash in Formatter (and its deps, such as InstNamer or
location handling) prevents a stack from being printed. I'm pretty sure
I've written crashes in Formatter before.

Here's an example crash snippet (generated by adding a crash inside
`return` handling) before:

```
2.	NodeStack:
	0.	FunctionDefinitionStart -> function2
	1.	ReturnStatementStart -> no value
	2.	IntLiteral -> inst+26
inst_block_stack_:
	0.	block<invalid>	{inst+0, inst+1, inst+2, inst+23}
	1.	block9	{inst+26}
param_and_arg_refs_stack:
args_type_info_stack_:
```

And after:

```
2.	Check::Context
          NodeStack:
            0. FunctionDefinitionStart: function2
            1. ReturnStatementStart: no value
            2. IntLiteral:
              unexpected.inst+26.loc12_10: i32 = int_literal 0 [template = constants.%.2]
          inst_block_stack_:
            0. block<invalid> {
                package: <namespace> = namespace [template] {
                  .Core = unexpected.inst+2
                  .F = unexpected.inst+23.loc11_22
                }
                unexpected.inst+1 = import Core
                unexpected.inst+2: <namespace> = namespace unexpected.inst+1, [template] {}
                unexpected.inst+23.loc11_22: %F.type = fn_decl @F [template = constants.%F] {
                  unexpected.inst+9.loc11_9: init type = call constants.%Bool() [template = bool]
                  unexpected.inst+10.loc11_9: type = value_of_initializer unexpected.inst+9.loc11_9 [template = bool]
                  unexpected.inst+11.loc11_9: type = converted unexpected.inst+9.loc11_9, unexpected.inst+10.loc11_9 [template = bool]
                  unexpected.inst+12.loc11_6: bool = param b
                  @F.%b: bool = bind_name b, unexpected.inst+12.loc11_6
                  unexpected.inst+19.loc11_18: init type = call constants.%Int32() [template = i32]
                  unexpected.inst+20.loc11_18: type = value_of_initializer unexpected.inst+19.loc11_18 [template = i32]
                  unexpected.inst+21.loc11_18: type = converted unexpected.inst+19.loc11_18, unexpected.inst+20.loc11_18 [template = i32]
                  @F.%return: ref i32 = var <return slot>
                }
              }
            1. block9 {
                unexpected.inst+26.loc12_10: i32 = int_literal 0 [template = constants.%.2]
              }
          param_and_arg_refs_stack:
          args_type_info_stack_:
```
2024-07-17 22:05:19 +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
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 6d3c915bbf When performing name lookup, determine the generic instance within which the lookup result was found. (#4118)
Require types into which qualified lookup is performed to be completely
defined. Eventually this will trigger substitution into the definition
for generic types.
2024-07-10 18:35:55 +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 9581a1867d Move import refs to their own block. (#4103)
This executes on a TODO in AddImportRef to add instructions to their own
block instead of the File block. This has an important consequence of
removing a pattern from InstBlockStack that added to blocks not
currently at the top, cleaning up an issue for ArrayStack. The delta
here is then mostly in different formatting of the import refs, a
consequence of the separation.
2024-07-03 18:21:12 +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 Smith 10a198a9e6 Use the correct type for Self in generic classes and generic interfaces (#4087)
In a `class C(T:! type)`, the type `Self` should be `C(T)`, not merely
`C`. Similarly, in an `interface I(T:! type)`, the type of self should
be `I(T)`, not merely `I`.
2024-06-28 20:20:40 +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
Geoff Romer 5a8dfda4f0 Diagnose missing definitions in impl files (#4079) 2024-06-26 18:57:37 +00:00
Chandler CarruthandRichard Smith b70cfd0be9 Remove another hashtable iteraiton order dependency. (#4070)
Name scopes store the names in their scope in a `DenseMap`. Several
places reasonably avoid depending on the iteration order by sorting the
names -- they're in the formatting code path where that's a solid
approach.

Unfortunately, when we're importing one scope into another, we also need
to walk the entire scope and do something for each name. =[ This doesn't
seem like a great place to sort things to stabilize them.

I've switched to a fairly simplistic solution of having a vector of name
entries that can be iterated stably, and a separate map for lookups. I
didn't use the set-of-indices trick here because it's not clear that's
the right trade-off for a scope: likely a lot of small scopes here with
relatively hot name lookups. And the key here isn't a large or
dynamically sized thing that we're canonicalizing, it's a `NameId`. That
made me lean towards duplicating the name in the hashtable for lookup
and the vector for iteration.

I thought about a fancy approach of sorting the hashtable keys by their
values (the indices), but that would still require a bit of copying and
more code.

I also thought a bit about other optimizations, but decided to leave a
comment for now -- it's not obvious to me exactly how hot this is and
whether it's better served by faster lookups, being more memory dense,
etc. And that might involve more of an SOA layout change or some other
approach. Rather than do that here, and especially before switching
hashtables, I stuck with a simple approach to address the ordering.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-06-21 22:13:03 +00:00
Richard Smith d18584c6c2 Make representation of call to a generic class / interface more uniform. (#4050)
Model such calls as call operations, and compute the resulting type in
constant evaluation rather than in type-checking. This means we no
longer form non-constant `ClassType` or `InterfaceType` values, and that
we produce an `<error>` type in the case of bad argument lists rather
than a broken / meaningless `ClassType` / `InterfaceType` that doesn't
actually represent a type. This in turn suppresses some follow-on
diagnostics.
2024-06-13 21:24:36 +00:00
f772c1f5f3 More support for generic interfaces, aiming for parity with support for generic classes. (#4034)
This is mostly mechanically duplicating work done for generic classes to
also support generic interfaces.

Also fix both generic interfaces and generic classes to support
importing class and interface types with arguments from another file.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-06-07 18:24:35 +00:00
Richard Smith 1c07f959a8 Format types in SemIR using the formatting for their instruction. (#4035)
Don't use the pretty-printed type name, because that's intended for
diagnostics, not for a theoretically machine-readable format like SemIR.

Types are always constants, so omit the leading `constant.` on the type
instruction name.
2024-06-06 15:12:48 +00:00
Richard Smith 9a11e977b3 Improve formatting of the type of a function or generic class name. (#4033)
Don't format the *type of* the function `F` as `"F"`. Instead use
`"<type of F>"`.

Also improve instruction naming for function and generic class name
values: name the value after the function or generic class, and add a
`.type` suffix to the type.
2024-06-06 00:40:43 +00:00
Richard SmithandJon Ross-Perkins 7792e5fce3 Support out-of-line definitions of members of generic classes and interfaces. (#4029)
Check the parameters specified in a name qualifier against the
parameters of the entity that the qualifier refers to.

For interfaces, this required adding minimal support for parameterized
interface names.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-06-05 18:52:17 +00:00
Jon Ross-Perkins 83413479d7 Move some of the test information to TIP lines (#4007)
This has is a nice-to-have for me. Frequently I want to run a specific
test, and end up digging through output to be able to copy-paste the run
line. This uses TIP lines to inject the command into the file when using
AUTOUPDATE.

Note, one of the reasons I want this is because "bazel test
//toolchain/testing:file_test --test_output=all" has been regularly
exceeding bazel's output limit for me (workaround is either opening the
output file or specifying an obscure output limit flag), making it a
little harder for me to get the commands. However, frequently I'm adding
a file and want to iterate on it, so that's really the use case I have
in mind here.
2024-06-04 17:57:23 +00:00
Richard Smith 28cefe98df Factor out pushing / popping of names plus parameters. (#4005)
Previously we did some of this in decl_name_stack and some of it in the
callers of decl_name_stack. Factor out a single place to pop a name and
its optional following parameters.

Part of making this behavior consistent is that we now track whether an
implicit parameter list was present or absent rather than mapping an
absent list to `InstBlockId::Empty`. This improves our redeclaration
checking and the precision of some diagnostics.
2024-05-30 16:05:35 +00:00
Jon Ross-Perkins 55300d1ebb Switch type literals to use builtin functions. (#3978)
Modifies the core package and literal handling to use factory functions
for standard type literals.

Updates function/builtin/import.carbon to stop depending on the prelude,
since it would list all the impls in the core file. Updates
alias/builtins.carbon to be failing (the type values cannot be aliased).
2024-05-23 16:00:08 +00:00
Jon Ross-Perkins 3561ab5fae Switch the prelude to using 'export import'. (#3976)
Note, I assume this doesn't affect all the TODOs (like for i32.carbon),
but does cut some things down (and requires updating some tests that
have prelude name conflicts, but I think they were intended to be
updated this way).
2024-05-22 22:55:31 +00:00
Richard Smith 23f9065949 Implement proposal #3927. (#3963)
Change syntax for package declaration to put the `impl` keyword at the
start and remove the `api` keyword.

To support this, rearrange processing of package, library, and import
declarations to use the general modifier handling support in declaration
parsing rather than special-case logic.

There is an ambiguity in `impl package.Foo as Bar`, which we resolve by
treating `package` as an introducer after a modifier only if it's not
followed by `.`.
2024-05-21 00:36:03 +00:00
Chandler Carruth bc370a771d Avoid relying on a hashtable iteration order. (#3960)
The toolchain was iterating a map of package name to import list in a
couple of places to do things beyond counting or other order-invariant
operations. The result was that the specific hashtable iteration order
influenced the order of SemIR generated (and other behaviors like
diagnostic emission I suspect, but the source location sorting probably
hid this). Switching to a hashtable implementation with any order
seeding that changes run-to-run immediately shows the SemIR order
fluctuating without this.

This PR fixes that by instead accumulating the package imports data in a
vector and using a map to vector indices. This is also slightly more
efficient, although that seems unlikely to be an important factor here.

There was only one insertion point so I've just hand coded the
management of the indices and map, but happy to take a different
approach or use an abstraction here if desired.

One awkward aspect of this is that some of the loops need access to the
package name as well. I've just added storage for that as these seem
unlikely to be huge arrays of 10s of 1000s of imported packages, so the
double storage of the identifier ID seems likely OK. But again, happy to
take a different approach here if desired. It also seems like it might
be possible to work out the identifier from the node, but I kept the
patch more direct for simplicity.

I've also not used the LLVM `MapVector` abstraction of this pattern.
This was mostly to avoid adding another layer of abstractions to our
data structures, and because this is the first time we've hit this
really. My experience is also that it is reasonably often that there is
a more efficient way to orient the vector and map than what is
automatically provided. But that may just be my experience.
2024-05-20 16:02:25 +00:00
Richard Smith d5c0c9cfe3 Accept generic parameter lists in class declarations. (#3933)
Check that they match across redeclarations.

Fix some importing bugs for symbolic bindings which were uncovered when
testing this.
2024-05-04 02:08:38 +00:00
Jon Ross-Perkins 92fa0ac1ac Remove ImportRefUsed (#3934)
This was to track use of a declaration after import, prior to a
redeclaration. Per [discussion on
Discord](https://discord.com/channels/655572317891461132/1217182321933815820/1236016521059237962),
we likely don't need this check due to the change in behavior of
`extern`.

Rather than potentially getting one of many `extern` decls and depending
on it by accident, it is now planned to be _required_ to be imported,
and the library doing a non-`extern` decl must _know_ it's importing the
`extern` decl. The stricter requirement on the library means it now
seems more reasonable to use the `extern` decl.

So kind of rolling back #3831, though keeping `ImportIRInstId` (at least
for now) and keeping `Loaded`/`Unloaded` terminology (seems a nicer
fit).
2024-05-03 23:33:42 +00:00
Jon Ross-PerkinsandRichard Smith 76ed3c73cb Promote FunctionType to a standard instruction. (#3931)
This removes the builtin FunctionType, replacing it with a FunctionType
instruction. The constant for a FunctionDecl is now a StructValue with
type of FunctionType.

Note this means a function declaration produces _both_ a type, and a
value of the type. This has some consequences in terms of circularity,
and makes the importing of function declarations a little more complex.

It'll get particularly peculiar for imports because of the behavior of
the reference, but that's a known issue due to other things such as
`alias`. The impact will hopefully be contained to
ResolvePrevInstForMerge (and ImportRefs).

To note a small formatting change in diagnostics:

```
-  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated <function> in Interface>` is not callable.
+  // CHECK:STDERR: fail_member_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated F in Interface>` is not callable.

-  // CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated <function> in Interface>` is not callable.
+  // CHECK:STDERR: fail_todo_facet_lookup.carbon:[[@LINE+4]]:3: ERROR: Value of type `<associated F in Interface>` is not callable.
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-05-03 15:18:04 +00:00
Richard Smith 008d41d7f3 Move instruction names for struct and tuple values from lower to InstNamer. (#3918)
Change the names for emitted globals for constants with storage to
include both the name of the constant and the name of the use.

This causes the instructions to also be named in SemIR and in LLVM IR
constants.
2024-04-26 23:47:08 +00:00
Jon Ross-Perkins de4c32beb5 Split apart some tests which don't need the prelude. (#3904)
This could probably go further, but I'm just trying to get the ability
to run some significant tests without the prelude. This already requires
some migration of `i32` and `bool` to non-prelude-dependent types
(technically not at the moment, but I'm trying to stick with the
philosophical model of the prelude).

Note this undoes part of #3895 which had made all lex/parse tests depend
on the prelude -- I don't think that was a necessary change. Rather, it
seems better to isolate individual lex/parse tests from the prelude. I'd
been on the fence in that PR (it was fixing one of the issues that
contributed to wanting to not include the prelude), but now it feels
more consistent. The prelude could have a parse error and we shouldn't
break every parse test on that.
2024-04-24 20:16:48 +00:00
Richard SmithandJon Ross-Perkins 62fe0cd385 Remove the builtin IR, and instead define builtin types locally. (#3910)
We don't need it any more, and removing it simplifies a few things:

- One fewer predefined `File` and reserved ID.
- We now have simply `Builtin` instructions for builtins, instead of
having an `ImportRef` that indirectly references a `Builtin`.
- `ConstantId`s now always refer directly to a local constant, instead
of sometimes referring to an `ImportRef` for a constant in the builtins
IR.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-04-24 18:32:59 +00:00
Richard Smith ccf87f0a38 Use computed constants in lowering rather than lowering instructions (#3905)
First steps towards using constant values in lowering.

For now, we reuse the regular instruction lowering to lower constants.
This mostly works, because we don't actually need an `llvm::Function` or
a current basic block when lowering a constant most of the time.
However, a special case is needed for lowering aggregate value constants
because they would otherwise create a stack alloca to store the
constant. Separate constant lowering code will be added in a future
change to clean this up.

When lowering a constant initializing expression, the result is a value
of the destination type, rather than code to initialize the destination,
so a separate copy step is required when finishing initialization from a
constant for a type that uses in-place initialization. Handling this
required extending `ReturnExpr` to track its destination location.

We currently often create non-constant `*_access` SemIR instructions
that are only used by constant `*_init` instructions. These cause
lowering to leave behind `getelementptr` instructions in the lowered IR
that are now unused. It should be possible to detect this case and avoid
producing these instructions, or to produce them lazily, but for now
we're just leaving them around for LLVM to clean up.
2024-04-23 16:23:24 +00:00
Richard Smith e0b8728263 Allocate de Bruijn levels to symbolic bindings. (#3906)
Use a level comparison during substitution to determine whether we're
substituting a particular binding. Evaluate symbolic bindings with the
same name and the same level to the same symbolic constant, for example
across redeclarations of a generic function.
2024-04-23 16:15:47 +00:00
Jon Ross-Perkins 76a5cf5f50 Fix incorrect application of invalid type on imports. (#3902)
In handle_class and handle_interface we assign TypeType, so is more
consistent. I think this had been missed because we haven't really been
using these declarations (historically, declarations didn't have a
type). It seems not to significantly affect output at present, although
I found this while trying to change merge behavior.
2024-04-22 20:34:27 +00:00
Richard Smith 3776c068de Unify instruction naming between SemIR and LLVM IR (#3898)
Factor out `SemIR::InstNamer` and also use it when lowering to LLVM IR.
Automatically name all instructions created with our `IRBuilder` based
on the name computed by the `InstNamer`, and likewise name basic blocks
using the label generated by the `InstNamer`.

Move some of the existing naming logic out from lower into `InstNamer`
so that it's also used in SemIR. In particular, we now name call
instructions after their callee, or after the builtin name for calls to
builtins.

Computing and adding these names isn't completely free. This instruction
naming is designed to be optional, so that we can turn it off for builds
where the LLVM IR will only be converted to assembly and won't be seen
by a human, but so far it's enabled unconditionally. We can tune that
later as needed.
2024-04-19 02:19:30 +00:00
Richard Smith 015c7c780c Fix location of converted inst for explicit as conversion. (#3887)
Use the complete location of the `as` conversion rather than the
location of the first operand, so diagnostics referring to the result
point at the whole thing.
2024-04-15 23:22:44 +00:00
Richard Smith 1b335402d1 Allow incomplete return types in function declarations. (#3875)
Move completeness check to the point where the function is defined or
first called. This means we also defer deciding whether the function has
a return slot until that point. Instead of storing a return slot per
function, store the location of the return storage, which may or may not
be used, and compute and store a separate flag saying whether to use it
at the point of first use or definition.

This is the final piece in supporting simple `Make` functions in classes
as a replacement for constructors.
2024-04-11 07:23:56 +00:00
Jon Ross-Perkins 895e90e791 Start including the prelude for testing. (#3861)
- Adds an empty prelude.carbon file
- Imports that file in any non-Core package file
  - Adds --disable-prelude-import to avoid that
- Adds --exclude-dump-file-prefix to be able to hide files from dumping
- Used to hide core files (we can't do this by package name due to lex
dumps, for example)
- Restructures some tests to not rely on `i32`, particularly `alias`
tests (which rely on a name ref) and tests with no prelude.

I'm adding the framework for switching i32 to calling Int32 in the
prelude, but I'm running into a separate error actually switching over.
So that *mostly* works, but isn't quite ready for prime time. However,
maybe the current state of this PR is still useful to review since it
does a lot of the infrastructure work and adds the %Core everywhere?
2024-04-07 17:11:42 +00:00
Richard SmithandJon Ross-Perkins c26241cd03 Import all impls in imported IRs. (#3865)
This allows impl lookup to find such impls.

Eventually we'll want to do this more lazily, and filter to the relevant
subset of `impl`s needed for a query. But for simplicity, for now just
import all `impl`s.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-04-05 18:47:55 +00:00
Richard SmithandJon Ross-Perkins f9ce0b194d Defer parsing of method bodies until the end of a suitable enclosing scope. (#3832)
In parse, form a list of methods that are defined inline, tracking where
they start, where they end, and which other inline methods are nested
within them.

In check, when we reach an inline method body, skip it and add it to a
worklist to be processed later. We also track when we reach the start
and end of a context in which inline method bodies are deferred, so that
we know when to replay the bodies.

When suspending a function definition to be processed later, the
`DeclNameStack` entry is moved to separate storage, including popping
the corresponding scopes from the scope stack and removing the
corresponding lexical names from lexical lookup. Later, when we return
to the function and parse its definition, the `DeclNameStack` entry is
restored. The same is done when we reach the end of a nested context
that can have inline methods, so that we can reenter the nested scope
before processing its members.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-04-01 18:25:27 +00:00
Richard Smith e8cc089b2b Allow simple uses of Self in impls. (#3824)
Per #3714, some of the details here are not yet settled. In particular,
we might want `Self` to come into scope at the start of the definition,
not at the `as` keyword. However, this change allows us to accept the
uncontroversial examples.
2024-03-27 22:52:45 +00:00
Jon Ross-Perkins b8ceb8dd8b Print a blank line after a diagnostic. (#3806)
The purpose of the newline is to make it clearer where a given
diagnostic begins and ends, particularly as the first message of a
diagnostic may not be the error.

This is a trivial code change, but ripples edits through test files.
2024-03-22 18:10:49 +00:00