Commit Graph
3791 Commits
Author SHA1 Message Date
Thomas Köppe bf32da8dad Add missing standard library header inclusions (#5316)
Discovered by clang-tidy.
2025-04-17 15:37:57 +00:00
David Blaikie f45a632d77 Implement virtual call dispatch (#5308)
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.
2025-04-17 14:42:30 +00:00
Richard SmithandJon Ross-Perkins 48dc411776 Stop using Add*InstInNoBlock during import. (#5317)
`Add*InstInNoBlock` adds an instruction in the current context,
including adding its type and constant to the current generic eval block
if necessary. This is inappropriate during import, because the current
generic is generally not related to the instructions we're importing.

Previously we worked around this by pushing a placeholder generic onto
the generics stack, but that workaround doesn't interact well with
building generics incrementally. Instead, change the import code to
create instructions directly instead of via `Add*InstInNoBlock`.

This also allows a little simplification, because all the import logic
created imported instruction locations in the same way.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
v0.0.0-0.nightly.2025.04.17
2025-04-16 23:56:08 +00:00
Jon Ross-Perkins 401c72a5c3 Allow no-op functions to have unused arguments (#5318)
For example, we might want `[self: Self]` to be ignored.
2025-04-16 22:03:21 +00:00
Jon Ross-Perkins 4923445e3a Drop Singleton from ErrorInst::SingletonInstId and similar (#5304)
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`.
v0.0.0-0.nightly.2025.04.16
2025-04-15 22:40:29 +00:00
Jon Ross-Perkins 838417e358 Update check_deps roots (#5311)
- Add pkg rules to the search, specifically so that we can pull the full
release tar instead of the busybox binary.
- Shift the tree_sitter exclusion to the script, so that it's easier to
use the script.
- tcmalloc_if_linux_opt isn't really interesting (it's referenced by
.bazelrc).
- Misc tiny changes to the query, just to simplify it.
2025-04-15 22:33:29 +00:00
Jon Ross-Perkins 72cfaad1c7 Remove the indirect_value library (#5312)
This was used by explorer, and no longer has uses.
2025-04-15 20:16:58 +00:00
Jon Ross-Perkins dc8fab1d81 Refactor PerformCall (#5302)
`PerformCall` has gotten a little long, 130 lines; splitting out some
functions to help size. `PerformCallToFunction` in particular seems
symmetric with `PerformCallToGenericClass` and
`PerformCallToGenericInterface`.
2025-04-15 17:20:32 +00:00
Jon Ross-PerkinsandChandler Carruth b49e89e97e Add a no-op builtin function which shouldn't generate code. (#5306)
This is part of a broader plan to have noop destructor functions for
trivial destruction.

Note this emits a SemIR call (`%no_op: init %empty_tuple.type = call
%NoOp.ref() [concrete = constants.%empty_tuple]`), but not LLVM IR. My
thought was this was probably okay, since even though it'll be a little
spammy with destructor calls, the flipside is there'll probably already
be a fair amount for the name reference, and this at least shows when
the call is injected (and discarded).

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
v0.0.0-0.nightly.2025.04.15
2025-04-15 00:33:39 +00:00
Dana Jansens da83b65aa2 Concrete impl takes precedence over a facet value (#5305)
If a concrete impl is found via lookup, its associated constants should
be used over the constants found through a facet value.
2025-04-14 18:48:55 +00:00
Dana Jansens afa946aefa Specialization test with final assoc constant can pass now (#5303) 2025-04-14 16:10:17 +00:00
Alina Sbirlea 02e9ac21bf Fix type when lowering associated constants. (#5295)
Get type in specific when lowering associated constants. This resolves
crash when getting type for type_id is not found, when the query is for
a specific.
Note: Currently lowering only supports mangling of impls that can viewed
as a single interface (single ImplConstraint).
2025-04-14 15:55:12 +00:00
Dana Jansens eabe1cf9b8 Avoid crashing when a NamespaceType is in a type structure (#5301)
NamespaceType is not valid to use as an argument for generics, but when
it's there handle it gracefully through to the diagnostic.

Found by fuzzer.
2025-04-14 14:59:27 +00:00
Jon Ross-Perkins 55da026a46 Remove the SemIRLoc typedef (#5299)
Replace SemIRLoc typedef uses with explicitly SemIR::LocId, loc ->
loc_id for consistency.
2025-04-14 14:28:15 +00:00
Jon Ross-Perkins 77cbcd0aa8 cc_toolchains has defs.bzl, fix references (#5297) 2025-04-14 14:22:02 +00:00
Jon Ross-Perkins 9759387a13 Collapse GetAbsoluteNodeId overload (#5298)
Since LocId can handle a NodeId, this overload isn't really needed
anymore. Probably helpful to simplify.
v0.0.0-0.nightly.2025.04.14 v0.0.0-0.nightly.2025.04.13 v0.0.0-0.nightly.2025.04.12
2025-04-12 00:30:19 +00:00
Dana Jansens f0663715dd Even more usage of TypeInstId (#5296)
Use TypeInstId in many more places where the instruction is required
to/known to always be a type value. This should be a somewhat exhaustive
set of places, as it covers all instructions given to
GetTypeIdFromTypeInstId().

The things of interest here are:

- Singleton instructions are always of type TypeType, so they are now
TypeInstIds.
- ErrorInst::SingletonInstId gets upcast to be an InstId because it's
sometimes used to define the type of a variable (as in `auto inst_id =
SemIR::ErrorInst::SingletonInstId;` that may hold other InstIds.
- Parse nodes don't really know about TypeInstId, so NodeStack::Push
needs to do some special casing to avoid CHECK failures when given a
TypeInstId but expecting an InstId. We leave a TODO behind here because
the nodes which are being pushed a TypeInstId should probably be taught
to expect that, but such a change is a bit tricky, so too much for this
PR.
2025-04-11 21:47:43 +00:00
Dana JansensandRichard Smith 0e8d354567 Split the witness table into a separate ImplWitnessTable instruction (#5272)
This allows us to import the table for a given impl only once, while we
can import many ImplWitness instructions with different specifics for a
generic impl.

For example in convert_facet_value_to_narrowed_facet_type.carbon we see
that a single witness table is imported for the BitAnd interface, with
multiple witnesses (for different specifics) imported and sharing the
same table.

The ImplWitnessTable now contains a back-link to the Impl the witness is
for, allowing inst namer to name that interface in the textual semir,
and allowing the interface to be found when debugging from a witness.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-11 20:30:04 +00:00
Dana Jansens c34a8d0a3a Convert remaining type-value InstId fields to TypeInstId (#5294)
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`.
2025-04-11 20:11:03 +00:00
Jon Ross-Perkins 8c3fa80691 Add cc rule wrappers for cc_env (#5277)
Rules executed by bazel don't necessarily have the right environment to
find the symbolizer, which was the intent of `cc_env` setting
`LLVM_SYMBOLIZER_PATH`. So far, this has kind of been a case-by-case
fix, but every so often I'm trying to debug a crash in a test that
doesn't provide it. Rather continuing down this route, instead add
drop-in wrappers for cc rules so that it's hard to forget.

Note `bazel/cc_rules` is intended to mirror `bazel/carbon_rules` and
`bazel/cc_toolchains`, rather than `@rules_cc`.

AFAICT there isn't a great way to add this as a default for the `bazel
run` environment. It's not typically going to be set on its own,
forwarding `$PATH` would be too broad, and the [action
`env_sets`](https://bazel.build/docs/cc-toolchain-config-reference#using-action-config)
I think are not quite what we need (I think those don't include output
execution, only compilation).
2025-04-11 19:58:54 +00:00
Jon Ross-Perkins faeb024462 Remove explorer deps from MODULE.bazel (#5293)
These are only used by explorer, which is being removed by #5290
2025-04-11 15:49:33 +00:00
Jon Ross-Perkins ea130f1e73 Remove explorer/ and installers/ directories (#5290)
References were removed by #5287, #5291, and #5292; this is just
deleting the directories themselves.

Note this does not change anything else (e.g. removing things in
MODULE.bazel that were only used by explorer). I'm trying to make a pure
delete that's easy to review.
2025-04-11 15:36:50 +00:00
Jon Ross-Perkins fe29224016 Refactor LocId to merge in SemIRLoc (#5284)
The main goal of this is to collapse the LocId and SemIRLoc types into a
single type, eliminating the need for APIs to decide which to use. This
originated from discussion about UnwrapSemIRLoc in #5169. Although that
was removed in #5202, it's probably still a good direction for LocId.

This changes the packing of LocId to allow adding InstId, making it
tri-modal: ImportIRInstId, InstId, or NodeId. This has a side-effect of
reducing the available space for ImportIRInstId, although not by much
due to the pre-existing `ImplicitBit` behavior. If needed, we could also
probably play with packing a bit more since `ImplicitBit` really only
applies to `NodeId`, but I was trying to keep the logic a little
simpler. Note `TokenOnlyBit` can still apply to `ImportIRInstId`.

This leaves in place a typedef for SemIRLoc -- I intend to clean that up
separately.

Some Discord discussion is
[here](https://discord.com/channels/655572317891461132/655578254970716160/1353755830058745959).
2025-04-11 13:35:58 +00:00
Jon Ross-PerkinsandRichard Smith 422df75a92 Switch tree-sitter from explorer to toolchain testdata (#5292)
Noticed as part of #5290; `srcs` is needed to make `$(locations)` work.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
v0.0.0-0.nightly.2025.04.11
2025-04-10 23:45:19 +00:00
Dana JansensandRichard Smith cf57c85545 Introduce TypeInstId (#5288)
TypeInstId is an InstId whose constant value has a type of TypeType.
This includes:
- Type value instructions, the `ClassType` or `IntLiteralType`
instructions.
- Constraint value instructions, which are the `FacetType` and
`TypeType` instructions, each of which also have type TypeType.

TypeInstId encodes in the type system that it is safe to convert the
instruction's value to a TypeId, and CHECKs at construction that this
invariant is maintained.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-10 22:59:02 +00:00
Jon Ross-Perkins 03a31bd0de Drop explorer from website (#5291)
Noticed this while preparing #5290, I think it can be split out.
2025-04-10 22:55:38 +00:00
Jon Ross-PerkinsandRichard Smith a94136d477 Remove references to explorer (#5287)
I'm doing this separately from removing the explorer/ and installers/
directories so that it's easier to review the side-effects.

Note for the main README, I didn't think it was worth keeping a mention
of "used to have a prototype interpreter, now archived" versus focusing
on the existing toolchain (for "Currently, we have fleshed out").

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-10 22:05:45 +00:00
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
Dana Jansens 1445ec9e4f Remove toolchain/check/testdata/impl/fail_impl_as_scope.carbon (#5289)
The same things are tested in
toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon,
along with more cases.
2025-04-10 20:06:49 +00:00
Richard Smith 47fa1b5991 Rename StringifyType to reflect that it can stringify non-type constants. (#5285)
Use it to stringify associated constant values in diagnostics. In
passing, add missing support for stringifying bool literals. Note that
there are some cases that it doesn't stringify properly, but that's not
new here; such cases could already be observed when stringifying generic
arguments.
2025-04-10 19:15:27 +00:00
Dana Jansens aec90e3ae1 Rename rewrite_value to rewrite_inst_id to clarify what it's holding (#5286)
Also add a note about the RewriteConstraint insts being canonical
2025-04-10 16:42:24 +00:00
Dana JansensandRichard Smith 76c68153a2 Look for final impl when accessing associated constant in facet (#5269)
While facets may come with a rewrite for an associated constant, they
are symbolic. A final impl has the ability to provide a concrete value
instead, which allows generic code to use the concrete value in place of
the associated constant's (fully qualified) name.

For instance, instead of `I.Type`, the concrete type `()` can be used if
there is an `impl final [T:! type] T as I where .Type = ()` impl.

This does not yet cache the result of the lookups.

Depends on https://github.com/carbon-language/carbon-lang/pull/5255

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
explorer-archived
2025-04-10 13:48:49 +00:00
Boaz Brickner 68111a994c C++ Interop: Basic C++ record (class/struct/union) import support (#5156)
Focus: Calling static C++ function defined in C++ classes.

Limitations:
* Ignores visibility (public / protected / private).
* No support for: dynamic classes, member methods, data members,
declarations without definitions, importing inheritance.

Based on #5142.

C++ Interop Demo with a class:

```c++
// hello_world.h

namespace some_namespace {

class MyClass {
 public:
  static void hello_world();
};

}  // namespace some_namespace
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

namespace some_namespace {

void MyClass::hello_world() { printf("Hello World!\n"); }

}  // namespace some_namespace
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.some_namespace.MyClass.hello_world();
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
Hello World!
```

Part of #5150.
2025-04-10 08:15:12 +00:00
Richard Smith a91752de60 Represent rewrite constraints in FacetTypeInfo with InstId not ConstantId. (#5281)
This follows the pattern used elsewhere, and allows facet types in eval
blocks to directly reference their operands instead of doing so
indirectly via a `ConstantId` attached to the generic. This prepares us
for making `ConstantId`s always be unattached.

In passing, add a stringified version of the `InstId` to diagnostics in
a couple of places where it seems useful.
2025-04-10 03:56:12 +00:00
Dana Jansens c15dea4fa2 Stop erasing ImplWitnessAssociatedConstant instructions from the witness table (#5283)
Unintentionally, we were adding ImplWitnessAssociatedConstant to the
witness table and then immediately evaluting and replacing it with its
constant value instruction, which is incorrect. The point of the
instruction is to be a symbolic value in the witness table that is a
dependent of the generic impl declaration being built.
v0.0.0-0.nightly.2025.04.10
2025-04-09 23:03:45 +00:00
Richard Smith 6322c7734e Don't define an unscoped enumeration out of line. (#5282)
The C++ language semantics for doing so are weird and a bit broken.
Under
[CWG1485](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1485)
this code may become invalid in the future.
2025-04-09 22:41:31 +00:00
Jon Ross-Perkins a527626d87 Add tests and range enforcement for current LocId use-cases (#5274)
This is trying to document the status quo. Note
https://github.com/carbon-language/carbon-lang/pull/4497 placed
restrictions on a bit, and this is in part flowing back to restrictions
on both NodeId and ImportIRInstId limits.
2025-04-09 17:41:37 +00:00
Alina Sbirlea 7da972b773 Create a single global for the PrintInt format string. (#5275)
Create a single global for the PrintInt format string. Cleaner tests.
2025-04-09 16:47:32 +00:00
Alina Sbirlea 694a329bdd Reuse LLVM global constants. (#5273)
Reuse LLVM global constants: do not generate a new llvm::Global constant
for a pointer to a global constant for the same Carbon const_inst_id,
reuse already generated one.
2025-04-09 16:36:42 +00:00
Dana JansensandJon Ross-Perkins 20444c0103 Move explorer out of toolchain git repo (#5270)
The explorer is an archived codebase, without a plan to restart
development on it. The costs incurred by keeping it in the main git repo
can be alleviated by moving it to a new sibling repo, without
diminishing the usefulness of the explorer codebase for demonstrating
implementation of the carbon language design.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-04-09 13:35:53 +00:00
Boaz Brickner 817dacfc77 Fix clang-tidy: function 'rewind' has no error detection; 'fseek' should be used instead [bugprone-unsafe-functions,-warnings-as-errors] (#5265) 2025-04-09 13:17:26 +00:00
Ivana Ivanovska 7580df8b8a [Carbon/C++ interop] Add support for int function params (#5197)
Added support for `int` function parameters. Currently only
pass-by-value is supported.

```c++
// hello_int.h;

auto foo_int(int a, int b) -> int;
```

```c++
// hello_int.cpp

#include "hello_int.h"
#include <cstdio>

auto foo_int(int a, int b) -> int {
    printf("a = %i \n", a);
    printf("b = %i \n", b);
    return a + b;
}
```
```c++
// main.carbon

library "Main";

import Cpp library "hello_int.h";
import Core library "io";

fn Carbon_foo(b: i32) {
  Core.Print(b);
}

fn Run() -> i32 {
  Carbon_foo(Cpp.foo_int(2, 8));
  return 0;
}
```

```
$ clang -c hello_int.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_int.o main.o --output=demo
$ ./demo
a = 2 
b = 8 
10
```

Part of  #5064
2025-04-09 11:38:39 +00:00
Richard Smith 1a4d6ca255 Store an InstId instead of a TypeId in UnboundElementType. (#5260)
This gives a slightly simpler representation for `UnboundElementType`s
in eval blocks, and in principle allows us to preserve the spelling of a
field's type into the `UnboundElementType` and thereby into a field
reference, although as of right now this doesn't affect our diagnostic
output in any way.

During error recovery for a field with a non-concrete type, preserve the
type in the `UnboundElementType` regardless. It's not really problematic
to have a non-concrete type there, and this makes it easier to track the
instruction used to specify the type.

This is a step towards switching symbolic types to always be abstract
during type checking.
v0.0.0-0.nightly.2025.04.09
2025-04-08 22:21:44 +00:00
Richard Smith bfef32b482 Add an EvalOrAddInst function. (#5258)
Use that instead of `AddInstInNoBlock` to get the value of an
instruction when evaluation might depend on the `InstId` but only the
`ConstantId` of the instruction is desired by the consumer.
2025-04-08 21:04:30 +00:00
Dana Jansens d07f70cfb3 Add insts for witness table entries that are unset or associated constants (#5255)
Instead of using None, use an explicit ImplWitnessTablePlaceholder in
the witness table for entries that have not yet been populated, to aid
debugging. This would ensure they would show up very clearly in the
SemIR. This uncovered some `<invalid>` in the SemIR under erroneous
conditions that have now been turned into `<error>`.

Add the ImplWitnessAssociatedConstant instruction which wraps the
canonical instruction found from the constant value of the rewrite
constraint. This ensures that we have an instruction inside the eval
block for a generic impl declaration for each rewrite constraint's
value, which allows Subst to be performed to rewrite the symbolic
constant of the ImplWitnessAssociatedConstant instruction to associate
it with the generic. This will prevent the otherwise orphaned symbolic
constant of the rewrite's value from being used which can not have a
specific applied to them.

While applying the new insts in InitialFacetTypeImplWitness(), rearrange
the function to use less nesting. And avoid using entity names from
imported instructions (as we found is not effective in deduce.cpp) and
use a local instruction by going through the constant value.

This PR is part of the effort to allow a rewrite to name a generic
parameter, such as `impl forall [T:! type] T as Z where .X = T`, however
tests for this involve a final impl so that we can typecheck that the .X
value is a specific T, so the tests will come with that work. This piece
is split off because introducing new instructions causes a lot of SemIR
churn, and I wanted to get that done separately.
2025-04-08 19:10:49 +00:00
Geoff RomerandDana Jansens cda97cb292 Include all symbolic parts in structure comparison (#5247)
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-08 19:02:55 +00:00
Alina Sbirlea 3ccb0b82f8 Add/update lowering tests. (#5254)
Add lowering tests for future redesign.
2025-04-08 17:26:16 +00:00
Boaz Brickner 7d2029e8ca Fix clang-tidy: result of a data() call may not be null terminated, provide size information to the callee to prevent potential issues [bugprone-suspicious-stringview-data-usage,-warnings-as-errors] (#5267)
Replaced using `llvm::StringRef` with `const std::string&` so we can
have `c_str()`.
2025-04-08 15:39:55 +00:00
Boaz Brickner afa29d5e66 Fix clang-tidy: use a ranges version of this algorithm [modernize-use-ranges,-warnings-as-errors] (#5268) 2025-04-08 15:37:52 +00:00
Richard Smith 0631e18184 Provide an InstId when evaluating a constant in cases where one is needed (#5202)
For each kind of instruction, specify whether its constant evaluation
needs an `InstId` or not. If it does, ensure that all constant
evaluation of that instruction provides one. Otherwise, allow calling
into the evaluator without providing an `InstId`.

This allows us to reliably use the `InstId` in evaluation steps that
either need a location or need to look at the original operands of the
instruction prior to evaluation, and also to support `TryEvalInst` calls
safely for instructions whose evaluation does not need an `InstId`.
v0.0.0-0.nightly.2025.04.08
2025-04-08 00:40:21 +00:00