Commit Graph
92 Commits
Author SHA1 Message Date
Richard Smith 05ba1d7356 Add a conversion impl from T* to const T* (#7010)
This is already allowed as a builtin conversion, but the impl allows the
generics system to know about it, so that conversions like
`Optional(T*)` to `Optional(const T*)` are allowed. This in turn allows
a C++ `T*` to be implicitly converted to a C++ `const T*` in Carbon
code.
2026-04-03 22:07:53 +00:00
Richard Smith 37b238fa28 Make C++ types impl Core.Default. (#6962)
C++ classes that are default-constructible now implement `Core.Default`
by calling the default constructor.
2026-03-25 21:07:24 +00:00
bc38deb16c adds witness support for associated types (#6937)
This commit creates an instance for any associated types in an interface
with a custom witness table. This unlocks interfaces designed for C++
interop that rely on arbitrary return types. For example,
`CppUnsafeDeref` becomes usable as of this commit.

This commit may have also implemented support for non-type associated
constants, but since we're lacking a practical test case, they're still
marked as TODO for the time being.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-20 22:03:52 +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
Christopher Di BellaandRichard Smith 4df2b6ea9d adds checking support for CppUnsafeDeref witness (#6890)
Iterators, smart pointers, optional, and expected types depend on
`operator*`. This commit adds `CppUnsafeDeref` as a core interface, with
an associated function, so that the compiler can dereference
user-defined C++ types.

Things not implemented in this commit:

* `operator*` overload resolution
* SemIR lowering

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-12 18:02:34 +00:00
Richard Smith c297344937 Support conversion between integer types. (#6856)
Add an `IntFitsIn` interface with a custom witness, such that `T impls
IntFitsIn(U)` if `T` is an integer type all of whose values fit
losslessly into the integer type `U`. Use it to constrain implicit
conversions between integer types.

So far, this has not been extended to the
`CppCompat.[U]{Long32,LongLong64}` types, only to `Core.Int(N)` and
`Core.UInt(N)`.

Assisted-by: Gemini 3 Pro via Antigravity
2026-03-10 01:40:16 +00:00
Geoff Romer 34764d0d0e Fix issues from #6745 (#6811)
- Typo in the definition of `Core.Form`
- Resolved TODO to add test coverage
- Restored lexicographic order in a switch
2026-02-27 22:47:00 +00:00
fdb188ccfd Implement unused pattern bindings, continued (#6518)
Implementation of unused pattern bindings #2022, continued.

Whereas previous PR #6460 took care of parsing, and PR #6479 prepared
the stage by using _ in some test cases, this PR has the the actual
implementation, using a simple dataflow analysis.

---------

Co-authored-by: Burak Emir <bqe@google.com>
Co-authored-by: jonmeow <jperkins@google.com>
2026-02-19 23:33:36 +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
Nicholas Bishop 1382a8645a Replace convert_checked with convert in some ImplicitAs impls (#6704)
`convert_checked` is for conversions that are checked at compile time.
Since these conversions do not require a constant value they should use
`checked` instead.

(Split out from
https://github.com/carbon-language/carbon-lang/pull/6673, explanation of
convert/convert_checked derived from the [Jan 20, 2026 meeting
notes](https://docs.google.com/document/d/1YlxEOJ0r-o19o19TCJbFl4Ln1U88yn_Vj23y1Hr5vTk/edit?tab=t.tjeylv584s7j#heading=h.ih31dlc0ma58).)
2026-02-06 21:50:59 +00:00
Ivana Ivanovska 9f69ebf6de Add heterogeneous bitwise operators for CppCompat.Long32 (#6661)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-29 16:04:46 +00:00
Ivana Ivanovska de4a2ee6c8 Add missing operators for CppCompat.LongLong64 (#6663)
Adds arithmetic and bitwise operators, compound assignments, and
increment/decrement operations for CppCompat.LongLong64.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-28 19:24:21 +00:00
Ivana Ivanovska 3757a79f4c Add heterogeneous arithmetic operators for CppCompat.Long32 (#6644)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-27 17:39:36 +00:00
Ivana Ivanovska ff38378efc Add comparisons for CppCompat.LongLong64 (#6643)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-26 11:29:40 +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 a2e4c31e8e Clean up after combination of #6634 and #6635. (#6640)
We can now cast directly from `T*` to `U*`; stop going via `void*`. Also
remove the conversion impl from `void*` as it's now subsumed by the
general impl.
2026-01-21 21:03:35 +00:00
Ivana Ivanovska c9dbf40f11 Add comparisons for CppCompat.Long32 (#6639)
Support for both homogeneous and heterogeneous comparisons are added for
CppCompat.Long32.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-21 19:11:48 +00:00
Richard Smith 8353965ca3 Allow conversions between all pointer types with unsafe as. (#6635)
Previously we only allowed conversions from `void*` to `U*` this way,
requiring casting via `void*` to get from `T*` to `U*`. That seems like
an unnecessary circumlocution.
2026-01-21 15:47:51 +00:00
Ivana Ivanovska a448792207 Enable heterogeneous compound assignments for CppCompat.Long32 (#6628)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-21 13:27:58 +00:00
Ivana Ivanovska c0e7198995 Implement copying for ULong32, LongLong64, ULongLong64 (#6627)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-20 20:36:17 +00:00
Ivana Ivanovska 082b420f6e Provide increment and decrement operators for CppCompat.Long32 (#6622)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 22:58:56 +00:00
Ivana Ivanovska ec0a8a9b52 Implement copying for CppCompat.Long32 (#6625)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 15:25:48 +00:00
Ivana Ivanovska c252e7d31e Implement compound assignments for CppCompat.Long32 (#6621)
Only homogeneous compound assignments are supported for now.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 11:17:18 +00:00
Ivana Ivanovska 9ee2177dd4 Add bitwise homogeneous operators for CppCompat.Long32 (#6584)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-15 15:07:14 +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
Ivana Ivanovska d1b13194d5 Add arithmetic operators for CppCompat.Long32 (#6573)
`CppCompat.Long32` is a distinct type, mapped to C++ `long` on `LLP64`
(64-bit Windows).

Context: #6275.

Part of #5263.
2026-01-12 11:58:14 +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
josh11bandJosh L 77caf3b9d8 Add Core.PrintStr and a "hello world" example (#6493)
Thanks to @ammaralassal for #6329 which did the heavy lifting to make
this possible!

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2025-12-12 20:07:05 +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
Chandler Carruth 5d0d443c98 Move the :install_paths library to //toolchain/base (#6457)
Previously this was kept in `//toolchain/install` so it would be near to
the code that actually defines the installation layout. However, that
creates somewhat unfortunate dependency cycles between
`//toolchain/install` and other directories. Exacerbating this, a
subsequent PR is likely to add dependencies on it from
`//toolchain/base` itself that suggests that is the correct layering.

This PR just moves the code mechanically with as few other edits as
possible.
2025-12-03 17:14:34 +00:00
Boaz Brickner 2073594d8a C++ Interop: Add implicit casting between int literals and CppCompat integers (#6442)
Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2025-11-28 08:49:47 +00:00
Boaz Brickner bef92cf881 Add CppCompat.ULong32, CppCompat.LongLong64 and CppCompat.ULongLong64 (#6386)
This extends #6364 to allow having:
* `Cpp.unsigned_long` as a distinct type when `unsigned long` is 32
bits.
* `Cpp.long_long` and `Cpp.unsigned_long_long` as distinct types when
`long` and `unsigned long` are 64 bits.

Similarly to #6364, we only support implicit conversions from the
matching literal type (`u32`, `i64` and `u64`).

See #6275 for rationale.

Part of #5263.
2025-11-26 16:51:22 +00:00
Richard Smith 0678501038 Replace builtin CppVoidType with a prelude type. (#6403)
Following #6357, map C++ `void` to a prelude class type
`Core.CppCompat.VoidBase`, not to a builtin type. This is mostly just
moving logic around, but does notably change `Cpp.void` from being an
incomplete type to being a complete-but-abstract type.

Also change `NullptrT` to be an adapter for `void*` instead of `()*`, to
follow the approved design.

Implicit conversions to `void` and to `void*` are still absent.

Part of #6280.
2025-11-19 20:40:17 +00:00
Boaz Brickner bc734bb768 C++ Interop: Add Core.CppCompat.Long32 as a distinct type for Cpp.long when long is 32 bits (#6364)
For now, only support implicit conversions from and to `i32`.

See #6275 for rationale.

Part of #5263.
2025-11-14 23:26:43 +00:00
Geoff Romer 2b8fdf3417 Switch the prelude to use ref instead of addr (#6359) 2025-11-14 00:40:26 +00:00
Richard Smith 86b02ee8af Interop support for nullptr and nullptr_t. (#6353)
Add a `Core.CppCompat.NullptrT` type that C++'s `nullptr_t` maps into.
Map `nullptr` to an uninitialized constant of that type -- `nullptr`
doesn't actually have any defined bits within it, despite having the
same representation as `void*`.
2025-11-12 23:23:48 +00:00
Richard Smith 5db1141f52 Allow adding / removing const with ImplicitAs. (#6323)
If `T` implicitly converts to `U`, then:

 * `const T` implicitly converts to `U`,
 * `T` implicitly converts to `const U`, and
 * `T` implicitly converts to `Optional(U)`.
2025-11-05 07:38:09 +00:00
josh11bandJosh L c329bce240 PrintChar from "io" library takes a char (#6264)
As [observed in
#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1428791603786416351),
this makes demo code nicer.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2025-10-23 16:38:20 +00:00
Richard Smith 851da43c88 Make Optional support specializing its representation. (#6058)
Switch to using a pair of `MaybeUnformed(T)` and a `bool` as the normal
representation for `Optional(T)`. When `T` is a pointer type, add a
customized representation that uses `MaybeUnformed(T*)`, with a null
representation used for absent values.
2025-10-15 22:34:22 +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 e1b87ac2e1 Change IndexWith to use a standard binary operator setup (#6127)
This is closer to [the
design](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/indexing.md?plain=1#L55-L64),
just lacking `ref`, but does remove a lot of special-casing done for the
lookup.

The `ErrorInst` changes in `Build*Operator` are to align with what was
being done for `IndexWith`; don't do an interface lookup if the relevant
operand is an error. Otherwise, that becomes visible because some files
have an error operand and don't provide the interface.
2025-09-29 18:17:48 +00:00
Jon Ross-Perkins 705c95d6e0 Drop fn destroy support (#6136)
`fn destroy` is being removed per decision on #6124. It seems like the
relevant decision will result in no more keyword-based function names,
so this is removing all related support.
2025-09-25 21:56:48 +00:00
Jon Ross-Perkins 9704dc670e Change the Destroy blanket impls to be more specific (#6098)
The main direction of this change is the edits to `destroy.carbon`
(matching in both prelude and min_prelude).

Previously there was a no-op blanket impl for `Destroy`, which hid all
missing implementations of `Destroy`. This does a few things:

- Sets up builtin aggregate destruction for struct and tuple types as
before, but also adds C++ class types and array types to the same
handling. (all as a TODO for actual implementation)
- Also maybe-unformed destruction, for now at least. (there's a chance I
may try a different approach on this, but the impl lookup wasn't working
as I'd hope in order to write it in code)
- Adds handlers for simple things that are easy to do in code: `type`,
`bool`, pointers. (because these are no-op destruction)
- Redirect `const T` destruction to `T` destruction.

This leaves as future issues:

- `partial T` destruction. (this can't be done similar to `const`
because it only works for non-`final` class types; I think `class`
definitions should just generate what's needed)
- Destruction of other prelude-provided types. (will probably come up as
we implement class destruction, that the adapted builtin type doesn't
implement `Destroy` -- but may end up special-casing that in a way that
moots it)

This moves the `&` operator from `facet_types.carbon` to
`convert.carbon` because more things need to handle type and now that
we're getting separate copy and destroy interfaces. It should be
low-cost (an interface and builtin) so hopefully this is the right
balance for complexity and re-use.

A few tests are also edited in order to focus them more on what they
intend to test, and avoid a `Destroy` dependency.
2025-09-18 22:10:50 +00:00
Richard Smith 6086d6eef2 Make str copyable. (#6083) 2025-09-17 01:04:24 +00:00
Richard Smith d60900cbeb Remove special case for returning value expressions by copy (#6052)
When returning a value from a function whose return type has a by-copy
initializing representation, perform initialization like we do when the
return type has an in-place initializing representation. This makes our
SemIR representation more uniform, as the return expression will now
always be an initializing expression rather than a value expression, but
more importantly it means that attempts to return a non-copyable type by
value now fail, even if the type has a by-copy initializing
representation.

This catches a bunch of places where we were returning a value of an
unconstrained template parameter `T:! type`, which we were incorrectly
allowing because we didn't notice it was not copyable. Unfortunately
this then requires quite a few test updates.

Like #6034, this exposes a lowering issue where lowering crashes when
attempting to lower a specific copy operation for certain types; a
couple more tests are temporarily disabled here. An upcoming PR
dependent on this one will fix the issue and re-enable those tests.
2025-09-12 00:13:33 +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 Smithandjosh11b 10fab24451 Add example showing basic interop with C++ RE2 library (#5967)
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-09-03 20:41:48 +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 50e5476ee3 Add support for unsafe as operator to the toolchain. (#5993)
Following the direction of #5913, add support for parsing an `unsafe as`
operator. For now, we allow one additional conversion using `unsafe as`
beyond the conversions supported by `as`: we permit pointer conversions
that remove qualifiers, such as `const T*` -> `T*`.
2025-08-28 23:00:53 +00:00
Richard Smith 41ed82e033 Add basic support for strings to core, check, and lower. (#5963)
Add a `Core.String` class to the prelude representing a string view, and
rename the `String` keyword to `str` and make it evaluate to
`Core.String`.

`Core.String` is represented as a pair of a pointer to a character
(actually, to the first character of a string, but we don't have a way
of modeling that yet) and a size (which should be pointer-width, but is
currently always a `u64` as we don't have a `usize` equivalent yet).
`Core.String` values are generated directly by the toolchain for string
literal expressions.

This follows the direction established at the recent summit, but the
design implemented here has not been through the proposal process yet.
2025-08-20 00:18:50 +00:00