Commit Graph
1573 Commits
Author SHA1 Message Date
David Blaikie 53ea894d0d Add unit tagging to ClangDeclId (#6274) 2025-10-24 20:18:18 +00:00
David Blaikie 184a39ed8b Add unit tagging to ClangSourceLocId (#6273) 2025-10-24 17:09:46 +00:00
Dana Jansens 26381f6eaf Handle parsing of require...impls declarations (#6255)
Check is not implemented yet, but some tests are added.
2025-10-23 18:34:52 +00:00
David Blaikieandjosh11b 4f1f0fc7c2 Add unit tagging to ImportIRId (#6265)
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-10-23 17:34:35 +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
Geoff Romer 09710d102f Separate binding insts for refs and values (#6235)
This resolves a TODO in `expr_info.cpp` by using the inst kind rather
than the bound value to track the binding's category.

Since we're churning all the `bind_name` insts in testdata anyway, I'm
also taking this opportunity to align the inst naming with the design's
terminology, by calling these insts "bindings" (this aspect of the PR is
dependent on #6231 resolving an ambiguity in that terminology). For
consistency we'll need to rename several other insts as well (see the
TODO on `RefBinding`); I'm deferring that to a separate PR to minimize
the review load, but I think those name changes are in-scope for this
review.
2025-10-23 01:46:24 +00:00
David Blaikie d4a8cb96de Correct format string specifier to match number of parameters (#6266) 2025-10-23 00:30:31 +00:00
David Blaikie b02c6a8db4 Add unit tagging to SymbolicConstantId (#6262) 2025-10-22 23:39:00 +00:00
David Blaikie 79541ee50c Add unit tagging to StructTypeFieldId (#6260)
Based on #6259
2025-10-22 22:22:53 +00:00
David Blaikie 2dd9e7f0d7 Add unit tagging to CppGlobalVarId (#6263) 2025-10-22 21:44:18 +00:00
David BlaikieandDana Jansens 79dd1e362c Add unit tagging to InstBlockId (#6259)
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-10-22 21:02:48 +00:00
Dana Jansens 22580a47d3 Initial support for empty named constraints (#6245)
Type check named constraint decls and definitions. We don't correctly
error if you put a `fn` inside them. There is no support for `require`
or `alias` yet, so there's nothing useful you can do with them yet.

We have attempted to share code between `interface` and `constraint` as
they are quite similar. First by splitting out some of
handle_interface.cpp to a separate file. Second by sharing some code
paths when you want a facet type from either one, as they both turn into
a facet type.
2025-10-22 18:26:32 +00:00
David Blaikie a340808062 Add unit tagging to FacetTypeId (#6256) 2025-10-22 18:21:09 +00:00
David Blaikie c2ddf50892 Add unit tagging to EntityNameId (#6257) 2025-10-22 16:30:12 +00:00
Geoff Romer 39503a5561 Disambiguate "value binding" (#6231)
This proposal removes the definition of the term "value binding" as a
primitive
category conversion from reference to value, replacing it with the term
"value
acquisition". The other meaning of "value binding", a binding declared
by a
value binding pattern, is unchanged.
2025-10-22 00:38:55 +00:00
Richard Smithandjosh11b b3c25ecfa2 Allow implicit conversion to a value expression to remove const. (#6253)
`const` doesn't mean much on the type of a value expression; it's valid
to remove it because we can't perform modifications to a const value
regardless.

We already allowed most of this, but only as part of adapter conversion
rather than in general, and we didn't previously allow it when the
source of the conversion was a reference expression.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-10-21 22:16:58 +00:00
David Blaikie 3ea16b8313 Add unit tagging to NameScopeId (#6258) 2025-10-21 20:06:09 +00:00
Boaz Brickner 840562feb3 C++ Interop: Fix access calculation to handle private member of base classes correctly (#6238)
Always take into account both the lookup access specifier and the
declaration. When set, lookup access specifier takes precedence. When
not set, we have two use cases:
1. This is not a record member, so no access is specified at all. Treat
this as public.
2. This is a record member of a base class. Treat this as private.
[Reference](https://github.com/llvm/llvm-project/blob/4b1d7827c07381610ad4fa7bd9d1a9659008b963/clang/include/clang/AST/DeclCXX.h#L1724).

Also, deduplicate access mapping between import and overload resolution.

Background:
https://github.com/carbon-language/carbon-lang/pull/6221#issuecomment-3407981790

Part of #5859.
2025-10-21 08:12:57 +00:00
David Blaikie 3d6810beb6 Add unit tagging to InterfaceId (#6243)
Based on #6241
2025-10-20 21:41:55 +00:00
David Blaikie 7663c38291 Add unit tagging to SpecificId (#6251) 2025-10-20 21:12:54 +00:00
David BlaikieandDana Jansens 0ed5d41a1b Avoid mismatched InterfaceId comparison between two files (#6241)
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-10-20 18:44:05 +00:00
Jon Ross-Perkins b1f734e1cd Switch EvalLookupSingleImplWitness from "concrete" to "final" terminology (#6246)
A `final impl` can have a symbolic witness, but that witness is still
final. Using "final" here per discussion on
[#generics-and-templates](https://discord.com/channels/655572317891461132/941071822756143115/1428851511672312120).

I'm also changing the variant a little because `concrete_witness` was
only called when `has_concrete_value` was true, so it can be more
careful about its contract. Having a more explicit `None` also
simplifies `has_value`. I think it doesn't change the overall cost much
past that.
2025-10-20 17:25:26 +00:00
David Blaikie 1df0d4566e Add unit tagging to GenericId (#6248) 2025-10-17 23:21:27 +00:00
Richard Smith 8cf4c4d10d [C++ interop] Pass top-level declarations to the code generator. (#6237)
This allows us to lower indirectly-referenced C++ functions and
variables.
2025-10-17 17:10:14 +00:00
Richard Smith 304d2056cc Map nullable C++ pointer types to Core.Optional(T*). (#6230) 2025-10-16 20:52:32 +00:00
Ivana Ivanovska 2a96b52780 Remove big float literals TODO (#6220)
A Carbon floating-point literal passed as a call argument to a C++
function is mapped to `double`. If the value is too large to fit in
`double`, an error is reported. This follows the C++ rules for assigning
types to floating-point literals, as discussed in the [interop
meeting](https://docs.google.com/document/d/1YlxEOJ0r-o19o19TCJbFl4Ln1U88yn_Vj23y1Hr5vTk/edit?tab=t.0#heading=h.9zzqn7n3o8lm)
and documented in this [design
doc](https://docs.google.com/document/d/18u8z9UEuGH73XzXlDynTgyNK76q1Efl8YYWbpM5LX7o/edit?tab=t.0#heading=h.6hkga1yq1f3o).

Added missing tests for this as well.

Part of #5915
2025-10-16 16:24:28 +00:00
Boaz Brickner 4e8810fa19 Add more extern "C" tests (#6232)
Add tests in `check`.
Add overload set tests in `lower`.

Part of #6233.
2025-10-16 16:07:02 +00:00
David Blaikie f64b08863a Dump all non-indexed ids as hex (#6228)
The indexed ids are kept in decimal since they won't get tagging because
their ordered-ness is significant to their usage, as I understand it.

Addressing
https://github.com/carbon-language/carbon-lang/pull/6215#discussion_r2430180953
feedback
2025-10-16 01:04:51 +00:00
Jon Ross-Perkins c7646b74c1 Reduce use of function return type deduction (#6227)
Trying to reduce use where we could have explicit return types because
it should make it a bit quicker to understand what's returned. We've
generally agreed to it for [local
variables](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md#naming-variable-types-and-the-use-of-auto),
but even the [google style
guide](https://google.github.io/styleguide/cppguide.html#Type_deduction)
discourages it and says "Do not use decltype(auto) if a simpler option
will work; because it's a fairly obscure feature, it has a high cost in
code clarity."

(which to one point of discussion, feels like maybe we don't need a
specific rule about this -- the remaining couple uses I see feel like
they're harder to avoid)
2025-10-15 23:02:51 +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
Boaz Brickner 45017bf65d Add tests for calling a base function without qualifications (#6221)
This demonstrates that we don't diagnose when trying to call a base
class private function when we refer to the function from a derived
class without qualifications.

Demo: https://godbolt.org/z/vbWs1P915
2025-10-15 20:14:08 +00:00
David Blaikie a486c12bd6 Add unit tagging to SpecificInterfaceId (#6215) 2025-10-15 18:09:29 +00:00
Boaz Brickner c2d21429f2 Avoid changing visiblity when inheriting in CodeContextRenderer (#6219)
This fixes clang-tidy `override-with-different-visibility`.
2025-10-15 15:50:47 +00:00
Boaz Brickner ffefa7711c Move the mapping from entity name to an imported C++ global variable declaration outside of EntityName (#6211)
This would save space for every `EntityName` that is not an imported C++
global variable.
C++ global variables include static data members.
Created `CppGlobalVarId`, `CppGlobalVarKey` and `CppGlobalVar` to allow
having `CanonicalValueStore` that maps `EntityNameId` (which is in
`CppGlobalVarKey` and `CppGlobalVar`) to `ClangDeclId` (which is also in
`CppGlobalVar`).
This is similar to `ClangDeclId`, `ClangDeclKey` and `ClangDecl` .
2025-10-15 13:33:32 +00:00
David Blaikie 2d1de16293 Add unit tagging to ImplId (#6214) 2025-10-15 01:41:37 +00:00
Jon Ross-Perkins 9010249936 Remove reallocation assumptions from generic code (#6217)
Rather than assume reallocations can occur, we've switched to providing
stable references, so simplify related code.

Only removing the comment in `BuildGeneric`, no refactoring, because I
don't feel a refactoring would be a significant improvement.
2025-10-14 21:53:48 +00:00
David Blaikie 1a9826bc29 Add unit tagging to FunctionId (#6213) 2025-10-14 20:52:56 +00:00
David Blaikie d0d2f18f37 Add unit tagging to CppOverloadSetId (#6212)
No update to lldbinit.py because we don't currently have
dumping/debugging support for CppOverloadSetId anyway.
2025-10-14 18:29:40 +00:00
Boaz Brickner a0ef7e7112 C++ Interop: Add test coverage for access control of static/instance data/function members (#6199)
This demonstrates two issues:
1. It seems like we wrongly treat private static data members the same
way we treat protected and allow access to them from within derived
classes member functions.
2. Calling instance member functions of a base C++ class using a derived
class as self (no implicit upcast) is not yet supported. This isn't
related to access control, but prevents us from testing some access
control use cases.

Part of #5859.
2025-10-14 17:56:24 +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
David Blaikie 60b2b7f8c1 Add unit tagging to ClassId (#6195) 2025-10-11 05:36:18 +00:00
Richard Smith e26b6a35c2 Allow instance binding on tuple-valued expressions. (#6203)
Don't expect the right-hand operand of `a.(b)` to always be a tuple
index when `a` is of tuple type; it could also be a method name.

Fixes #6162.
2025-10-11 04:54:13 +00:00
Boaz Brickner 1ac1d11063 C++ Interop: Support reference types in fields and globals (#6187)
Implemented by generalizing the reference type support for parameters
and return values to other use cases.
The changes to the `method.carbon` test are due to to supporting the
reference types but not supporting the necessary conversions.

C++ Interop Demo:

```c++
// global.h

struct C {
  int member = 0;
  int& member_ref = member;
};

extern C& global;
```

```c++
// global.cpp

#include "global.h"

static C static_c;

C& global= static_c;
```

```carbon
// main.carbon

library "Main";

import Core library "io";

import Cpp library "global.h";

fn Run() -> i32 {
  Core.Print(Cpp.global->member);
  ++(*Cpp.global->member_ref);
  Core.Print(Cpp.global->member);
  ++(*Cpp.global->member_ref);
  Core.Print(Cpp.global->member);
  return 0;
}
```

```shell
$ clang++ -stdlib=libc++ -c global.cpp
$ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link global.o main.o --output=demo
$ ./demo
0
1
2
```

**Without this change**:
```shell
main.carbon:10:14: error: semantics TODO: `Unsupported: var type: C &`
  Core.Print(Cpp.global->member);
             ^~~~~~~~~~
main.carbon:10:14: note: in `Cpp` name lookup for `global`
  Core.Print(Cpp.global->member);
             ^~~~~~~~~~
```

Part of #6006 and #6186.
2025-10-10 23:15:31 +00:00
Boaz Brickner 0365467872 Merge toolchain/check/testdata/interop/cpp/class/struct.carbon into class.carbon (#6198)
The tests are almost identical and test the same logic so basically
duplicated.
The extra coverage that was in `struct.carbon` is added to
`class.carbon`.
One basic test in `struct.carbon` was left just to make sure `struct` is
supported.

Part of #5150.
2025-10-10 22:37:25 +00:00
Boaz Brickner 46c5209f2f C++ Interop: Set location when creating a return pattern (#6185)
This requires changing `ReturnSlotPattern` and `OutParamPattern`
definitions to use untyped node id, so they can have any associated
node.

Follow up of #5197.
Part of #5064.
2025-10-10 15:32:14 +00:00
Boaz Brickner 9441c278df Avoid using clang::UnresolvedSetImpl (#6197)
Avoid relying on implementation details.
Also, use `DeclAccessPair::operator->` instead of `.getDecl()->`.
2025-10-10 15:29:53 +00:00
Dana Jansens 0679b779fb Return SymbolicBindingType separately in TypeIterator (#6193)
A SymbolicBindingType is going to only have EntityNameId as its field,
and we will use the ScopeStack to use that to find a facet. The
ScopeStack is a check/ thing, so this won't be possible in
SemIR::TypeIterator. And TypeStructure throws away the details for
symbolic types anyways. So this drops the TODO and returns the
EntityName from TypeIterator for any future user who would want it in
check/.
2025-10-10 12:37:37 +00:00
Boaz Brickner f713964db4 C++ Interop: Set location when creating param patterns (#6184)
Follow up of #5197.
Part of #5064.
2025-10-10 09:00:00 +00:00
Dana Jansens 3d592ebe59 Support member access into the type of (facet as type) expressions as being into the facet's type (#6190)
When we do member access `x.F` we attempt to look into the type of `x`
for `F`. If `x` is a facet, we look at its FacetType to find `F`. We
want `facet` and `facet as type` expressions to be generally treated as
equivalent, so we need to get at the "canonical facet value" of `x` in
order to look into its type. Add a new operation that allows us to
preserve the non-canonical `base_id` in the member access for
diagnostics if no conversion to a canonical facet value was needed.
2025-10-09 22:06:02 +00:00