Commit Graph
108 Commits
Author SHA1 Message Date
Richard Smith e4528b8abb Add infrastructure for distinguishing between signed and unsigned integer types. (#3822)
Because we don't have any unsigned integer types yet, this is mostly a
no-op change, except that we now format negative values in SemIR
properly.
2024-03-27 20:18:25 +00:00
Richard SmithandJon Ross-Perkins ebbc648342 Add builtins for some basic integer operations. (#3816)
Supports unary `-`, and binary `+`, `-`, `*`, `/`, `%`, `==`, `!=`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-03-27 00:15:52 +00:00
a3d77d9b74 Factor out some parts of builtin handling and add declaration checking. (#3815)
In preparation for adding more builtins, factor out the handling of
builtin function kinds into separate files.

Add checking for builtin function signatures. The mechanism used here is
intended to provide a lot of flexibility for declaring generic builtin
functions and pretty arbitrary constraints on the types of parameters of
builtin functions. For now, these constraints are checked when the
builtin function is declared. The hope is that this will suffice, but if
not, it should be straightforward to switch to doing some of the
checking on call and share logic between the checks.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-03-26 22:58:11 +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
Richard Smith f0e940ddfd Initial support for builtin functions. (#3803)
For now, a builtin function is defined by specifying a string literal
initializer in a function declaration:

```carbon
fn MyBuiltin(a: i32) -> i32 = "builtin.name";
```

End-to-end support is included for a sample `"int.add"` builtin
performing integer addition, covering constant evaluation and code
generation.

The implementation here needs substantial refactoring before we'll be
ready to start adding more builtins. That refactoring work will be
coming next. This change is aiming to checkpoint some incremental
progress.
2024-03-21 20:46:34 +00:00
Richard SmithandJon Ross-Perkins d8be774b8b Lowering support for overloaded operators. (#3798)
Fix a collection of issues that were preventing lowering for overloaded
operators from working.

Instead of creating `import_ref` instructions during name lookup in the
current block, whatever that might be, we now create them in the `file`
block always. This avoids inserting them into blocks that might not be
intended to contain them, such as functions, and avoids the IR generated
for a function depending on which names we happen to have looked up
first.

When importing a class, function, or interface, import its enclosing
scope ID. This is necessary to allow us to distinguish between functions
at interface scope, which shouldn't be lowered, and other functions, and
will also be used in future to provide qualified names for declarations
when printing types. In order to support this:

- Track the constant values of namespaces created during importing so
that we can find them when resolving an import ref. Use those constant
values to convert an enclosing scope ID from the imported IR into a
corresponding ID in the current IR.
- Change how we do two-pass import of classes and namespaces so that we
can do two-pass import even for non-defining declarations, so that we
can import the enclosing scope.

While working on the final point above, I reworked `TryResolveInst` to
return a flag indicating whether another pass is necessary instead of
implicitly encoding this in the `ConstantId`. This permits the handling
of classes to be simplified; now `import_ir_constant_values` is only
accessed in a single place.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-03-20 23:32:44 +00:00
Richard Smith 3884d3c27e Parse and check support for compound member access. (#3790)
On the parsing side, we treat `a.(b)` as a member access whose second
operand is a `ParenExpr` rather than a `MemberName`. A new node category
is added for the union of `MemberName` and `ParenExpr` to support this.

Checking is mostly reusing the same pieces we already have for simple
member access. Compound member access is in most ways a simplified form
of simple member access because it doesn't need to do any lookup.
2024-03-16 22:38:23 +00:00
8cb932b99c Substitute Self in associated function signatures before checking them against impls. (#3788)
Add a general substitution mechanism to support substituting symbolic
bindings with their values throughout symbolic constants and, more
specifically, types. This is done by decomposing the constant
instruction into its operands, substituting into the operands, and then
rebuilding the constant value by invoking the constant evaluator.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2024-03-15 23:21:12 +00:00
Jon Ross-Perkins 8567e02aa7 Refactor handling of cross-package imports. (#3783)
This revamps the support for cross-package imports, making them look
more like a namespace. The planned model is mentioned on
[#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1217586076022210670).
This does not implement name lookup into the new namespace structure.

A few key changes in this PR (it's a little sprawling) are:

- Moves logic for adding package imports from context.* to import.*
- Remove SemIR::Import, which was the prior model. This is instead now a
SemIR::Namespace with the NameScope getting a new import_ir_scopes
field.
- Allow SemIR::Namespace to use Parse::ImportDirectiveId in addition to
the prior Parse::NamespaceId
- The import_ir_scopes field includes a NameScopeId so that as we
traverse to child namespaces, we can directly perform name lookup in the
other IR.
- is_closed_import now tracks whether a namespace comes from a different
package. This has a diagnostic implemented in decl_name_stack.
2024-03-14 22:03:30 +00:00
Richard SmithandJon Ross-Perkins 1d720dc001 Basic support for looking up impl members when naming an associated entity. (#3776)
When a member access names an interface member, perform impl lookup to
find the impl and its corresponding member.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-03-14 18:31:21 +00:00
Richard Smith ce1dd20be2 Refactor member lookup in preparation for adding impl lookup. (#3775)
A couple of minor functional changes here:

- We now always create a `name_ref` for the name referred to by the
right-hand operand of member access. Previously we skipped creating this
instruction if the referenced name was a field, and just created the
field access instruction. This makes our processing of member accesses
and our SemIR representation a bit more uniform.
- We now perform lookup into the type of the left-hand operand if it's
any type with a scope, not just for classes. This means we do lookup
into interface types. However, doing so isn't really useful yet because
it always finds an associated entity that isn't usable by itself. This
changes the diagnostic in
`toolchain/check/testdata/interface/fail_todo_facet_lookup.carbon`.
2024-03-13 23:44:38 +00:00
Richard SmithandJon Ross-Perkins abf23ae7fe Initial scaffolding for building a witness table for an impl. (#3743)
Add an instruction to hold the witness table, along with a corresponding
type to keep things simpler. Add `check/impl.{h,cpp}` to house the new
logic. No checking of impls against interfaces is performed yet.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-03-07 23:10:14 +00:00
Richard Smith f5a3a9a7e0 Add Self into scope in interface definitions and using facets as types. (#3740)
`Self` is modeled as a `bind_symbolic_name` with no corresponding value,
for now at least. In the future it might make sense to model it as a new
kind of instruction, or as a `bind_symbolic_name` whose value is a
`param`, but for now we just want it to introduce a symbolic constant.

In order to convert a value like the `Self` of an interface to a type, a
new instruction `facet_type_access` is introduced. This notionally
accesses the "type" field within a facet, converting it from a pair of
(type, witness) into just the type.
2024-03-06 22:33:33 +00:00
Richard Smith 8e956baca8 Basic support for associated constant declarations (#3737) 2024-03-04 21:23:06 +00:00
Richard SmithandJon Ross-Perkins 33c1e9ca95 Add an associated entity instruction and corresponding type for interface elements. (#3730)
When declaring an associated entity in an interface -- just associated
functions for now -- create an associated entity value and corresponding
type to represent a "slot in a witness table". Also track the list of
associated entities on the interface so that we will eventually be able
to check impls against them.

Associated entities are represented as the integer index of their slot
in a witness table.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-02-28 01:56:27 +00:00
Calvin f9f9ed2092 Remove obsolete __init__.py files (#3723)
I noticed that there are some empty `__init__.py` files in the repo,
with no immediately clear reason to have them. I asked [in
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1211088334894534686)
and it looks like these are likely artifacts from when `lit` was used
for testing, now left over and obsolete from the migration. To keep the
repo tidy, this PR deletes the files.
2024-02-26 16:02:27 +00:00
Jon Ross-Perkins 1437b0e26d Implement 'alias' with transparent semantics. (#3701)
Adds `BindAlias` with a hybrid of `BindName` and `NameRef` semantics. I
think it's slightly closer to `BindName` because it introduces a name,
so I'm going more in that direction. This also matches the need for
`bind_name_id` with imports on enclosing scopes.

Note, only things that look like a name reference are being allowed on
the RHS of `alias`. This includes builtins that look like name
references, such as `bool`, but not ones that turn into values
underneath, such as `false`.
2024-02-14 18:33:18 +00:00
Jon Ross-Perkins 1974e44fd9 Rename factory functions from 'Create' to 'Make' (#3706)
Similar to #3705, we actually have a mix of `Make` and `Create` in
factory functions too, so this PR is normalizing on `Make`. It's
intended to be consistent with the naming choice for Carbon factory
functions.

Note, MakeSyntheticBlock is the only one I feel a little weird about
because llvm's own APIs use Create, and this is essentially wrapping
LLVM calls. But the flipside is it also feels like a vague line to draw,
when we also differ from LLVM coding style in other ways.
2024-02-14 18:26:56 +00:00
Richard SmithandJon Ross-Perkins 0e053703f8 Build Impl entity to represent an impl declaration. (#3683)
Collect the contents of an `impl` into a scope, and start doing very
basic checking for `impl` declarations and definitions.

This change adds two new `Id` types to the set of type that `NodeStack`
supports -- `ImplId` and `NameScopeId`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-02-06 18:49:21 +00:00
Richard Smith 9e7a17b1a1 Scaffolding for checking impls. (#3672)
Consume the components of the `impl` declaration, and set up scopes for
the child elements. We don't yet build a representation for the impl
itself.

Also, add an interface type value. This is necessary so that we have a
value for the expression on the right-hand side of `as` in an `impl`.
2024-01-31 22:18:29 +00:00
Chandler Carruth bf02d1f4b0 Remove headers marked as unused by ClangD. (#3661)
This required adding a few headers that were found transitively before,
but not too many. This is sadly a fairly manual process of opening every
file in my IDE, but I think I got everything in `//common` and
`//toolchain`.

There are a few cases where technically we don't need `foo.h` to be
included into `foo.cpp`, but I've forced those to stay with a pragma.

I've tried to catch the places where we can cut deps in Bazel as well,
but not sure I got all of those.

I had been noticing these in other PRs and it seemed better to isolate
the change.
2024-01-29 16:15:35 +00:00
Jon Ross-Perkins 8167c44a03 Merging CrossRef into ImportRefUsed, shifting builtins over. (#3659)
This is a bit of a cleanup; I probably should've just renamed CrossRef
instead of adding ImportRefUsed.

Adding `is_builtin` to InstId is more about providing a standard API for
the check, which I expect to add a little more of.

Shifts import tests to validate that the BuildValueRepr CHECK isn't
accidentally hit.
2024-01-27 00:36:58 +00:00
Chandler CarruthandJon Ross-Perkins 13de9e9d06 Fix outstanding clang-tidy errors. (#3654)
Recent runs of `clang-tidy` for me started showing more errors, and this
is a collection of changes to address them.

First, I've systematically applied the disabling tag to all C++ rules
under //explorer/... with `buildozer` so we don't spend time analyzing
this code or reporting errors from it. Not sure this was strictly
necessary, but it seemed like a nice consistency improvement.

Next, I disabled a buggy check for missing `default` cases in
`switch`es. It seems to get confused by the fancy conversions in our
`enum_base.h`. We don't miss much with this as the Clang compiler
warnings for `switch` catch most of our actual bugs. I also removed the
local disabling of this now that it is turned off centrally.

Lastly, I added error checking to two file descriptor manipulating calls
in the `file_test` infrastructure.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-01-26 18:20:47 +00:00
Jon Ross-Perkins c1a894fca7 Start adding ImportRefUsed, removing older copy behavior. (#3657)
Builds on #3656.

Under the prior "lazy" model, we had been planning to copy instructions.
Under the current "unused+used" model, we're restricting that to
constants. I'm trimming back some of the ResolveIfImportRefUnused logic
because it was more appropriate for the former model.

Right now, I'm adding ImportRefUsed direct creation in import.cpp for
namespaces. I think I'll need to do something similar in
RseolveIfImportRefUnused... I'm still trying to think about how to
manage type information there (which needs to come in as an import
reference itself, and probably have some amount of deduplication before
forming a TypeId). So ImportRefUnused lacks a type because I'm hesitant
to aggressively load it, whereas ImportRefUsed should *always* have a
type but it's just an error while I think things through.

For reference, ImportRefUnused and ImportRefUsed are mainly split in
order to track the boolean "used" without making fundamental
modifications to Inst for bit packing (this effectively instead packs a
bit into InstKind). AnyImportRef currently excludes the type because
it's mainly for diagnostic printing at the moment. It could end up with
a TypeId that would end up Invalid for ImportRefUnused, though it could
also be that the TypeId is only accessed when using ImportRefUsed
explicitly.
2024-01-26 17:26:15 +00:00
Jon Ross-Perkins adad286b74 Refactor LazyImportRef into ImportRefUnused. (#3656)
This makes some changes to the formatter so that ImportRefUnused and
ImportRefUsed will both be labeled as "import_ref" with an "unused ->
used" argument change in textual IR, but is otherwise not changing
logic.
2024-01-26 03:10:00 +00:00
Richard Smith 439a644960 Propagate the phase of a type from its constituent types. (#3645)
To avoid bouncing through `constant_values()` to determine whether a
type is symbolic or template, store the `ConstantId` on the `TypeInfo`
not just the `InstId`.

In addition to propagating the symbolic / template phase, this also
propagates whether a type contains an error, resulting in our no longer
producing types such as `<error>*` -- these now evaluate to simply
`<error>`. While this makes our types less precise after an error, it
also removes some follow-on diagnostics, so it seems to be an
improvement on the whole.
2024-01-25 01:00:37 +00:00
Richard Smith b138c90c9e Use constant evaluation to determine the identity of types. (#3617)
Remove the type canonicalization mechanism and instead rely on constant
canonicalization to deduplicate types.

Rename the `Canonicalize*Type` functions to reflect that they're no
longer performing canonicalization. Switch code that creates types due
to semantic checking, rather than due to source syntax, to directly
create type constants through evaluation rather than creating an
instruction and evaluating it to produce a separate constant
representation.

The mapping from `const (const T)` that was previously performed by type
canonicalization is now implemented in expression evaluation instead.

The value `<error>` is now treated as a constant value, with a special
property that an instruction involving `<error>` that could possibly be
constant evaluates to `<error>`. This helps avoid producing follow-on
errors when an error occurs as a subexpression of an expression, such as
a type, that is intended to be constant.
2024-01-19 00:47:37 +00:00
josh11b 5e004b854e Delete unused NoOp instruction (#3586) 2024-01-10 22:40:34 +00:00
josh11b f5c34d62dd Abbreviate "address" -> "addr" (#3580)
As [requested in
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1184904724483416064)
and is now documented in [the toolchain architecture
doc](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw&tab=t.0#heading=h.pph7i5m5un7q).
2024-01-09 22:37:48 +00:00
Richard Smith a6508fcf05 Basic support for generic bindings. (#3555)
This change adds a `BindSymbolicName` instruction for generic bindings,
paralleling the existing `BindName`. A mechanism is also added to allow
both kinds of binding to be accessed uniformly, for convenience in the
case where the two different kinds of binding are treated the same.

Generic bindings of type `type` are allowed to be used as types,
although no operations are provided for such types. For now lowering
treats these types as empty structs, which seems like a reasonable
lowering for non-monomorphized unconstrained types.
2024-01-05 03:39:45 +00:00
Richard Smith fe24ebc021 Create a BindName for function parameters. (#3535)
The goal here is to make the representation more uniform so that we can
start adding different kinds of binding -- checked generic bindings and
template bindings -- across both function parameters and local `let`
declarations.

With this change, the entry in the parameter list for the function is
the name binding, not the Param itself, which has some ripple effects on
consumers of that list that want to access the parameter rather than the
binding. This is expected to change again when we start adding more of
the pattern matching SemIR, but this seems good enough for now.
2023-12-22 00:12:16 +00:00
Richard Smith fbb4ecf319 Remove SelfParam, add an AddrPattern instead. (#3506)
This is intended to make the representation of a `self` pattern be more
similar to other patterns.
2023-12-14 20:53:51 +00:00
Jon Ross-Perkins 032c0e017b Start adding lazy import references to name lookup. (#3475)
Adds a `LazyImportRef` instruction. Versus `CrossRef`, this is intended
to represent an instruction which cannot be used directly, and must be
replaced when it comes up due to name lookup. The intent is to use this
to avoid recursive loading of imported IR instructions.

Note, under this model, when `ResolveIfLazyImportRef` is called, it
essentially needs to load both inst and type information to a sufficient
point where any further attempts would hit name lookup again. That will
probably be complex, and the current implementation is just touching the
surface of the issue. I was heading down this route because it would
mean we have a limited number of points that need to consider whether
they're going to talk about a `LazyImportRef`.

I'm considering whether `CrossRef` should be dropped in favor of more
specific `Builtin` special-casing, due to the divergence of desired
behaviors. This could mean dropping the `builtins` IR since it's not
looking useful right now.

Modify `NameScope` to track whether the scope is associated with a load
error. This is to handle cases where one or more imports failed, so we
do not want to issue warnings for related scopes.

The 0-size on `ValueStore` comes up due to the changes to `NameScope`,
which make it too large for the default handling. After discussion with
zygoloid, the thought was we might want to try reserving a roughly
correct value based on parse node counts, but the stack default wasn't
buying much.

Fixes a bug where the implicit import used the package name instead of
the invalid identifier.
2023-12-12 00:13:25 +00:00
Richard Smith 87d341c61b Support derived to base conversions. (#3487)
This is enough to support calling methods that take a `Base` or `Base*`
as their `self`. But name lookup doesn't look in the base class yet, so
base class methods aren't actually found.
2023-12-11 23:09:01 +00:00
Richard SmithandJon Ross-Perkins cef7eb5522 Simplify interface for getting an instruction from a type. (#3455)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-08 21:50:33 +00:00
josh11b 3b0923c81d Add interface support to check (#3474)
Largely copied from the `class` code
2023-12-08 17:13:49 +00:00
Jon Ross-Perkins 8ace1dcb78 Remove BinaryOperatorAdd (#3469)
BinaryOperatorAdd had been added early on as a proof-of-concept for
toolchain design for parsing -> checking flow. However, it doesn't
reflect the interface direction for operators, and now other portions of
the toolchain demonstrate the relevant logic. Instead, it's just a bit
of an outlier versus other instructions which have evolved over time.
2023-12-08 01:06:19 +00:00
Jon Ross-Perkins ef0fa81a58 Upgrade clang-format version (#3471)
This apparently includes a fix for
https://github.com/llvm/llvm-project/issues/47664 (previously
https://bugs.llvm.org/show_bug.cgi?id=48320)

Note this continues with a clang-format version that's different from
the compiler versions we're often using, but the differences in
formatting seem worthwhile.
2023-12-07 19:09:36 +00:00
josh11b e9fc07feee Abbreviate "representation" -> "repr" (#3464)
Specifically using these abbreviations:
* InitRepr: "initializing representation"
* ObjectRepr: "object representation"
* ValueRepr: "value representation"

As discussed in [#toolchain
discord](https://discord.com/channels/655572317891461132/655578254970716160/1182086098470572143)
and now documented in the [list of
abbreviations](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).
2023-12-06 23:11:47 +00:00
josh11b a970b1e587 Require extend before base: BaseType; (#3459) 2023-12-06 20:14:16 +00:00
josh11bandJon Ross-Perkins fada410559 Support declaration modifier keywords (#3412)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-05 22:45:57 +00:00
Richard Smith 433d626b04 Rename SemIR::{Base,Field} -> SemIR::{Base,Field}Decl. (#3452)
Also fix printing of unbound element type to say "element" not "field"
since we're touching all the relevant SemIR output anyway.
2023-12-05 16:37:02 +00:00
Richard Smith 7dffa0c7ec Support for base: T;, .base, x.base. (#3450)
No support for `extend base` yet, in an effort to minimize collisions
with #3412.
2023-12-04 22:45:59 +00:00
Richard Smith ca53c18ddc Rename MemberIndex -> ElementIndex, ClassFieldAccess -> ClassElementAccess, UnboundFieldType -> UnboundElementType. (#3446)
In preparation for base class support, where these types will be used
for bases as well as fields.

As discussed [on
discord](https://discord.com/channels/655572317891461132/963846118964350976/1180267686316478575).
2023-12-02 00:29:48 +00:00
Jon Ross-Perkins 0db63ff17a Abbreviate Integer and FloatingPoint (#3435)
I was suggesting this because `FloatingPoint` is pretty long. `int` and
`float` should be familiar abbreviations. `unsigned` should be familiar
to developers too, but `UnsignedInt` still feels usefully clearer for
the additional chars.
2023-11-29 23:29:48 +00:00
Jon Ross-PerkinsandRichard Smith 0d618b1278 Tidy up lint issues. (#3429)
These are manual fixes; mostly from clang-tidy, some from clangd (which
notes unused includes).

In typed_insts, adding inlline due to misc-definitions-in-headers. Per
discussion, clang-tidy is wrong, but inline silences it.

For parameter name skew in definition versus declaration, I'm just using
the name from the definition.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-11-29 20:41:53 +00:00
Jon Ross-Perkins 239f8030a4 Pass imports to SemIR. (#3415)
This adds instructions so that we get printing. I may adjust the
instruction format a little further to add a type, but I think the basic
setup will remain.

Note this builds on #3414
2023-11-28 19:55:38 +00:00
josh11b a307e7a72a Rename files to use "expr" and "deref" (#3426)
Follows #3425 and #3375 .
2023-11-28 17:11:35 +00:00
josh11b c89c452579 Abbreviate "Reference" -> "Ref", "Dereference" -> "Deref" (#3425)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

File renames will be done separately.
2023-11-27 23:30:31 +00:00
josh11b 7d8afed6f7 Abbreviate "Initialization" -> "Init" (#3398)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).
2023-11-15 05:36:16 +00:00