Commit Graph
30 Commits
Author SHA1 Message Date
Richard SmithandDana Jansens 19182f08aa Compute a fingerprint for constants and import_ref instructions. (#4763)
Use it in the instruction namer to make instruction names more stable
across unrelated changes to the toolchain or the prelude.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-01-07 20:41:44 +00:00
c5fd8f42b8 ImplWitness (#4679)
* Change `InterfaceWitness` -> `ImplWitness`
* Include a `SpecificId` in the `ImplWitness`. This allows the
`InstBlock` it contains to have its own identity, allowing it to be
changed as the impl is processed. Evaluation only updates the specific.
* Create the `ImplWitness` at the start of the impl definition. In the
future, this will be populated with the values of non-function
associated constants. For now, it starts full of invalid instruction
ids.
* Implements the model suggested in #4672 .

Note that the non-SemIR testdata changes are to these file:
* `toolchain/check/testdata/impl/lookup/fail_todo_undefined_impl.carbon`
* `toolchain/check/testdata/struct/import.carbon`
* `toolchain/check/testdata/tuple/import.carbon`

The last two are due to an import of generics bug exposed by this PR,
which will be fixed in a follow-on.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-01-02 23:03:11 +00:00
Richard Smith 6fe8e0b5aa Provide generic impls for Core.Int and Core.UInt operations. (#4693)
Instead of providing operations only for `i32`, provide them for all
`iN` and `uN` types.

For now, this excludes the `*Assign`, `Inc` and `Dec` interfaces,
because the implementations for those are defined as Carbon functions
rather than builtins, and we can't yet lower definitions for specific
functions, so converting those to be generic breaks the build for our
examples.
2024-12-19 22:02:18 +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 a10c79569e Model Core.Int as a class type (#4644)
Instead of treating `Core.Int` as the toolchain's builtin `IntType`,
model it as a class that adapts the builtin type. This aligns us better
with the intended language model, gives an associated library for
`impl`s involving `Core.Int` to live within, and opens the door adding
member functions to `Core.Int` if we decide that is desirable.
Remarkably it also seems to make the formatted SemIR a little smaller,
because a call to a generic class generates less IR than a call to a
function.
2024-12-16 22:19:23 +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
Jon Ross-Perkins e7a86b03c6 Remove offsets from InstId formatting, trying to name more (#4645)
The offsets were originally added to deal with churn from builtins in
the raw semir. In textual semir, we mostly see instruction IDs for
imports, and builtins have also settled down more.

On imports, where possible, use the `EntityNameId` for an import instead
of printing an instruction. Next, show the source location if we have a
node. Only show the instruction if there's no location.

This also exposes `Parse::Tree` and `TokenizedBuffer`, so that we can
pass a `SemIR::File` without the component parts. In particular this
allows us to get the `TokenizedBuffer` for import IRs without
substantial structural modifications. We may want to make these optional
for serialized `SemIR` later, but the nodes/tokens contain source
location, which we'd need for debug information -- so it's not clear how
much we can really make them optional without substantial information
loss.

Reduce arguments to just `File` in a few spots, as a result of the
accompanying `TokenizedBuffer` and `Parse::Tree`. Also updates style to
pass around `const File*` where the reference is maintained, instead of
`const File&`.

I was considering keeping a direct reference to the tree and tokens on
`Context`, but initially my thought was it wouldn't make much
difference. I can re-add those if desired, just as direct caching of the
`File` fields.
2024-12-06 21:17:24 +00:00
David Blaikie a2c939a2a2 Add an instruction for vptr initialization (#4633)
This fixes a crash in lowering, at least (though only initializes the
vptr to
null for now) - certainly open to naming feedback on the instruction, or
the
exact semantics (we could have a global vptr instruction that's
referenced from
the existing instructions for reading globals, for instance).

I guess we'll want one type parameter for the vptr_init instruction,
which is
the type that this is a vptr for? (can do that here or in a follow-on
patch)
2024-12-06 18:51:36 +00:00
Richard Smith f8e7dad33a Include the file from which an entity was imported in formatted SemIR. (#4621) 2024-12-04 19:12:56 +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 831dd2c929 Fix importing of the complete_type_witness for a generic class. (#4600)
We need to create an instruction on import to attach the generic
constant value to.
2024-11-28 00:13:21 +00:00
Richard Smith 4a10d29b99 Include the complete type witness for a class in its SemIR output. (#4599)
This seems slightly redundant for a locally-defined class, where there
will be a complete_type_witness instruction earlier in the class, but is
important for imported classes, where we're currently doing the wrong
thing in a way that's invisible in formatted SemIR.
2024-11-27 23:45:20 +00:00
Richard SmithandJon Ross-Perkins d6ec885eb3 Track the type as written in BaseDecl and AdaptDecl. (#4564)
Represent the type as an `InstId` rather than as a `TypeId` to preserve
how it was written and better support tracking its value in a generic.
Add accessors to `Class` to get the base and adapted type to reduce code
duplication, and add `TypeStore::GetObjectRepr` to make it easier to map
from a type to its possibly-adapted object representation type. In
passing, also move `GetIntTypeInfo` and `GetUnqualifiedType` into
`TypeStore`.

This fixes specifics of generic adapters to properly look at the
specific adapted type, and also fixes importing of adapters.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-11-27 22:26:30 +00:00
David Blaikie 14bb9dd5cf disallow impl without base (#4583) 2024-11-27 01:37:49 +00:00
David BlaikieandRichard Smith f921923b4b lazy field index (#4514)
We considered a couple of other options for this:
* https://github.com/carbon-language/carbon-lang/pull/4515 Keep the
`ElementIndex` numbering vptr-ignorant, and do +1 offsets as needed -
seems subtle/easy to miss
* https://github.com/carbon-language/carbon-lang/pull/4517 Always have a
zeroth element in the object representation, make it zero-size in the
case of no-vptr - @zygoloid was concerned this would add overhead
especially to stateless objects used in type-trait-like things.

But currently moving forward with this direction - of initializing field
indexes with an invalid value until the end of the class definition,
then assigning field indexes during construction of the class's object
representation struct type. This direction might reinforce/help avoid
premature access to the object representation before the class is
complete, and give a single place where class layout is done (at class
completion) if we want to add more options there, such as class layout
optimizations, etc.

This patch still has problems with object initialization (that #4515
does not have/does address) but does address normal `obj.member` access
correctly.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-11-26 18:16:25 +00:00
David Blaikie b15875e302 element index init with vptr (#4565)
Not sure if this is the most robust way to do it - I guess the
alternative is doing name lookup into the dest struct fields too?
2024-11-23 01:02:43 +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
josh11bandJosh L abd12c18c7 Support extended scopes that are parameterized types (#4524)
* The `extended_scopes` in a `NameScope` were represented by a
`NameScopeId`. Replace that with an `InstId` of an instruction returning
the type that is extending this name scope.
* `Context::LookupQualifiedName` now can take multiple scopes to look
in.
* `GetAsLookupScope` was moved out of `member_access.cpp` and is now
`Context::AppendLookupScopesForConstant`

This PR also fixes some existing issues that were revealed as part of
writing and testing this PR:
* Additional validation and handling of invalid ids.
* `extend impl` in a class is not properly imported yet, but at least
now it doesn't crash.

The change to use an `InstId` also allowed some diagnostics and
formatting to be improved.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-11-13 23:48:02 +00:00
David Blaikie 79c5c47911 Preserve the is_dynamic property of classes when importing them (#4501)
The test update shows a class derived from an imported base class with a
vptr, and without this change the derived class got its own vptr, with
this change the derived class can see the base is dynamic, so the
derived doesn't need to add a vptr and can rely on the base class's vptr
instead.
2024-11-12 16:11:19 +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
David Blaikie d79a374ad4 Skip vptr when performing object initialization (#4490)
The cehck for vptr could be done differently (is this class dynamic and
its base class non-dynamic), and if we change the layout (to put the
vptr after any base) then this code will break (could add an assertion
that the vptr isn't present apart from at the start of the field list if
that'd seem worthwhile).

There's still later issues with lowering (if this patch causes crashes
in lowering, do they result in fuzz failures/need to be avoided before
this change is submitted?)
2024-11-06 18:27:40 +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
Richard Smith 2e63da1a40 Move diagnostic kind name to the end of the diagnostic. (#4437)
Also surround it in square brackets rather than parentheses. This
matches the format used by Clang and GCC, and means diagnostics will
still match the `file:line:col: error: ` pattern used by some IDE tools.

Before:
```console
fail_builtins.carbon:11:11: error(AliasRequiresNameRef): alias initializer must be a name reference
```

After:
```console
fail_builtins.carbon:11:11: error: alias initializer must be a name reference [AliasRequiresNameRef]
```

Also tighten up test regex to only match on `STDERR` lines that list a
file name.
2024-10-23 16:56:23 +00:00
Jon Ross-Perkins 62c36eceda Support printing the diagnostic kind for verification. (#4425)
This is to help identify which diagnostics we're actually using.

Note that driver/testdata still has tests which don't pass this flag,
and so continue to test the kind-less (default) behavior.
2024-10-18 22:33:56 +00:00
Jon Ross-Perkins 7c22348461 Add s plural format to IntAsSelect (#4423)
Per discussion on #toolchain, add "s" as a special-case for the common
plural format.

Note this removes periods from a few diagnostics; the periods shouldn't
be there per message style. Also, while I'm ignoring llvm::StringLiteral
uses, those should be addressed as #4416 -- this'll probably conflict
and make me clean up one or the other.
2024-10-17 19:51:52 +00:00
David BlaikieandRichard Smith dfed743de2 Add vtable pointers to class layout (#4407)
A small step to virtual functions - adding vtable pointers to the
layout, but not initializing or otherwise using them at this stage.

A few open design questions I'd love feedback on:

* Is this the right/good enough SemIR representation for now? This patch
adds a `is_dynamic` attribute to `SemIR::Class` and populates/flags it
based on the flag of the base class, or if any virtual function is
declared in the class (or, at least that's my intent). Some other
options include:
* Each `Class` could store a `ClassId` (or `TypeId`?) of the (possibly
indirect, possibly self) base class that is the first one that is
dynamic/has a vtable pointer
* Could make the property narrower, like `has vtable pointer` and have
it `true` only on the type that introduces the vtable - then derived
classes would have to walk their base classes to check if they're the
one that needs to define the vtable pointer or not
* Should the vtable be the first element in the type? If there's a
non-dynamic base type, we could have a layout that's `{<non-dynamic base
type>, vtable ptr, <derived members>}`? Derived types would still be
able to uniquely identify where their vtable pointer is just fine... -
and the vtable pointer is, in a sense, a member of that intermediate
type, so it does seem a bit strange to force it to the front - but I
guess it's probably more efficient in some ways?

Open to any other suggestions/advice/thoughts on the direction, etc.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-16 21:26:17 +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 2044366652 Support initialization of specific classes from struct literals (#4320)
Add support for initializing types like `GenericClass(i32)` from a
struct literal. A new kind of instruction, `complete_type_witness`, is
added to the class definition to track the object representation type so
that it's visible to the generics machinery. Accesses to the object
representation of a class have all been updated to pass in the class's
`SpecificId` so that the types of the fields of the specific class are
used instead of the types of the fields of the generic class in places
that look at the object representation -- primarily class
initialization.
2024-09-19 19:18:32 +00:00
David BlaikieandJon Ross-Perkins 5806d8385d Add SemIR support for virtual functions (#4272)
I guess this technically would also allow code to pass check that hasn't
before, and that isn't covered by tests (since it's masked by other
failures in the tests that already test this functionality) - should I
add another test/add some code to a valid test case?

Also, this'll miscompile in lowering, since there's no support there yet
- should I do anything about that to make lowering fail in some way? Or
is it acceptable that some things just silently mis-lower? (I could add
a currently-miscompiling test case too, to demonstrate this? (not sure
if the autogenerated tests leave space for comments that would explain
that the currently-tested behavior is incorrect?))

Is the addition to EntityWithParamsBase suitable? of course not all
functions can be virtual, so it's a wasted bit at the moment for all
those cases (though it's free, since it's bitpacked - but as we want to
add more bits in there it might not be a scalable solution)?

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-10 18:16:59 +00:00