114 Commits
Author SHA1 Message Date
Christopher Di Bella f7cd39428e Add Destroy.SubobjectDestroy as a temporary replacement for Destroy.Op (#7773)
This change partially implements [PR #7362], which revises how objects
are destroyed. It is a partial implementation for two reasons:

1. This change moves `Destroy.Op`'s current behaviour into
`Destroy.SubobjectDestroy`, but it doesn't add support for objects with
non-trivial destruction.
2. `Destroy.SubobjectDestroy` is a workaround for `require impls
SubobjectDestroy`. We aren't able to use the latter until the dependents
add their requirements' implementations to their own witness tables.

[PR #7362]: https://github.com/carbon-language/carbon-lang/pulls/7362
2026-09-24 00:06:28 +00:00
Richard Smith b8814f6c80 Add named constraints for Eq and Ordered. (#7714)
Also add a default for `EqWith.NotEqual`.

Switch advent examples to use these named constraints, and also go
through all the other TODOs in the advent examples and fix the ones that
are trivially fixable now.
2026-09-03 16:20:13 +00:00
Dana Jansens 48671bffe2 Use match_first and remove some workarounds in prelude float.carbon (#7713)
The float.carbon conversions for int->float, uint->float and
float->float were using various workarounds through extra indirections
in order to avoid the impls overlapping. Now we can write them all as
`impl From as ImplicitAs(Float(To))`, which makes them all appear to
overlap, though any given type will only match at most one of them. We
use `match_first` to give them an ordering regardless so that they are
allowed to overlap in type structure.
2026-09-03 14:58:27 +00:00
DavidLoftus 70b6abd6f1 Implement FloatLiteral addition and subtraction (#7621)
Addresses part of issue raised in
https://github.com/carbon-language/carbon-lang/issues/7159 by
implementing float.add & float.sub builtin for FloatLiteralValues

The following code now compiles:

```
let a: f64 = 1.0 + 1.0;
```

Code handles case where operands are both decadic (base 10) and dyadic
(base 2) real literals, with the result being whichever format results
in smaller mantisssa.

File tests assert equality by converting to f128, this can possibly be
improved once CompareWith is implemented for FloatLiteral too.

Assisted-By: Gemini
2026-08-18 17:47:58 +00:00
DavidLoftus 54b7f1345a Implement Core.Negate for float literals (#7616)
Addresses part of issue raised in #7159 by implementing float.negate
builtin for FloatLiteralValues

The following code now compiles:

```
let a: f64 = -1.0;
```

To achieve this I switch the mantissa from being unsigned to signed.
Lexed literals within source file will still always be unsigned, however
it is now possible to create negative FloatLiteralValue constants. Main
non-local changes this causes is:

- All llvm::APInt parsing / printing calls flipped isSigned param
- Zero extension replaced with sign extension
- getActiveBits() replaced with getSignificantBits() for min bit width
calculation
2026-08-13 20:28:42 +00:00
Christopher Di Bella 8e90e2a855 Change String.size from u64 to i64 (#7614)
`String.size` is likely to be a signed word-sized integer in the future,
(per a Discord conversation). Changing to `i64` now allows us to iterate
over a string's contents using `IntRange`.
2026-08-07 18:14:50 +00:00
Richard Smith c278bea3c5 Support LP64 platforms such as Darwin where int64_t is long long. (#7596)
Add `Core.CppCompat.[U]Long64` to represent a 64-bit long that is not
`i64`. Treat it as being "just slightly smaller than" `i64`, like we
treat `Core.CppCompat.LongLong64` as being "just slightly larger than"
`i64`, so that we get implicit conversions `Cpp.long` -> `i64` ->
`Cpp.long_long` on all targets.

This follows the direction of proposal #5448, and seems like the obvious
extension of the `[U]Long32` and `[U]LongLong64` types added in #6275
for targets of this "shape".

Assisted-by: Gemini via Antigravity
2026-08-07 16:10:01 +00:00
Lucile Rose Nihlen 3a37b89da2 Change carbon_library Bazel parameters back to srcs and hdrs (#7585)
It's come up that `carbon_library` better represents a linkage unit
instead of having to closely mirror the Carbon language library concept.
Given that we can have more than one API file in a linkage unit, and
that `srcs` and `hdrs` gives better compatibility with other C++
tooling, this PR switches `impls` and `api` back to `srcs` and `hdrs`,
and fixes up the broken code.
2026-07-29 18:49:54 +00:00
Richard SmithandDana Jansens 643ab57f5a Refactor CppRange interface and fix a crash exposed by doing so. (#7515)
Split up the CppRange interface into smaller parts, with the intent of
improving the diagnostic quality and making the implementation easier to
understand.

This also makes the implementation details of the CppRange machinery
private, which breaks one of the existing tests; that test is split into
two files, one which tests the low-level machinery works, and another
that tests the resulting prelude behavior.

This change exposes a crash in `where` expression handling, where we
would perform a substitution that creates a new `SpecificConstant` that
refers into a region of a generic that has never been resolved. Fix that
by resolving the definition region of a generic if eval sees a
`SpecificConstant` that refers into it. This is usually not necessary
because something else should have resolved that region first, but that
doesn't happen here.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-07-17 00:31:12 +00:00
Lucile Rose Nihlen 31cc20f6e3 move Core//range into prelude (#7524)
As discussed in the 2026-06-14 toolchain open meeting, `Range`
is a better fit for the prelude than as a general library in
`Core`. This PR moves `Range` into the prelude, and updates
the build infrastructure and various tests to reflect that
change.
2026-07-16 21:36:45 +00:00
Lucile Rose Nihlen 625f2ca629 precompile and cache Carbon prelude (#7432)
Refactors the link driver to automatically compile and cache the carbon
prelude for use in linking.

Implements a `carbon_library` rule for compiling the Core library
dependencies in the examples.
2026-07-16 18:02:14 +00:00
Chandler Carruth 8be274cf60 Replace :! binding syntax with phase keywords and contextual defaults (#7479)
Implement the toolchain side of proposal #7254, removing the `:!`
binding
syntax for generic and template parameters in favor of the keywords
`generic`,
`template`, and `runtime` plus contextual defaults for phase.

For valid programs this is semantics-preserving: each binding resolves
to the
same phase, and produces the same SemIR, as it did under `:!`/`:`. The
parser
derives a binding's phase from its syntactic context plus any explicit
phase
keyword; new diagnostics and error recovery for misused keywords are
described
below.

Implementation details for each component:

- Lexer: remove the `:!` (`ColonExclaim`) token, move its virtual
parse-node
  budget onto `:`, and add the `generic` and `runtime` keywords.
- Parser: thread a `BindingContext` (`ExplicitParam`, `DeducedParam`, or
`CompileTimeEntityParam`) from declaration introducers down through
parameter
lists to each binding pattern, using a one-token lookahead to
distinguish a
name-qualifier parameter list from a declaration's own final list.
Parameters
of a compile-time entity (`class`, `interface`, `constraint`, `choice`,
`alias`, `export`, `namespace`) and deduced `[]` parameters default to
checked
generic; explicit function parameters and local bindings default to
runtime.
`HandleBindingPattern` resolves the phase from that context plus the
keyword: a
`generic` keyword needs no node of its own (the phase is carried by the
  binding's node kind), while a `runtime` keyword is preserved as a
`RuntimeBindingName` node so `check` can name it in a diagnostic. A
phase
keyword that is merely redundant with the contextual default is
diagnosed
  here, without invalidating the parse tree.
- Check: a phase keyword that is invalid for its context (for example
`runtime`
on a checked-generic parameter) is diagnosed here, and recovers by
building an
error binding that still introduces the name so that later uses of it do
not
  produce cascading errors.

The removed `:!` syntax is now rejected as an ordinary parse error.

The `form`/`:?`/`->?` ("extended types") portion of proposal #7254 is
left for a
separate change.

Assisted-by: Claude Code
2026-07-11 01:22:44 +00:00
Richard Smith 25e72882fc Implement Core.CharLiteral operations from #6710 and #7314 (#7316)
Adds support for arithmetic and comparison operators on
`Core.CharLiteral`s, as well as conversions between `CharLiteral` and
integer types.

Make some minor tweaks to fix skill issues encountered while making this
change.

Assisted-by: Gemini via Antigravity
2026-06-11 16:45:39 +00:00
Chandler Carruthandjosh11b 7871237c15 Move self to the explicit () parameter list (proposal #7016) (#7272)
Implements proposal #7016: `self` moves from the deduced implicit list
(`fn F[self: Self]()`) to the front of the explicit list. Its type may
be written explicitly (`fn F(self: Self)`) or omitted, in which case it
defaults to `Self` (`fn F(self)`, `fn F(ref self)`); `self` in the
implicit list is rejected.

Throughout checking, `self` is modeled as the first explicit parameter.
Because a method is just a function whose first parameter is `self`, it
can also be called as an ordinary function with the receiver passed
explicitly (`Type.M(obj, ...)`), not only as `obj.M(...)`. A new
`SemIR::CallArgParamPatterns` helper chooses the parameters matched
against the explicit arguments, excluding a leading `self` only when it
is supplied as a method-call receiver; arity checking, conversion, and
generic deduction use it. The resulting SemIR and lowering are
unchanged: `self` is still `call_param0`, and witnesses, thunks, and
vtables are unaffected.

An omitted `self` type is parsed as a `SelfBindingPattern` node with no
type expression; checking synthesizes the `Self` type so it behaves
exactly like `self: Self`. However, the exact spelling used must match
between a forward declaration and a definition, following #3763's rules
around declaration matching.

Generated functions, thunks, and C++ interop import/export build `self`
as the first explicit parameter, and the `self`-type override (e.g.
Derived->Base for a virtual override) applies to the explicit `self`.
Placement is validated by new diagnostics: `SelfInImplicitParamList`,
`SelfNotFirstParam`, and `SelfOutsideParamList`. The benchmark source
generator and the documentation adopt the `(self)` shorthand; the
prelude, the examples, and the test data are migrated in the following
commits.

Assisted-by: Claude Code with Claude Opus 4.7

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2026-06-10 15:30:43 +00:00
Richard Smith ae6846197a Remove trailing () from Core.*Literal and Core.Bool. (#7313)
We exposed `Core.IntLiteral()`, `Core.FloatLiteral()`,
`Core.CharLiteral()`, and `Core.Bool()` as functions as a workaround,
because we had no way to provide the type names without parentheses that
the design requests. But now we can do so, by using an alias. Switch all
of these over from being functions to simply being names of the
corresponding types.

Assisted-by: Gemini via Antigravity
2026-06-05 22:33:30 +00:00
Richard Smith 88c191146d Support for float <-> float conversions. (#7279)
Implement support for floating-point <-> floating-point type conversions
as described in https://github.com/carbon-language/carbon-lang/pull/820
and https://github.com/carbon-language/carbon-lang/pull/845.
Value-preserving conversions are implicit; narrowing conversions require
explicit `as`.

Assisted-by: Gemini via Antigravity
2026-06-04 00:33:33 +00:00
Richard Smith 7fe3e35aec Support for float <-> int conversions. (#7275)
Implement support for floating-point <-> integer type conversions as
described in #820 and #845, extended to support `unsafe as` conversions
for the conversions that can't be expressed as either implicit
conversions or `as` conversions.

One tricky part here is conversions from floating-point literals to
integer types. Such literals may have both a very large mantissa and a
corresponding somewhat large negative exponent, and still produce a
result that is in the range of values that a small integer type can
represent. In order to support that while avoiding building very large
2^N or 10^N constants in general, we first compute a conservative
approximation of the number of bits necessary to represent the integer
result, with an early exit if the number is either definitely too large
or definitely zero. The remaining cases have a reasonable bound on the
size of integer necessary to compute the base^exponent multiplicand.

Assisted-by: Gemini via Antigravity
2026-06-03 23:41:20 +00:00
Christopher Di Bella 61ee4edd9c Implement Iterate for types that implement CppRangeForIterate (#7294)
This change adds rudimentary support for C++ ranges in Carbon range-for
loops. Since C++ ranges are exposed through `Core.Iterate`, C++ ranges
have the same limitations as Carbon ranges (e.g. can't return
references).

`Iterate.CursorType` now requires `Destroy`, since types that implement
`CppRangeForIterate` can't be used in range-for loops unless their
cursor type can be verifiably destructible.
2026-06-03 04:51:09 +00:00
Christopher Di Bella d578e4afe7 Remove ref pattern from CppUnsafeDeref (#7293)
Since we can't currently iterate over ranges as references, the
`CppUnsafeDeref` interface can't require types that implement it to take
or return references.
2026-06-03 01:22:07 +00:00
Richard Smith e45045d63b Implement char operations from #6710 (#7266)
This only covers `char`, and does not include the `CharLiteral`
operations.

Assisted-by: Gemini via Antigravity
2026-05-27 23:18:27 +00:00
Richard Smith 09d1331e85 Make Optional(T) copyable. (#7268)
`Optional` is already restricted to only be able to store copyable
types, so it should always implement `Core.Copy`.
2026-05-27 18:13:26 +00:00
Christopher Di BellaandRichard Smith 2aaa061688 Support detecting begin()/end() methods for range-for loops (#7185)
This commit adds support for range-based for loops using C++ types. It's
currently limited to detecting that `r.begin()` and `r.end()` are
available. We should be able to add full support for methods after #7181
is merged.

Support for ADL is still a work-in-progress, and will be added at a
later time.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-05-12 19:03:55 +00:00
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