Commit Graph
260 Commits
Author SHA1 Message Date
Jon Ross-Perkins a2ba7f1262 Have Specific track whether regions contain errors (#6982)
This removes some loops in type completion, but is motivated by the
thought that eval probably wants to query it.

Assisted-by: Google Antigravity with Gemini
2026-03-27 19:36:52 +00:00
Richard Smith 965879a9a9 Support for in-place return in eval fn. (#6954)
Ignore storage arguments when evaluating a call, like we do for other
kinds of instruction. Create a placeholder constant to represent each
out parameter so that it can be used in the function body to form more
storage arguments.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-25 16:03:44 +00:00
Dana Jansens 17657d0586 CHECK if a SymbolicOnly instruction produces a concrete value of the same inst type (#6938)
The contract for SymbolicOnly is that the instructions are only allowed
to have a symbolic value unless their value is a different instruction
type.
2026-03-23 16:15:56 +00:00
Richard SmithandGeoff Romer ce50f181f1 Add an interface for initialization of vars without an explicit initializer (#6934)
When a `var` is not explicitly given an initializer, initialize it in
one of two ways:

* If its type implements the new interface `Core.Default`, call
`Core.Default.Op` to initialize it.
* Otherwise, if its type implements `UnformedInit`, leave it in an
unformed state. For now, this is always an uninitialized state, but that
will change in the future.
* If neither of those apply, the `var` declaration is ill-formed.

This is a step towards implementing leads decision #6739 and proposals
#257 and #5913.

Assisted-by: Gemini 3.1 Pro via Antigravity

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-03-19 23:46:06 +00:00
Dana Jansens bad9beddc7 Diagnose using named constraint's name inside its definition (#6906)
Using a named constraint inside itself is problematic:
- If there were not require decls written above, it identifies as an
empty set. This makes `Z(Self)` essentially disappear in the identified
facet type, which produces "no use of Self" diagnostics while the user
can see a use of Self in the code.
- It won't include require decls that are written after, and so `require
T impls Z` won't actually enforce that `T` impls all of `Z`.

Previously this was an error because using the named constraint would
require it to be identified, and it's not identified until it is
complete. But this will change in proposal #6902. So that proposal also
includes changes to preserve diagnostics for incorrect use of a named
constraint before it's complete, which is implemented here.

Discussed in open discussion [on
2026-03-12](https://docs.google.com/document/d/1mjllGO3ZCL4qGt9uJHUtcxKoHAGEY7Y999ie4EtBWB8/edit?tab=t.0#heading=h.1dvbbrp5a6t3).

The new tests exposed a bug where we're not copying named constraints in
a facet type on the RHS of `where .Self impls` into the facet type on
the left, which is now fixed. The
`fail_require_impls_incomplete_self_in_period_self_impls.carbon` test
would not diagnose its error without this fix.
2026-03-13 16:54:58 +00:00
Nicholas Bishop c1fd771242 Support calling constexpr functions at compile time (#6878)
Example:

```carbon
import Cpp inline '''
constexpr int f(int a, int b) { return a + b; }
''';

let a: array(i32, Cpp.f(1, 2)) = (1, 2, 3);
```
2026-03-12 01:45:31 +00:00
Dana Jansens fbc8d59d32 Introduce Diagnostics::ContextScope and remove diagnoser callbacks in type completion (#6761)
Introduces `Context` and `SoftContext` messages, which can be introduced
through a `ContextBuilder`:
- The `Context` messages come before the diagnostic in the output.
- The first `Context` message steals the diagnostic level from the main
diagnostic, and turns the main diagnostic into a Note attached to the
context.
- A `SoftContext` message works similarly, but if it's preceeded by a
`Context` or `SoftContext` message, then it is dropped. This can be used
as a default/backup scope when nothing more interesting is provided up
the stack, such as in `TryEvalBlockForSpecific`.

The `ContextBuilder` is provided to a callback through
`Diagnostics::ContextScope`, an RAII type `AnnotationScope` but for
context messages.

This allows a high level operation to provide a context message like
"failed to identify facet type {0}" which will then be used as the error
if a diagnostic is produced during identification, with the latter
diagnostic attached as a note to explain why the contextual operation
failed.

In particular, this allows monomorphization errors (such as an array
bound being negative) to be attached to a higher lever operation instead
of being top-level diagnostics themselves, with the monomorphization
site being a note. This inverts the source code locations that appear in
the diagnostic, so that the top-level diagnostic points to the "user
code" which causes the monomorphization.

This is presented as an alternative strategy to #6753, which plumbed
diagnoser callbacks around to achieve the same goals.

We replace the diagnoser callbacks in type completion and operators with
ContextScope callbacks instead, which now provide better diagnostics for
monomorphization errors. Other callers to MakeSpecific do not yet have
ContextScopes introduced in order to turn monomorphization errors into
more interesting diagnostics.
2026-02-25 15:15:29 +00:00
Geoff Romer 6a3529f4b5 Add Core.Form to prelude (#6745)
Unfortunately, currently it has to be a function rather than a constant.
2026-02-19 19:26:56 +00:00
Richard Smith 108277c3f3 Support if expressions in eval fn. (#6725)
Add support for `BranchWithArg` and `BlockArg` during compile-time
function execution. We only track the most recent block arg value for
now, because that's all we need -- we never look at a block argument for
any block other than the current one.

Also refactor `FunctionExecContext` to better encapsulate the blocks
list.
2026-02-18 13:32:45 +00:00
Geoff Romer 7f29436d4e Restore the name of GetCompileTimeBindValue. (#6733)
It had been renamed to GetCompileTimeAcquireValue in #6281 due to an
overzealous find/replace.
2026-02-13 00:54:23 +00:00
Richard Smith 1b2ae912fc Add basic support for eval fn and musteval fn. (#6694)
Add support for compile-time functions. `eval fn` is analogous to C++
`constexpr`, and is evaluated at compile time when it has compile-time
arguments. `musteval fn` is analogous to C++ `consteval`, and requires
that its arguments be available at compile time and is always evaluated
at compile time. For now we require the modifier to match across
redeclarations of the function. The specific modifier syntax here is a
placeholder and not yet part of an approved design.

Limitations: Only very basic support for evaluation is provided. So far
there's no support for mutable state or `if` expressions, but otherwise
control flow and passing and returning values should work. Carbon
evaluation recursion is modeled by C++ recursion for now, so you can
overflow the toolchain stack easily. Functions that use in-place
initialization will generally not work yet, as they are modeled as
passing a non-compile-time-constant reference to a temporary to the
call.

Add missing categorization of `name_binding_decl` as `NotExpr` to match
other similar declaration instructions like `FunctionDecl`, so that we
can uniformly skip over them when they occur within function bodies.

Assisted-by: Gemini 3 Pro and Flash via Antigravity
2026-02-11 02:08:16 +00:00
Jon Ross-Perkins 45ca3d28f5 Drop "diagnostic" from some filenames in the "diagnostics" folder (#6686)
Mainly because "sorting_diagnostic_consumer" is legacy, since
`SortingDiagnosticConsumer` became `SortingConsumer`. Also better
reflecting contents of these files.

Where I'm not renaming, I'm less positive about dropping "diagnostics"
from "file_diagnostics" and "null_diagnostics" (which contain both a
consumer and emitter, and "null.h" seems like poor naming), so not doing
that here. Also "diagnostic.h" contains `struct Diagnostic`, so is a
decent fit.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-04 17:24:55 +00:00
Richard Smith c0b24047dd Interop support for initialization via std::initializer_list. (#6672)
Add a new builtin function `cpp.std.initializer_list.make` that takes an
array and returns a `std::initializer_list`, initialized to refer to
that array. When C++ initialization wants to perform a
`std::initializer_list`-from-array construction, synthesize a
declaration of a matching builtin function and use that to perform the
initialization.

Ideally we would specify this conversion as an impl of `ImplicitAs` in
the prelude instead of hardcoding it in the interop layer, but
unfortunately that's not currently possible, for various reasons -- we
can't make the conversion form-generic, we can't deduce the array length
from the initializer, and we can't deduce against the arguments of
imported C++ class templates yet -- so for now synthesizing a builtin
function on demand is the best we can do.

Assisted-by: Gemini 3 Pro via Antigravity
2026-01-30 22:24:18 +00:00
f42352759f Adding support for UInt-to-char conversion (#6425)
This pull request adds support for integer-to-char conversion, allowing
the compiler to correctly handle character casting, implementing part of
the issue #5922.

```carbon
import Core library "io";

fn Run() -> i32 {
	var i : i32 = 65;
	var ch: char = (i as char); // Support implemented!
	Core.PrintChar(ch); // Print 'A'
	return 0;
}
```

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-01-21 21:48:49 +00:00
Richard Smith 31919afa24 Allow conversion between T* and Cpp.void*. (#6575)
Support an implicit conversion from `T*` to `Cpp.void*` and to `const
Cpp.void*`, and an `unsafe as` conversion in the opposite direction.

In order to support C++ calls taking and returning `void*` (which get
mapped to Carbon `Optional(Cpp.void*)`, also support conversions from
`Optional(T)` to `Optional(U)` if there's a conversion from `T` to `U`.

Fix a bug in `OptionalStorage` for `T*` where its `HasValue` was exactly
backwards.
2026-01-12 16:32:15 +00:00
Jon Ross-Perkins c5eba90317 Change Destroy to use a CustomWitness instead of a blanket impl (#6512)
Pursuant to recent decisions on #6124, switch `Destroy` to use a
`CustomWitness` for its implementation. Right now this is manufacturing
no-op implementation functions on each lookup, which obviously isn't
ideal but is intended as a first pass. I'm mostly trying to find the
right balance between updating the approach to reflect new decisions,
while still breaking apart work in a way.

The `CoreInterface` logic is intended to build on `CoreIdentifier`
support. We have a number of additional interfaces that require
specialized logic, and that'll extend pretty far with C++ interop, so it
seemed easiest to have a generic function for it. That's what's
replacing the logic inside C++ interop that was doing string comparisons
(which could have already been moved to `CoreIdentifier`, I just missed
it in my first pass).

This adds `CustomWitness` support because the `Destroy` witnesses can be
imported cross-file. `CustomWitness` was previously only used for C++
types, which don't yet support import, which is why that wasn't
previously an issue. The addition of `query_specific_interface_id` is
similarly needed in order to get correct sorting of witness blocks when
imported.

This PR also removes builtin constraint logic (note this is in a
separate commit to help review; it's not a separate PR because it's
difficult to split apart without tests breaking). This had been made
generic with the expectation that destroy, copy, move, and conversions
would all need related support. Under the new decision, we are not going
to do blanket impls and will instead just manufacture a `CustomWitness`
for everything.

A lot of SemIR fingerprints change, but that's probably because the
addition of `Destroy` on core classes is yielding structural changes.
2025-12-19 18:36:06 +00:00
Ammar AlassalandDana Jansens a848ae11e4 Added string indexing (#6329)
Implemented string indexing for Core.string
Handles references or struct values. No runtime checks as per
https://discord.com/channels/655572317891461132/655578254970716160/1431015866270748682
Part of #6270

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-12-11 21:31:31 +00:00
f000194d8b Make a couple of parts of our infrastructure more robust. (#6455)
Don't CHECK-fail when trying to format invalid SemIR with an ImplWitness
whose table_id isn't an ImplWitnessTable. We use SemIR formatting as a
debugging aid, so it's good for it to be robust even in the presence of
invalid SemIR.

Don't crash if a typed instruction has no type_id field and has a
constant kind of Always. We don't have any instructions like that at the
moment.

These caused problems while working on #6451, and while I ended up not
needing either fix for that PR, they both seem like they may be worth
keeping to save some trouble for the next person who hits these.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2025-12-03 19:24:39 +00:00
Dana Jansens 201e408252 Type completion of facet types is separate from Identifying (#6385)
Identifying a facet type is an operation on a pair of (self type, facet
type). It substitutes that self in as the `Self` of any require
declarations in order to form the set of (self type, SpecificInterface)
pairs that constitute the requirements of the IdentifiedFacetType.
Currently we don't pass around any self type, and assume all require
declarations are written against `Self` but this will change in the
future.

By contrast, type completion is done in the abstract and does not form
specifics for the require declarations. The purpose of type completion
is to enumerate the scopes where name lookup can occur and ensure they
are completed.

With this change, type completion is:
- No longer built on top of identification for facet types.
- Recursively ensures all `extend` scopes are complete since name lookup
can find symbols in them.

We add some test cases that demonstrate consistency between a resolving
the specific of a generic class, and a generic interface/constraint,
both used in a type position. In all cases, an invalid specific is not
materialized for the type completion when the specific's arguments are
used in a non-extend context. But they specific is materialized and
checked for type completion when in an extend context (extend impl or
extend require).

Type completion itself does not need to recurse into named constraints
or interfaces as the `extend require` declarations require the type to
be complete immediately, just as for `extend impl` in a class.

We had a test (`fail_incomplete_where.carbon`) with `impl as J where
.Self impls K` and `J` is incomplete, which used to be diagnosed but no
longer is, because we don't require non-extend interfaces to be complete
in type completion, nor in identification. The test was trying to test
the presence of rewrite constraints though, which it didn't even use. So
we remove the diagnostic that we can't hit anymore and replaced it with
a TODO, and add a test that should reach that TODO once qualified
rewrite constraints work.
2025-11-21 22:28:08 +00:00
Jon Ross-Perkins ee49d65e29 Remove a use of zip/to_array in eval (#6393)
The to_array was mainly needed for zip_equal, and the
GetBlockAsTypeInstIds is forming a vector that should also be size two.
But just writing this out should avoid memory allocations.

Of course, then I'm like "but maybe a lambda or function would be
clearer than a for loop"... So the second commit.
2025-11-18 19:19:40 +00:00
Jon Ross-Perkins fbc7690157 Switch zip to zip_equal where possible (#6389)
There are two uses I'm not converting here, that seem to want the
"shortest" behavior. For everything else, I'm going to `zip_equal` since
it's more restrictive.

I wish `zip` were named `zip_shortest`.
2025-11-18 00:28:06 +00:00
Dana Jansens ca3f95faa6 Make named constraint eval to a FacetType with itself in it (#6308)
This requires declared FacetTypes to hold NamedConstraintIds (along with
a specific) that are named in an extend or impls requirement. We add
support to stringify and formatter to display the named constraints in
the facet type, and special case when a facet type contains a single
extend named constraint, like we did for a single extend interface.

This means that `RequireIndentifiedFacetType` can now fail, if the facet
type contains a forward-declared named constraint. Add the appropriate
diagnostics for each call to this function, and note the ones that
should change to `RequireCompleteFacetType` in the future with TODOs.

We also add tests for using facet types that can or can't be identified,
or completed, with named constraints in them.
2025-10-31 22:10:35 +00:00
Jon Ross-PerkinsandDana Jansens 42e2280150 Clean up singleton TypeId use (#6300)
#6289 absentmindedly added fields in more places, and this is undoing
that plus further fixes.

This does some cleanup of types with relation to singletons. For
`TypeType` and `ErrorInst`, they're always complete due to a
`SetComplete` call in `file.cpp`. For `CppVoidType`, it's intended to be
incomplete by construction, and so a `TypeId` should be okay. The intent
though on not generally providing these had been that `GetSingletonType`
needs to be called to get a type to be marked as complete.

In the case of `AutoType`, removing `TypeId`does change a small printing
detail. I think that's old legacy that's just been carried forward.

Otherwise, for both `InstType` and `AutoType`, I've added
`GetSingletonType` calls where they were used in order to ensure
completeness is applied correctly. These calls cause small SemIR
permutations.

This causes `AutoType` to be seen by lowering, so I'm adding a
placeholder for it. Also merging two functions that look like they're
identical in intent -- not sure why they're separate.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-10-30 22:50:59 +00:00
Geoff Romer 0811d996e1 Finish renaming BindName and related insts. (#6281)
Resolves the TODO from #6235
2025-10-28 17:17:38 +00:00
Dana Jansens e12d1b6d6d Handle a specific providing ImplWitnessAccess for a symbolic binding used as a type (#6201)
SymbolicBindingType evaluates to the type component of a symbolic facet
value (a type/witnesses pair), and that symbolic facet value has its
constant value replaced by a specific. That specific can provide a
FacetValue, in which case it just evaluates to that FacetValue's type
component. It can provide a BindSymbolicName of another binding, in
which case it points to that entity instead and awaits a further
specific. Currently the code only handles these two cases, and they
match the behaviour of the evaluation of FacetAccessType itself.

However FacetAccessType evaluation also handles cases beyond these, as
there are other instructions that occur as facet values, such as
ImplWitnessAccess, when accessing an associated constant of an interface
that has a facet type as its type.

Currently eval then crashes in this scenario. Instead of furthering to
reproduce the contents of FacetAccessType's evaluation, defer to calling
the `EvalConstantInst()` overload for it when evaluating
SymbolicBindingType against a new value from a specific. This means
SymbolicBindingType can evaluate back into a FacetAccessType, when it
was originally a FacetAccessType(BindSymbolicName) and becomes
FacetAccessType(ImplWitnessAccess) through a specific.

This comes with a test that crashed in eval before this change.
2025-10-14 15:29:46 +00:00
Richard Smith 90771414f5 Add builtins to form and detect null MaybeUnformed(T*) values. (#6208)
In preparation for modeling `Optional(T*)` as a null pointer value.

With this PR, pointers remain non-nullable, but `MaybeUnformed(T*)` has
a particular unformed state that has the same representation as a C++
null pointer, which is accessible and detectable via builtins.
2025-10-13 20:06:56 +00:00
Dana Jansens fe020ee08b Make FacetAccessType evaluate to SymbolicBindingType for type-of a BindSymbolicName (#6115)
The SymbolicBindingType refers to the type value that will be
substituted in for the BindSymbolicName, but holds onto the EntityNameId
from the BindSymbolicName instead of (or in addition to, for now) the
instruction.

The EntityNameId will be used to look in the ScopeStack to find the
witnesses either from the BindSymbolicName instruction, or other
instructions that specify `impls` constraints against the EntityName.

This will allow us to have the `T` in `I(T)` resolve to a `.Self`
reference in the type so that we get type equality with the binding's
type: `T:! I(.Self)`.
2025-10-06 18:56:43 +00:00
Dana Jansens e3b4482893 Make the GetCanonicalFacetOrTypeValue operation more crisp (#6157)
Previously it performed two kinds of operations, with a boolean
parameter to control whether it would unwrap FacetValue or not. This
made the function hard to explain as "canonicalization".

Now the contract of GetCanonicalFacetOrTypeValue is as follows:
1. For a facet value expression, it returns the canonical value of the
facet value.
2. For a `<facet value> as type` it returns the canonical value of the
`<facet value>`.
3. For other type expressions, it returns the canonical value of the
type.

1 and 2 together collapse together two representations of a facet value
(as a FacetType or as a TypeType) into a single canonical value, which
is important for constant comparison of facet values where the `as type`
is not meant to change the result. This is the case in impl lookups and
`.Self` comparisons.

The step of unwrapping `FacetValue` is only useful in the constant
evaluation of `LookupImplWitness` and is used to collapse *symbolic*
queries on `FacetValue(T)` and on `T` down to a single canonical value,
since they produce the same result later when `T` is replaced with a
facet value or type that can provide a concrete witness. This is now
extensively documented in the constant evaluation of
`LookupImplWitness`.

This change came out of a request/discussion in #6115 (see comment
https://github.com/carbon-language/carbon-lang/pull/6115#discussion_r2383696576).
2025-10-03 15:21:07 +00:00
Jon Ross-Perkins 4a6376cf59 Rename/restructure Destroy logic to better reflect #6124 (#6144)
This also does a little restructuring in the same direction, following
#6124.

Leads want `Destroy` to work similarly now for all types. As a
consequence, there doesn't seem to be as much benefit to splitting off
aggregate destruction. In this PR, the `type.destroy` function can now
be expected to destroy anything that's destructible; that means it'll be
usable for the `final fn` once that support is available.

Similarly, this gets rid of the impls other than the single blanket
impl, now using `type.can_destroy`. Since they all need to use the same
function, there's no benefit to splitting approaches. Also, now it can
just be a `final impl` since there should be no need for people to
create specializations -- if this blanket impl applies, it means the
`final fn` is the same.

This also slips in `partial` support since there's no reason to have it
diverge anymore. Also `abstract`, which I'm not sure is broadly testable
since most cases it'd come up, the `abstract` keyword is explicitly
detected/rejected.

Note though that this doesn't make any really big changes. It's just
realigning on the leads decision. I'm going this way to try to reduce
name-related churn for other changes.
2025-09-30 20:43:36 +00:00
Jon Ross-Perkins 8004c2d5f6 CalleeFunction -> Callee name adjustments (#6117) 2025-09-23 17:51:31 +00:00
Jon Ross-Perkins 0f7df4ed7e Switch CalleeFunction to a variant (#6104)
Trying to make it easier to see what's intended to be present/correct on
`CalleeFunction` in its various modes.
2025-09-22 22:56:38 +00:00
Dana Jansens aa0095c29f Remove TODO in GetConstantValue for FacetTypeId (#6089)
The FacetTypeId comes from a CanonicalValueStore, so the value is
hashed, and if it's the same, the same id will be returned from Add().
2025-09-17 23:37:29 +00:00
Jon Ross-PerkinsandDana Jansens 5e3bb523f8 Add builtin functions for destroy, with special requirements in facet types (#6035)
This is in support of a goal of changing the blanket `destroy` impl to
use (roughly):

```
private fn CanAggregateDestroy() -> type = "type.can_aggregate_destroy";

// Handles aggregate type destruction.
impl forall [AggregateDestroyT:! CanAggregateDestroy()] AggregateDestroyT as Destroy {
  fn Op[addr self: Self*]() = "type.aggregate_destroy";
}
```

That isn't done here because there's still other issues that migrating
raises. What this *does* do is add the builtin functions, and in
particular, support to `FacetTypeInfo` to make `CanAggregateDestroy`
work.

The "special requirement" approach in `FacetTypeInfo` allows us to
support restricting a blanket impl under the current approach of impls.
Maybe we'll find a cleaner approach that can work in the future, but
this fits into the current model by propagating similar to other
requirements. I'm using an enum mask because we have a number of similar
things to add (e.g. copy, move) but I'm not sure we need a full vector.

A few alternatives considered were:

- Supporting syntax more like `where .Self impls
TypeCanAggregateDestroy(.Self, SupportedInterface,
UnsupportedInterface)`. I think it'd be a little cleaner, but requires
better compile-time evaluation in order to assess the type of the call.
Right now it's expected to be a `FacetType` too early to make this work,
and I was concerned about pouring too much more time down this route.
- Providing an actual interface, in particular doing name lookup back
into `Core.` for an interface. This would've added name lookup overhead,
and the question of whether an `impl` exists.
- Generating an interface. This avoids the name lookup, but would still
raise the question of whether an `impl` should also be generated. Work
I've previously done generating interfaces for class destruction also
feels complex to both write and understand (an unfortunate issue).
- Still modeling as an `ImplsConstraint`, for example by defining a
special `InterfaceId::CanAggregateDestroy = -2` similar to what we do on
other ids. I was hesitant because of how this expands the number of
modes of `InterfaceId`, and things for consuming code to watch out for,
for what feels like a relatively niche set of use-cases that are only
interface-like.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-09-15 17:03:43 +00:00
Richard SmithandGeoff Romer 1ec8ac7ef9 Add Copy interface and use it for making copies. (#6034)
Instead of hardcoding which types are copyable, add a `Core.Copy`
interface to perform copying. Move almost all the current copy support
to that interface. Some remaining pieces are still using builtin logic
after this PR:

* For tuples and structs, builtin logic is used to perform elementwise
copies. This also supports copying *adapters of* tuples and structs,
which seems like it may not be desirable, especially for non-extending
adapters. A `Copy` impl is provided for tuples of at most 2 elements, so
that `Core.Copy` constraints are satisfied, but we can't implement this
generally until we have variadics support, and don't yet have a
mechanism to generalize this to structs.
* For `enum` types imported from C++, builtin logic is used to perform a
copy. This is temporary until we have a mechanism to identify these
types from an impl in the prelude.

One lowering test in `toolchain/lower/testdata/class/generic.carbon` is
disabled for now, as it causes a crash in the lowering code due to an
ABI mismatch between the call signature in the lowered declaration of a
specific function and the call that is generated in the specific callee.
Fixing this is a little involved, and will be done in a separate PR.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-09-10 23:55:55 +00:00
Richard Smith 0e6dd7e701 Add MaybeUnformed(T) type. (#5989)
This type has the same object representation as `T`, but always uses a
pointer type as its value representation. No other semantics are
provided for it yet.
2025-09-02 20:50:49 +00:00
Richard Smith b851e8c423 Add support for f16, f64, f128. (#5952)
Generalize the f64 support to support other sizes. Also provide interop
support for `float`, `_Float16`, and `__float128`.

Also lay some groundwork for non-standard floating-point types, though
we don't have any syntax to name them yet.
2025-08-14 01:14:40 +00:00
Richard Smith 629f77eb61 Switch to representing FloatLiteralType as a RealId. (#5944)
Don't convert to f64 until we know that's the type that we actually
want. Also reimplement the conversion from RealId to FloatId to perform
an exact conversion with a real check for overflow, rather than
performing an approximate conversion via the host `double` type.

Unfortunately, LLVM doesn't expose its integer mantissa and exponent to
APFloat conversion, so we convert the RealId back to a string for now.

The LLVM conversion also detects overflow only if the literal would
round to having an out-of-range exponent, not if the literal is outside
the range of values of the type as the Carbon design expects. It's not
clear to me which rule we actually want here, so for simplicitly I'm
using the LLVM rule for now.

In preparation for adding other floating-point types beyond f64.
2025-08-12 22:08:07 +00:00
Richard Smith 28103b8f2e Convert LegacyFloatType into FloatLiteralType. (#5939)
* Rename the type.
* Change lowering to lower FloatLiteralType values as the placeholder
  `{}` value we use for literals instead of as an LLVM f64.
* Change eval to convert the type as part of a floating point
  conversion, so that lowering can lower converted constants properly.

For now we still represent a value of FloatLiteralType as a
double-precision APFloat. (That will need to change so that we can
losslessly convert literals to f80 / f128 values, and so that we can
convert literals to f32 values without double-rounding.)
2025-08-12 18:55:38 +00:00
694c00c7eb Make Core.Float a class. Add missing builtins for float support. (#5932)
Add missing builtins for float compound assignment, for building a
FloatType, and for converting a float literal to FloatType. Switch
`Core.Float` to being a class and add impls for the various
floating-point operators.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2025-08-11 21:01:34 +00:00
Dana Jansens 3d77c4441b Compare ImplWitnessAccess into Self as canonical constants (#5883)
This makes all `.Self` references in a facet type canonically the same
(which will remain true iff they refer to the same `Self` type in the
future), removing the need to do more complex comparisons between them
using the EntityName, interface, and index. This allows the comparison
of types containing `.Self` references to be done correctly regardless
of where the `.Self` appears, as such type expressions will all be
canonically equal if they otherwise equal now, regardless of whether
they are written in the context where `.Self` could have seen different
`Self` facet types.

In order to retain access to constraints on a base `.Self` facet type,
in the case of applying `where` to an existing facet type, we:
- Give the base facet type as a `RequirementBaseFacetType` constraint so
that eval of `WhereExpr` can find and copy all the constraints off of
it.
- Introduce eager/early rewrite constraint resolution, which allows a
constraint to eagerly resolve access to earlier rewrite constraints
(`where .A = () and .B = .A` is eagerly transformed into `where .A = ()
and .B = ()`) before the full constraint resolution step. This allows
use of rewrite constraints in larger type expressions, such as `where .A
= () and .B = C(.A)` and `C` will know that the argument is `()`.
2025-08-08 18:36:39 +00:00
37d5046ceb Support parse/check/lower for char (#5901)
toolchain/check/testdata/builtins/char/basics.carbon and
toolchain/lower/testdata/builtins/char.carbon are probably the most
interesting tests here. The parse tests is required because this adds a
new node kind, and we need coverage of it; but the attached info is
minor. There's a fair amount of test churn here because I'm adding the
Core.Char and Core.CharLiteral types as new singletons.

My intent here is that `CharId` is always a unicode code point, even
when the type is a `Char` and thus must be a single UTF-8 code unit
(single byte). This mainly means the stored value of a `CharValue` can
be printed internally without knowing the type.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-08-06 20:39:01 +00:00
Richard Smithandgoogle-labs-jules[bot] 4685890d63 Rename FloatLiteral to FloatValue. (#5911)
In preparation for `FloatValue` being used more generally, and not only
for literals.

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2025-08-05 22:34:34 +00:00
Dana Jansens 105618ecb1 Resolve nested accesses in rewrite constraints (#5872)
A rewrite constraint like `.X = .Y.Z and .Y = .Self and .Z = ()` has a
nested `ImplWitnessAccess` `.Y.Z` (technically `(.Self.Y).Z`). The inner
access `.Self.Y` needs to be resolved (in this case to `.Self`) before
the outer `???.Z` can be resolved as `.Self.Z` which is `()`.
2025-07-30 14:34:24 +00:00
Dana Jansens b36a987e73 Find cycles in rewrite constraints without performing the full exponential expansion of the RHS (#5673)
Make Subst perform "recursion" on the RHS instructions as they are
replaced, effectively doing a depth-first traversal through the rewrite
constraints doing replacements. This allows us to fully compute
individual associated constants in the minimal amount of work, and cache
the results so they can be reused cheaply in cases where the rewrite
constraints generate an exponential number of references to associated
constants.

Fixes https://github.com/carbon-language/carbon-lang/issues/5672
2025-07-29 16:31:28 +00:00
Jon Ross-PerkinsandRichard Smith b4b4d33789 Change CanonicalValueStore to take ValueT and KeyT as parameters (#5759)
`SpecificInterface` seems oddly placed. It appears to be in ids.h just
because it's used by typed_insts.h, but maybe that should be factored
differently? We typically aren't having typed_insts.h depend on non-ID
types. To that end, I'm splitting it out to its own file so that at
least I'm not adding a `ValueStore` dep inside ids.h

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-07-02 20:58:02 +00:00
Dana Jansens 6c6552ce57 Consistently return runtime phase if the operands contain a runtime (#5729)
Currently if the first operand contains an error, we will return error,
even though the second operands contains a runtime, and it has a
stronger priority (the phase always goes up if possible).

Import is only allowed on instructions with compile-time values, so we
crash if we ever try to import a runtime value. Importable instructions
must diagnose unexpected runtime values and produce errors in the semir
from which they would be imported so that runtime values are never
imported by another semir.

If we had an instruction where you had an error value from the first
operand, and runtime from the second, and we imported it:
- Before https://github.com/carbon-language/carbon-lang/pull/5728 we
would crash in import, but only because we treated errors as runtime
- After https://github.com/carbon-language/carbon-lang/pull/5728 we
would import ErrorInst because we propagate errors. This is desirable
for cases with compile-time values and errors present only.
- After this PR, we would crash again, cuz you're importing a runtime
thing.

This change means that instructions containing an
`InstConstantKind::Never` instruction like`ValueParam` will consistently
evaluate to a runtime value, even if there are errors present. This is
visible in the `BindName` instructions changing in the semir, where they
became constant `ErrorInst` values previously but no longer do.
2025-07-02 19:21:41 +00:00
Jon Ross-Perkins a65f4b89e2 Make ValueStore require a ValueT parameter (#5757)
This is reducing ValueStore inference of types from `using`, and removes
`using ValueType = ...` from affected id types.

I'm adding a number of `using FooStore = ValueStore<FooId, Foo>` because
I think it's a little repetitive otherwise; often 4 cases where I'm
doing this: getter, const getter, member, and getter on `Context`. Note
we also have a number of `-> decltype(auto)` that were added I think
mainly to avoid repeating the type, but I'm not sure whether there'll be
agreement on replacing those and so am not changing them here.

I'm placing these aliases with the value type in general, because I
think it's probably easier to view that way. An alternative would be to
put all the types on `File`, but:

- That would be inconsistent with things like `InstStore`, which are
very `ValueStore`-adjacent and put with their value type.
- `File` would have a _lot_ of using's, and the accessors are already
noisy -- I think it would just make the file harder to skim.

Note this is the heart of what I'd brought up [on
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1388199282250613019).
This PR still leaves CanonicalValueStore and BlockValueStore as things
to also add parameters to, but I thought it best to try breaking the set
of changes apart by type. Both of those rely on ValueStore, so
ValueStore needs to change first.
2025-07-02 18:07:55 +00:00
Jon Ross-Perkins b97646a890 Split value store related types to separate files (#5754)
As I'm looking at splitting value type setting out, this is to make it a
bit easier to see what's part of each type. Note, I expect
`ValueStoreTypes` to remain because of the `StringRef` logic it does --
I'm giving that its own file.
2025-07-01 17:38:56 +00:00
Dana Jansens 3585b31813 Handle insts that resolve to type on the RHS of impls (#5712)
In a facet type constraint, you can write `where .Self impls T` for any
facet type `T`, or the constant `type`. It is possible to write `type`
in different ways though, with a `NameRef` instruction appearing on the
RHS instead of `TypeType`. In this case, the canonical constant value's
instruction will still be `TypeType`, so make eval look at the canonical
instruction to see this.

Add a test with an `alias Type = type` which hits this case.

After this change, we only will accept and find one of the following on
the RHS of `impls`:
- `TypeType`
- A facet type
- An error, if the source code had something else there, which will
already be diagnosed. Tested by `fail_right_of_impls_non_type.carbon`
and `fail_right_of_impls_non_facet_type.carbon`.

So we handle these three cases, and drop the implicit handling of other
things which will never appear there.
2025-06-25 21:45:23 +00:00
Dana Jansens fa6322dd8f Propagate errors in import (#5728)
`AddImportedInstruction` was turning errors in an instruction into a
Runtime constant value instead of an Error, which led to crashes when
importing an instruction that had an error inside it somewhere.

Fixes #5726
2025-06-25 20:41:07 +00:00