Commit Graph
4274 Commits
Author SHA1 Message Date
Boaz Brickner 1d314c7c4d Import C++ constructors of class Type fn Type(...) -> Type (#5879)
Only supports classes with a single (non copy non move) constructor
(without default values), until overloading is supported.

Based on #5878.

C++ Interop Demo:

```c++
// hello_world.h

#include <cstdio>

class C {
 public:
  C(int x, int y) : x_(x), y_(y) {}

  int x() const { return x_;}
  int y() const { return y_;}

 private:
  int x_;
  int y_;
};

void hello_world(C* _Nonnull c);
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

void hello_world(C* _Nonnull c) {
  printf("C.x = %d. C.y = %d\n", c->x(), c->y());
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  var c : Cpp.C = Cpp.C.C(1, 2);
  Cpp.hello_world(&c);
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
C.x = 1. C.y = 2
```

Part of #5880.
2025-08-06 12:02:38 +00:00
Boaz Brickner 3c9d267388 Generate and use a C++ thunk to call non simple ABI C++ functions (#5850)
When the C++ function has a parameter that is not a pointer and not a
signed integer of 32 or 64 bits, generate a thunk.

Terminology:
* Callee function: The C++ function we actually want to call.
* Thunk function: The C++ function we generated that calls the callee
function.
* A simple ABI type, for now, is one of:
  * A pointer
  * signed integer with 32 bits
  * signed integer with 64 bits

The thunk function is marked `always_inline` and uses the `asm`
attribute to set its mangled to the callee function mangled name
suffixed with `".carbon_thunk"`.

When importing a C++ function, we decide whether calling it requires a
thunk and if so we generate it and import it as well, which is currently
a recursive call.

When calling the thunk function, we initialize a temporary storage for
each non simple ABI parameter type and take its address. This can be
optimized when the variable is already in storage.

Not supported yet:
* Functions with non void return values.
* Member methods.

Moved unsigned int param test from `arithmetic_types_direct.carbon` to
`arithmetic_types_bridged.carbon`, since only signed integers aren't
bridged using a thunk.

C++ Interop Demo:

```c++
// hello_world.h

struct S {
  S() {}
  S(const S&) { x = 1; }
  int x;
};

void hello_world(S s);
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

void hello_world2(S s) { printf("hello_world2: %d\n", s.x); }

void hello_world(S s) {
  printf("hello_world: %d\n", s.x);
  hello_world2(s);
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  var s : Cpp.S;
  Cpp.hello_world(s);
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
hello_world: 1
hello_world2: 1
```

Before this change (no thunk - copy constructor not called when calling
`hello_world()`):
```shell
$ ./demo
hello_world: -1219172304
hello_world2: 1
```
2025-08-06 10:27:33 +00:00
Richard SmithandJon Ross-Perkins 7cac77119c Support import Cpp inline "some code";. (#5904)
This adds support for importing C++ code directly from source rather
than via a `#include`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
v0.0.0-0.nightly.2025.08.06
2025-08-05 23:03:32 +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
Richard Smith bd2483b553 Don't use Check::Context when emitting C++ diagnostics. (#5910)
Diagnostics can get flushed after the context is destroyed. Should fix
an issue found by msan.
2025-08-05 21:21:30 +00:00
Jon Ross-Perkins fd4dbc5b6f Remove clang prefixes from isa/cast when optional (#5909)
This is from a quick discussion with zygoloid. There's a mix of uses,
we're both comfortable with a "minimum syntax" decision here to use ADL.

Note this doesn't touch llvm::cast uses in yaml_test_helpers, but ADL
doesn't work there (because the objects are in a `llvm::yaml`
namespace). This gets to another choice made here: if we specify a
namespace, prefer `llvm::` because it's shorter. `clang` has a using of
them, but it's probably better to point at the canonical version if
we're being explicit about it.
2025-08-05 20:04:51 +00:00
Dana Jansens 905c964278 Remove two todos in facet_type.cpp (#5908)
The first TODO is done/under development. The second is no longer
relevant now that we don't ever invalidate pointers into ValueStores.
2025-08-05 19:27:54 +00:00
Boaz Brickner 720c77f6e7 Don't use struct literals in tests (#5906)
The first version of C++ overload resolution would not support struct
literals, so we prepare the tests for that.
2025-08-05 18:57:03 +00:00
Boaz Brickner 29c102bd15 Add missing Cpp. to unsupported decl type test (#5907)
Followup of #5787.
2025-08-05 18:30:42 +00:00
Jon Ross-PerkinsandGeoff Romer 7209ad7c9f Generate Destroy impls for classes (#5873)
Although this focused on `Destroy` support, some choices here around
`implicit_type_impls` are because copy/move will likely follow a similar
approach. I'm trying not to predict too much about how we'll structure
those, but I'm putting `Destroy` impl logic in a file that could perhaps
be shared with those. They'd likely be interested in similar things,
e.g. traversing members of types (particularly class, struct literal,
tuple literal).

At present this sets the destroy function as `no_op` which is consistent
with current logic, but has a TODO to correctly define.

Constant importing for functions changes slightly due to some issues I
was having with `GetFunctionType`. zygoloid suggested this approach to
avoid `EvalInst` logic.

Adds a flag for controlling whether to generating these impls. While
this does generation for `class`, as noted above this'll also need to be
done for tuples and struct literals, which would leave the `none.carbon`
min_prelude unable to use any types. Note if destruction *would* occur,
it'll still look up `Core.Destroy` for that and fail, but that's already
true of any test using `none.carbon`. I'm trying to use the flag to see
if we can keep `none.carbon` working mostly-consistently.

I'd tried separating out the flag to #5852, but that got a lot of
pushback over whether the behavior was appropriate. I'm hoping that the
interactions here make it clearer why the particular approach -- the
goal is not to enable advanced testing, or create some new end-user
behavior that we really support, it's just to keep no-prelude tests
functional. The main question raised there was why not just keep
generating `impl T as Core.Destroy` if `fn destroy` is present -- but I
think here it should be apparent that would require additional
complexity, as the generation of `impl T as Core.Destroy` is not
currently conditioned based on the implementation of `fn destroy`. I'd
rather add complexity to this flag only if it's enabling interesting
test functionality.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
v0.0.0-0.nightly.2025.08.05
2025-08-04 19:39:22 +00:00
Dana Jansens a5a5e381be More tests for early rewrite application and implied constraints (#5892)
Attempting to capture all the use cases described in [open discussion
2025-07-31](https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.lup43xycic7t).
v0.0.0-0.nightly.2025.08.04 v0.0.0-0.nightly.2025.08.03 v0.0.0-0.nightly.2025.08.02
2025-08-01 21:38:49 +00:00
Alina Sbirlea 7198050573 Docs for specific coalescing. (#5886)
Add documentation describing the problem and algorithm for coalescing
the LLVM functions generated from Carbon generic functions into fewer
LLVM functions, where the LLVM types permit it.
2025-08-01 19:01:20 +00:00
Geoff RomerandJon Ross-Perkins 48e75892bf Document pattern-matching implementation (#5846)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-08-01 18:42:40 +00:00
Jon Ross-PerkinsandRichard Smith cae8aa3adf Support lexing characters (#5893)
Adapts `StringLiteral` to lex characters. Adds a `CharLiteral` token,
which contains a `CharLiteralValue` which is a straight unicode code
point (suggested by zygoloid).

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-08-01 18:24:03 +00:00
Dana Jansens c707a6deaa Verify rewrite constraints in impl lookup (#5617)
In order to verify rewrite constraints at the end of
`LookupImplWitness()` we need to replace references to associated
constants in the query facet type with values that come from the query's
self. To do this, we find any `ImplWitnessAccess` that is a reference to
`.Self` and replace its witness with the witness found through the impl
lookup process, if the interfaces match. This allows the
`ImplWitnessAccess` to resolve to a concrete value if that witness was
concrete. Then we just need to compare that for each rewrite constraint
the lhs and rhs are the same constant value. If they differ, the self
provided a different value for one side (either through its own facet
value constraints or through an associated impl), or the self did not
provide a value at all.

For now, only .Self references in the top-level facet type are
rewritten. Nested facet types are not, even if they contain a .Self
reference up to the top level facet value. This will be addressed by
adding numbering to the EntityName of of .Self in a BindSymbolicName.
See the third model in
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0
for the plan. For now, there is a TODO addressing this.
2025-08-01 18:04:20 +00:00
ac98870e67 ref parameters, arguments, returns and val returns (#5434)
- A parameter binding can be marked `ref` instead of `var` or the
default. It will bind to reference argument expressions in the caller
and produces a reference expression in the callee.
- Unlike pointers, a `ref` binding can't be rebound to a different
object.
- This replaces `addr`, and is not restricted to the `self` parameter.
- A `ref` binding, like a value binding, can't be used in fields of
classes or structs.
- When calling functions, arguments to non-`self` `ref` parameters are
also marked with `ref`.
- The return of a function can optionally be marked `ref`, `val`, or
`var`. These control the category of the call expression invoking the
function, and how the return expression is returned.
- These may be mixed for functions returning tuple or struct forms.
-   The address of a `ref` binding is `nocapture` and `noalias`.
- We mark parameters of a function that may be referenced by the return
value with `bound`.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-08-01 17:43:41 +00:00
Richard Smith e3a366f1c3 Add prelude impl of Iterate for array types. (#5895)
Iterate over arrays by producing their elements in the obvious way. We
use `i32` as the cursor type because that's the type that check converts
array indexes to. This may need revisiting if we support arrays with
more than 2Bi elements.

Also includes a fix for an import crash bug that's triggered by this
change, borrowed from #5873.
2025-08-01 16:13:22 +00:00
Boaz Brickner 7de86a0b10 Move and deduplicate testing access when a Carbon class extends a C++ record to access.carbon (#5897)
Followup of #5858.
Part of #5859.
2025-08-01 13:44:08 +00:00
Richard Smith 25681901bd Improve mapping of Clang diagnostics into Carbon diagnostics (#5894)
Instead of taking the complete text of the Clang diagnostic and using it
as the message portion of a Carbon diagnostic, generate the individual
pieces separately and pass them into the Carbon diagnostic
infrastructure.

* Clang's context lines are generated by running a custom "diagnostic
renderer" and tracking which lines it wants to print as context for a
given source location. When mapping from a C++ source location back to a
Carbon location, the Carbon `Loc` structure is now fully populated,
including filling in the context line and the column number.
* Clang's snippet is generated by running a custom diagnostic renderer
that is a cut-down version of the full text diagnostic renderer that
only prints a snippet. This is then attached to the Carbon diagnostic
manually as an override for the snippet we'd usually create.

We no longer repeat the file location twice on each diagnostic, and no
longer produce a bogus "in import" line for all locations coming from
clang that point arbitrarily to the first C++ import in the Carbon file.
The `[diagnostic kind]` marker is now displayed at the end of the
diagnostic message, not on a line of its own after the snippet.
v0.0.0-0.nightly.2025.08.01
2025-08-01 01:24:31 +00:00
Richard SmithandChandler Carruth b320ea77ec Improve source location in an import error. (#5887)
When attempting to import a definition of a class with virtual bases,
diagnose the point of use instead of the point of definition of the
class.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
v0.0.0-0.nightly.2025.07.31
2025-07-31 00:45:38 +00:00
Dana Jansens 7f96069b95 Add some tests for constraints depending on resolving other constraints (#5885)
Questions of what should be possible are raised in
https://github.com/carbon-language/carbon-lang/issues/5884

This provides the examples from the issue as test cases.
2025-07-31 00:14:31 +00:00
Richard Smith ae16014df8 Don't import a C++ class definition until the class is required to be complete. (#5865)
When importing a class definition, ask Clang to complete it first. This
causes class template specializations to get instantiated as needed when
the type-checking of Carbon requires a C++ class to be complete. It also
allows Clang to implement things like modules-aware definition
visibility checking.

Don't reject importing a class with a virtual base if it's never
required to be complete. Instead, defer diagnosing until the definition
is required.

This also removes the recursion from `MapType`, as mapping a class type
no longer maps its definition.

In order to get diagnostics from instantiation failures, fix a bug that
caused any Clang diagnostics produced after the initial building of the
`ASTUnit` to get discarded. This exposed some duplicate diagnostic
issues in `ImportNameFromCpp` which are fixed here too.
2025-07-30 23:34:18 +00:00
14f51d70c2 Emit diagnostics produced by Clang after the ASTUnit is constructed. (#5876)
Previously we would drop these diagnostics; now periodically flush them
to Carbon's diagnostics emitter. We flush them at the end of checking,
and also immediately before changing the set of diagnostic annotation
scopes, so that Clang diagnostics get properly annotated.

This exposes some double diagnostics being produced in situations where
Clang's name lookup logic would produce a diagnostic and we also
produced one. For access control issues, use the Carbon diagnostic, in
order to properly handle protected access. For ambiguity issues, use the
Clang diagnostic that produces helpful notes.

Also fix rendering of note diagnostics produced by Clang, by attaching
them to the prior error / warning diagnostic.

---------

Co-authored-by: Boaz Brickner <brickner@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-07-30 21:01:12 +00:00
Jon Ross-PerkinsandDana Jansens 19a7fb08b7 Switch handling of errors in impls to not build a type structure (#5881)
Per discussion at
https://github.com/carbon-language/carbon-lang/pull/5875#issuecomment-3137288037,
a different approach to the same solution.

A key difference is that whereas #5875 would build a `TypeStructure`
containing `ConcreteType{error}`, this instead just returns nothing.
This means impls with errors can't be compared in the same way, though
I'm not sure how much impact that'll really have (I've added a test here
to show a case where it seemed interesting to see what effect it'd have,
and it seems to have none).

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-07-30 20:24:38 +00:00
Boaz Brickner a905f15bf9 Fix the tests for forward declared union pointer as return type by making the return type pointer _Nonnull (#5878)
Followup of #5773.
Part of #5772.
2025-07-30 20:20:30 +00:00
Jon Ross-Perkins 800e8fd55a Add braces for CARBON_KIND uses that lack them (#5882)
Also document why these are expected on `CARBON_KIND`. In
`kind_switch_test.cpp`, drop the `str` variable.

My recollection of the original discussion of `CARBON_KIND` is that it
should always have braces due to the risk of confusion for statement
interpretation, similar to a typical `if`/`else` but more subtle due to
the macro.

For example:

```
      case CARBON_KIND(int n):
        str << "int = " << n;
        return str.TakeStr();
```

is equivalent to:

```
      case CARBON_KIND(int n): {
          str << "int = " << n;
        }
        return str.TakeStr();
```

This happens to work in context because `str` isn't scoped, but a
trivial refactoring to move `RawStringOstream str;` the first statement
of the `case` would probably have non-obvious results. For example:

```
      case CARBON_KIND(int n):
        RawStringOstream str; // Valid name shadowing, destructed without use.
        str << "int = " << n; // Name lookup error on `n`.
        return str.TakeStr();
```
2025-07-30 18:56:39 +00:00
Jon Ross-Perkins 4c0979fc10 Fix crash when importing an invalid impl (#5875)
Dropping this in with basic.carbon as an aspirational way to encourage
more tests there.

This currently crashes because `CollectCandidateImplsForQuery` tries
building a type structure which cannot contain `ErrorInst`.
2025-07-30 17:43:40 +00:00
Boaz Brickner 6a3e222fb7 Don't ignore SemIR ranges in C++ interop tests (#5877)
The non failing tests already define ranges.
2025-07-30 17:17:37 +00:00
Richard Smith a6f5143f22 Fix diagnostic for access of protected/private base member. (#5874)
When importing the member, import the access level for the lookup
result, not the declared access of the member declaration.
2025-07-30 17:17:09 +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
Boaz Brickner f0cff612eb Add support for using C++ double type in imported function declarations (#5868)
Carbon only supports f64, so only double can be mapped.

https://github.com/carbon-language/carbon-lang/blob/30f0ddab71bda71f8789080962b1fe8a5938e327/toolchain/check/type.cpp#L54

C++ Interop Demo:

```c++
// hello_world.h

auto hello_world(double x) -> void;
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

auto hello_world(double x) -> void {
  printf("double: %f\n", x);
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.hello_world(0.25);
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ $ ./demo
double: 0.250000
```

Before this change:

```shell
$ bazel-bin/toolchain/carbon compile main.carbon
main.carbon:8:3: error: semantics TODO: `Unsupported: parameter type: double`
  Cpp.hello_world(0.25);
  ^~~~~~~~~~~~~~~
main.carbon:8:3: note: in `Cpp` name lookup for `hello_world`
  Cpp.hello_world(0.25);
  ^~~~~~~~~~~~~~~
```

Part of #5263.
2025-07-30 07:13:59 +00:00
Richard Smith ef475d8197 Import C++ class A final as Carbon final class. (#5866)
Also import unions as final classes, and abstract classes as `abstract
class`es.
v0.0.0-0.nightly.2025.07.30
2025-07-30 00:41:42 +00:00
Dana Jansens 6b83414ee8 Dedupe rewrite constraints without sorting (#5864)
Dedupe rewrite constraints by consuming them by their LHS from the map
of rewrite values, and dropping any LHS that we see more than once. This
essentially uses the map to track which LHS we have seen in place of
sorting the rewrite constraints by the LHS.
2025-07-29 21:34:18 +00:00
Jon Ross-Perkins 64c31a6b9f Adjust ordering of EXTRA-ARGS to allow tests to override includes (#5870) 2025-07-29 20:22:51 +00:00
Dana Jansens 3d6395b75a Remove outdated piece of comment on SubstInst (#5869)
The comment on `Subst` explains what is going on with the possible
return values now, and the return type is no longer bool.
2025-07-29 18:18:32 +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
Kazu Hirata 0bba03ce71 Migrate away from llvm::ArrayRef(std::nullopt_t) (#5867)
The upstream LLVM has deprecated ArrayRef(std::nullopt_t).  This CL
migrates away from that.
2025-07-29 15:31:11 +00:00
Richard Smith 63b441390c Avoid vector copies when building dependent declarations list. (#5862)
Plus a few cleanups for uses of clang APIs.
2025-07-29 14:55:43 +00:00
Boaz Brickner 30f0ddab71 Add support for importing access from C++ to Carbon (#5858)
Better access control with inheritance should come with better
inheritance support (actually importing inheritance).

C++ Interop Demo:

```c++
// hello_world.h

class HelloWorld {
 public:
  static auto Pub() -> void;

 protected:
  static auto Pro() -> void;

 private:
  static auto Pri() -> void;
};
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

auto HelloWorld::Pub() -> void { printf("Public!\n"); }
auto HelloWorld::Pro() -> void { printf("Protected!\n"); }
auto HelloWorld::Pri() -> void { printf("Private!\n"); }
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.HelloWorld.Pub();
  Cpp.HelloWorld.Pro();
  Cpp.HelloWorld.Pri();
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
main.carbon:9:3: error: cannot access protected member `Pro` of type `Cpp.HelloWorld`
  Cpp.HelloWorld.Pro();
  ^~~~~~~~~~~~~~~~~~
main.carbon: note: declared here

main.carbon:10:3: error: cannot access private member `Pri` of type `Cpp.HelloWorld`
  Cpp.HelloWorld.Pri();
  ^~~~~~~~~~~~~~~~~~
main.carbon: note: declared here
```

Before this change (no access checks):
```shell
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
Public!
Protected!
Private!
```

Part of #5859.
2025-07-29 08:25:15 +00:00
Boaz Brickner 6d6e0d0418 Add support for using C++ bool type in imported function declarations. (#5860)
C++ in

C++ Interop Demo:

```c++
// hello_world.h

auto hello_world(bool x) -> bool;
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

auto hello_world(bool x) -> bool {
  printf("bool: %d\n", x);
  return !x;
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  let x: bool = Cpp.hello_world(false);
  if (x) {
    return 0;
  } else {
    return 1;
  }
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
bool: 0
```

Before this change (bool is interpreted as a 1 bit integer):
```shell
$ bazel-bin/toolchain/carbon compile main.carbon
... CRASH! ...
clang/include/clang/AST/Type.h:952: const ExtQualsTypeCommonBase *clang::QualType::getCommonPtr() const: Assertion `!isNull() && "Cannot retrieve a NULL type pointer"' failed.
```

Part of #5263.
2025-07-29 06:56:45 +00:00
432ee89dda Semantic Identity and Order-Dependent Resolution for Rewrite Constraints (#5689)
In open discussion[1] we decided that "identical" rewrites would mean
that for a given LHS value, all RHS have the same value (after
evaluation), rather than requiring the RHS to all have the same
syntactic value. This means the following is valid, since the value of
`.Y` is known to be `()` while resolving the rewrite constraints of `T`.
So both rewrites of `.X` are resolved to `.X = ()`:
```
fn Identical(T:! I where .X = () and .X = .Y and .Y = ()) {}
```

The implementation of this clarification, along with test cases encoding
it, is done in https://github.com/carbon-language/carbon-lang/pull/5686.

Clarify this in the language design documents, and improve some other
clarity while we're there:
- The prose talks about a facet `T`, but the examples were using `A` as
its name. Change the facet to be `T`. This means changing the `.T`
associated constant (and `.U` and `.V`) to be `.X` (and `.Y` and `.Z`).
While doing this, use `I` for the interface name instead of `C`, which
we use more commonly for a class type name.
- Correct the comments in the cycle example that claim we find `.Y then
.Y* then .Y**`. In this example `.Y = .Z* and .Z = .Y*` which adds _two_
levels of pointers when evaluating `.Y`: `.Y => .Z* => (.Y*)* => .Y**`

[1]
https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.qti4vn50zwy

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
v0.0.0-0.nightly.2025.07.29
2025-07-29 02:01:45 +00:00
David BlaikieandDana Jansens 26ec78ec00 Ensure vtable entries for generics are attached constants (#5853)
Otherwise these end up as unattached constants (see the baseline test
changes) and can't be resolved by `GetConstantValueInSpecific` in
lowering or in further derived vtables.

If the class is non-generic, then it's fine for the vtable entry for
some function inherited from a generic base is represented as an
unattached constant, since the specific in that specific_function is
already fully resolved.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-07-28 21:06:57 +00:00
Richard Smith 5de47962b0 Support for importing C++ base classes. (#5856)
For now, provide no support for virtual base classes and only minimal
support for multiple inheritance.
2025-07-28 20:56:06 +00:00
Richard Smith 0d74162e2a Support C++ import for anonymous struct and union members. (#5855) 2025-07-28 20:26:24 +00:00
Dana JansensandJon Ross-Perkins 5dc299f58b Note we are using Clang 16+ in the contribution tools docs (#5861)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-07-28 18:25:04 +00:00
Chandler Carruth eeea9dc9e5 Make minor improvements to ErrorOr based on usage (#5857)
When using this with filesystem errors, a few issues came up that I'm
fixing here. They're small enough and near enough in code that it didn't
seem worth splitting part.

- It's nice to forward declare custom error types and an API using them
and then define both later. That doesn't work with `requires` but works
fine with `static_assert`, so go back to that pattern here. A test is
added that checks this pattern compiles.

- The `operator*` didn't support moving out of `ErrorOr`, which is
especially important when writing code that is happy with just
`CARBON_CHECK`-failing on any errors. For example, we have a lot of
filesystem code in tests that is made *much* more concise by just using
`*` on a function return and letting the built-in checking ensure no
errors were present. But when the value is move-only, this requires
special overloading. Add that and add a test with a move-only value.

- There wasn't an idiomatic way to do something like `operator*` for
`ErrorOr<Success, ...>`. This PR factors out the checking for `ok()`
into a `Check()` method that can be used to make code more readable that
is intentionally just verifying no error. Also makes the result of
`operator*` `[[nodiscard]]` to improve error messages and help void
accidental bugs.

- The `IsError` and `IsSuccess` test helpers required printable values
which isn't always realistic. Teach the printing logic to be conditional
on some indication of a printable value and gracefully fall back to a
generic string otherwise for testing output.

- The use of the `listener` in `IsError` and `IsSuccess` assumed a
non-null stream. Instead, streaming should go directly to the `listener`
as it is configured to only actually do the output when a stream is
installed. When a stream isn't installed, the previous code would crash
if the `MatchAndExplain` method ended up called without an 'interesting'
stream attached to the listener.

- When doing a `CARBON_CHECK` that there isn't an error, print the error
out as the check failure message. Without this, all the nice error
message work doesn't end up helping the debugging of test code that hits
these errors, etc.
2025-07-28 17:42:36 +00:00
Dana Jansens 13e2268783 Add a dump command in lldb for dumping from ids (#5824)
The command is:
```
dump <context> [<ID>|<TYPE><ID>|<TYPE> <ID>|-- <ID>]

TYPE can be "inst", "entity_name", etc.
```

This saves a lot of typing of `SemIR::MakeInstId()` in a debugger, and
allows copy-pasting ids from dump output, as they take the form
`inst33`, etc.
2025-07-28 17:14:37 +00:00
Richard Smith 36f0a73092 Initial support for interop with class/struct/union fields. (#5849)
Add a new type, `custom_layout_type`, representing a struct type whose
size, alignment, and field offsets can be manually controlled. Use this
as the object representation type for imported C++ class types (which
also includes struct and union types), allowing us to model C++ class
type layouts. In passing, also add support for incomplete C++ class
types, mapping them into incomplete Carbon class types.

Map C++ fields into Carbon field declarations, allowing direct access to
C++ fields from Carbon. So far, no support is added for base classes nor
anonymous struct or union declarations; those will be added in
subsequent PRs. Also, we don't map C++ access control into Carbon yet,
so all C++ fields are accessible regardless of their access control.

For now we still use a `struct_type` as the object representation for
empty C++ classes, in order to continue to support our existing tests
that convert `{}` to empty C++ class types. This is temporary and should
be removed once we support interop with C++ class initialization.
v0.0.0-0.nightly.2025.07.28 v0.0.0-0.nightly.2025.07.27 v0.0.0-0.nightly.2025.07.26
2025-07-25 21:09:24 +00:00
Jon Ross-Perkins ef748ab36d Factor out an impl declaration helper function (#5851)
In trying to have types implicitly define `impl Self as Destroy`, I'm
wanting to use standard impl declaration support. For example, this
should produce more consistent errors if someone writes code that would
conflict with the generated impl. I'm also concerned, with the
complexity involved, that I'd get something wrong if I tried to write a
divergent implementation.

I'm only factoring out the start of the declaration. Right now the
finishing portion seems much simpler and lower risk to duplicate; I may
also factor it out separately. But either way, I think `StartImplDecl`
here is high churn risk due to its size (`CheckConstraintIsInterface` I
also expect to be used).
2025-07-25 18:34:07 +00:00
Jon Ross-Perkins bcfaf1044e Remove location support from error (#5837)
Location support was probably there for explorer, which is deleted.
Remove support as a simplification.
2025-07-25 15:00:33 +00:00