Commit Graph
1468 Commits
Author SHA1 Message Date
Dana Jansens bbca8668ae Allow witnesses to come from a facet with partially identified type in the lookup target (#7260)
We allow impl lookup to use `Self` which is partially identified, but we
were only allowing this for the `Self` facet appearing in the impl
lookup query self. We should also allow it when `Self` appears in the
impl lookup query target facet type.

But demonstrate that `Self` appearing in the interface of an
ImplWitnessAccess (a compound member access) is not sufficient at this
time, as it does not put `Self` into the type structure.
2026-05-25 23:02:06 +00:00
Dana Jansens 58b135235c Use earlier C(.Self) impls ... and .Self impls ... constraints in a facet type (#7246)
The `.Self` needs to be canonicalized when recording the witness, since
it will be a FacetAccessType in the `impls` clause.

Todo tests are also added for `C impls Y(.Self)`. The `.Self` in the
interface specific breaks everything as we end up replacing the `.Self`
with `C` in later `C as Y(.Self)` lookups, which then does not find the
witness.

Pull all the witnesses from `impls` constraints so that we capture
witnesses coming from named constraints on different self types, as `C
impls N(.Self)` may give witnesses for `C` or for other self types.
2026-05-25 15:13:20 +00:00
Richard Smith 49024c8d83 Improve diagnostics and error recovery for invalid identifiers. (#7249)
If a keyword or a sized type literal (eg, `f2`) is used in a context
where we are confident that we are expecting an identifier -- either
before a `:` in a binding pattern or after a `.` in a member access or
designator -- then recover as if a raw identifier was used.

This appears to be a particular stumbling block for coding agents, so
seems worth paying special attention to.

Add a mechanism to the tokenized buffer to track additional tokens
synthesized for error recovery so that we can keep the lexed token
sequence immutable and still satisfy the invariants throughout the rest
of the toolchain for recovery tokens. Thanks to chandlerc for suggesting
this approach!
2026-05-22 23:53:19 +00:00
Christopher Di Bella 64e890c246 Extend CppRangeForIterate to support ADL begin/end (#7230)
`CppRangeForIterate` needs to support finding `begin()`/`end()` as a
pair of methods and as a pair of ADL-findable functions. This change
adds the ADL component, which lets us also diagnose types that don't
implement the interface.

Unlike methods, we apparently have support for overloads when using ADL.
2026-05-22 21:12:06 +00:00
Nicholas Bishop e6b1679552 Add support for field initializers (#7238)
In handle_let_and_var.cpp, field initializers are now handled like
regular `var` initializers, by calling `LocalPatternMatch`.

In pattern_match.cpp, `FieldDecl`s with initializers are handled by
storing a value in `SemIR::File::field_initializers()`. This is a new
map where the keys are `FieldDecl` `InstId`s and the map values are
`InstId`s representing the initializer value.

In convert.cpp, `ConvertStructToStructOrClass` now has a `get_default`
function parameter that callers can use to provide a field default.
`ConvertStructToClass` uses this to provide a default from field
initializers.
2026-05-22 02:48:07 +00:00
Richard Smith 862b1c91f8 Fix GetTokenText for raw identifiers. (#7250)
Include the `r#` in the spelling of the identifier.
2026-05-22 01:57:13 +00:00
Richard Smith 805b3eebce Fix crash if initializing Clang fails. (#7248)
Flush diagnostics before destroying Clang. If we see an `inline Cpp` and
`Cpp` initialization failed, recover by skipping the inline code rather
than CHECK-failing.
2026-05-21 21:21:50 +00:00
Richard Smith ad97b9e3a5 Basic support for use of C++ modules via interop. (#7241)
Create a multiplex source to pull information from both the AST reader
and from our custom source.

Assisted-by: Gemini via Antigravity
2026-05-21 00:21:54 +00:00
Richard Smith 05cc09daca Fix cross-package signature mismatches. (#7232)
Fixes link failures when referencing a symbol involving a fingerprint
from a different package.

Previously we included the `Namespace`'s `import_id` as part of its
fingerprint, which caused local and imported namespaces to get different
fingerprints. We now store the `import_id` on the `NameScope` instead of
on the `Namespace` inst to avoid this problem.

Also, when we reach a package-level `NameScopeId`, consistently
fingerprint it as a (package name, library name) pair. Previously the
fingerprinting depended on whether it was imported or not, as an
imported `NameScopeId` had a parent scope (the current package). We need
to include the library name here so that private entities with the same
name in different libraries have different fingerprints.
2026-05-21 00:02:29 +00:00
Richard Smith 1231098c14 Fix crash in indirect template instantiation. (#7240)
Provide a source location to the member expression used when a thunk
calls a member function. This ends up being used as the point of
instantiation when the return type triggers a template instantiation;
the absence of this location previously caused assertion failures within
clang.

Assisted-by: Gemini via Antigravity
2026-05-20 23:18:15 +00:00
Richard Smith f31c553e65 Add a failing test for Clang modules support. (#7233)
Rearrange the file_test infrastructure so that we can customize the
mapping of file names to command line arguments. Map `module.modulemap`
files to corresponding Clang driver flags. In passing, also clean up the
interface for specifying custom argument replacements so that we don't
build a string map for each file we process, and stop using
`SmallVector::insert`.

Assisted-by: Gemini via Antigravity
2026-05-20 20:26:36 +00:00
Richard Smith ce080b3549 Support unqualified lookup into extended interfaces from classes and impls (#7217)
When a class extends an interface, referring to a member name of the
interface as an unqualified name should refer to the class's
corresponding associated entity value, not to the associated entity
itself. Similarly, in an `impl`, unqualified names of associated
entities should refer to the `impl`'s corresponding value for that
entity.

To support this, we treat `impl`s as `extend`ing their implemented facet
type, and we make lookups into an extended facet type use the `Self`
type of the extending `impl` or `class` if lookup finds an associated
entity. We already did the latter if the extending entity was an
interface; this extends the existing support for these other cases.
2026-05-19 18:01:54 +00:00
Richard Smith 9c277fd820 Add missing library line to test. (#7227) 2026-05-19 03:05:31 +00:00
Richard Smith b87f848db4 Fix passing mode computation for methods. (#7225)
We were incorrectly computing the index of the Clang implicit conversion
corresponding to method arguments. This led to wrong code and a crash in
lowering due to a calling convention mismatch.

Fixes #7224.

Assisted-by: Gemini via Antigravity
2026-05-18 20:30:23 +00:00
Nicholas Bishop 773ecdfac6 Implement static var class fields (#7215)
This adds the `static` token to the lexer and parses it as a modifier.

In check, `FullPatternStack::Kind::FieldDecl` is now used for both
static and non-static vars. Static vars get treated basically the same
as `NameBindingDecl`s.

Global initialization is used for static var initializers. To make the
necessary stack information available to `pattern_match.cpp`, the
`full_pattern_stack` and `decl_introducer_state_stack` are now popped
later in `handle_let_and_var.cpp`.

In lowering, each class's body is checked for `VarStorage` insts and
lowered the same as global vars.
2026-05-18 20:09:17 +00:00
josh11bandJosh L 832d46f01b Update LLVM (#7221)
Assisted-by: Google Antigravity

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2026-05-18 17:06:58 +00:00
David BlaikieandRichard Smith 843323b864 Export virtual functions when exporting a class definition (#7210)
This allows Clang to correctly generate the vtable for the exported
class.

There's still something wrong with new virtual functions in the Carbon
type (left a TODO) - I thought it might be related to not flagging
the CXXMethodDecl as virtual, but my initial experiments don't seem to
back that up, so I'll look into it further separately.

There's also a test regression due to an virtual (well, abstract
specifically, but I think it'd happen with a virtual one too) function
in an abstract class taking `self` by value being rejected since
the abstract class can't be instantiated. Not sure if this is a correct
change - the test's behavior could be preserved by using `ref self`
instnead of `self` in this function. Is that reasonable/expected? Should
we not require a type to be complete when passing by value if we can
compute the value representation without such completeness?

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-05-15 23:53:12 +00:00
Dana Jansens ed1a949b47 Resolve nested ImplWitnessAccesses in rewrite constraints (#7213)
We were assuming that a nested access meant that we'd resolve the outer
one, then the inner one. But it may be that we can just resolve the
entire nested access together. Previously if we encountered this, it led
to a CHECK failure. Now we correctly resolve it.
2026-05-15 20:31:28 +00:00
Dana Jansens 42a4dba9fd Makes impls constraints available to use in later constraints within a facet type (#7209)
If a facet type contains `.X impls Y` then later references to `.X`
should know that it impls `Y`. This is done through a stack on the
context like for rewrites, where impl lookup can find constraints from
the current `where` expression being checked.

Similarly, if a facet type contains `.X impls (Y where .Z = T)`, then
`.X.(Y.Z) = T` should be available to later constraints in the facet
type for early application of rewrite rules. We add these rewrites to
the rewrite stack when handling the `impls` constraint
2026-05-15 18:53:51 +00:00
Dana Jansens 835a61c385 Gracefully handle a concrete ImplWitnessAccess in the type structure (#7214)
While this can only happen when some other error is taking place, we
should handle it gracefully and report a concrete (but unmatchable)
value in the type structure instead of CHECK-failing.
2026-05-15 14:53:51 +00:00
Richard Smith dd47e41da6 Fix calls to functions with const T&& parameters. (#7208)
This also fixes passing a value expression to a forwarding reference,
since we currently deduce a `const T&&` parameter in that case.

We were accidentally looking at the type of the thunk parameter (which
is never an rvalue reference) rather than the type of the callee
parameter.
2026-05-14 20:22:32 +00:00
Dana Jansens 417531f484 Use early rewrites in compound member access (#7207)
We replace the non-canonical ImplWitnessAccess instruction with an
ImplWitnessAccessSubstituted instruction containing the RHS of a prior
rewrite constraint in the same facet type when possible, in order to
access the value of the prior constraint. We were doing this only in the
designator access path though, not in the compound member access. Join
these two code paths when they construct the ImplWitnessAccess, and
perform the early access there for both.
2026-05-14 16:37:50 +00:00
Richard Smith c9d8b59bbd Handle "gaps" in C++ vtables. (#7206)
Not every entry in a C++ vtable corresponds to a function that we want
to import. For the holes, leave a `SemIR::InstId::None` in the vtable.
Also mark vtables that extend a C++ vtable as being non-Carbon-native so
we don't try to lower them (and crash on the `None` entries).

In particular, we leave holes for destructors, since we don't have
destructor declarations on the Carbon side that need to override them.
2026-05-14 00:38:24 +00:00
Nicholas Bishop bd918fb33b Parse vars in classes the same as vars in other locations (#7188)
Class vars are still restricted to simple `name: type` bindings, not
full patterns. This is now handled in the check phase instead of during
parsing.

This is in preparation for supporting `static var`.
2026-05-13 21:22:46 +00:00
Dana Jansens 5706601096 Replace .Self in the self type of T(.Self) impls NamedConstraint when identifying a facet type (#7204)
Given this example function:

```carbon
fn F(T:! Z where .Self imps Y(.Self) and E(.Self) impls X(.Self)) {
  T as Y(T);
  E(T) as X(T);
}
```

When we identify the facet type of `T`, we replace `.Self` with `T`.
However in the initial loop, the self _is_ `T` so we don't want to
substitute `.Self` instances inside `T` with itself, as that creates
cycles.

When we see a `type impls...` constraint such as `E(.Self)` we now have
a different self-type so we can, and want to, substitute the `.Self` in
it with `T`. This was already being done, unless the RHS of the `impls`
was a named constraint. In that case we forgot that we were in a `type
impls...` constraint, and avoided replacing `.Self`. Now the algorithm
remembers and correctly replaces `.Self` for `type impls named
constraint` constraints in a facet type.
2026-05-13 18:49:02 +00:00
Richard Smith 917856aff7 Export Carbon classes as base / final / abstract. (#7191)
* For Carbon `base class C`, export as a regular C++ class.
* For Carbon `class C`, export with the C++ `final` keyword attribute.
* For Carbon `abstract C`, mark the destructor as pure virtual in cases
where no member function is abstract, or emit an error if the destructor
is not virtual.

To support the final point, mark the destructor of an exported class as
virtual if it overrides a virtual destructor from the base class.

In passing, fix a crash exporting fields if the class has an invalid
base type.
2026-05-13 17:48:55 +00:00
Richard Smith c33fb9fc48 Support signature mismatch between virtual fn and override fn. (#7198)
For now, hide `override fn`s from name lookup, so that the base class
version is always used, as the derived-class version does not have its
own vptr entry and so would not do the right thing if a further-derived
class adds a new override. This is implemented via a new access kind of
`Hidden`.

When checking the overriding function, pass in the expected `Self` type
and check the `self` parameter against that; the signature that we
generate for the thunk in the derived class is the base class signature
with the `self` parameter's type changed to the derived class.

When we generate a thunk for a virtual function, the thunk is assigned a
`virtual_index`, and the virtual function itself is not. When the thunk
makes a direct call to the virtual function, recognize this situation by
checking for a `virtual_index`, and perform a non-virtual call if there
isn't one.

Assisted-by: Gemini via Antigravity
2026-05-13 17:40:45 +00:00
Dana Jansens 0b47efa57a Don't re-require complete types for extended scopes (#7194)
When an outer type defines an `extend` relationship to an inner type, we
require that inner type to be complete so that we can know that name
lookup can search both scopes as soon as the outer type is complete.

When doing name lookup, we require the type in which we are looking to
be complete. Then, we recursively add extended scopes, but then also
require each of them to be complete again, which inserts
RequireCompleteType instructions into the block doing lookup.

While these new instructions may differ in terms of their specifics,
they are redundant since we already required the type to be complete,
and specifics can not change the completeness of a type. They are also
problematic because a named constraint or interface can extend a scope
with a symbolic specific, by using `Self` as an argument. This inserts a
symbolic instruction into the block doing name lookup, even though that
block may not be generic.
2026-05-13 17:16:02 +00:00
Dana JansensandRichard Smith 6326bbdbe1 Resolve cycles in .Self replacement in nested designators (#7183)
A nested designator like `.(X.X1).(Y.Y1)` results in nested
ImplWitnessAccess instructions, which can produce cycles in the
toolchain easily when replacing `.Self`.

First, when constructing a facet type like `V:! Z where .Z1 impls (Y
where .Y1 = U)` we substitute replace `.Self` in the nested facet type,
and in this case we replace `.Self` with `.Z1` which contains a `.Self`
of its own. This was coming from us being lazy about replacing `.Self`
in an `impl as` declaration, such as `impl C as Z where .Z1 = .Self`.
The self type is known there, so we can more eagerly replace `.Self` as
we do in a `require impls` declaration. Then the replacement for `.Self`
never comes with a `.Self` that needs to also be replaced. Any resulting
`.Self` would always be the top-level one.

Second, when evaluating ImplWitnessAccess, we were replacing .Self in
the LHS of rewrite constraints, but the `.Self` may itself have a type
that contains rewrite constraints. If one of those rewrite constraints
has nested ImplWitnessAccess instructions, we evaluate the new
ImplWitnessAccess, which again finds rewrite constraints to replace
`.Self` in, and we repeat forever. For this one we just stop replacing
.Self in the LHS of rewrite constraints. Since they are always against
.Self, we can always look in the access facet's type for a value.

While fixing ImplWitness access, also correct the lookup to search
through the types of nested ImplWitnessAccess instructions to find a
rewrite value, since it may find it at any level up to the eventual
`.Self`.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-05-13 16:11:20 +00:00
Richard Smith 798b177fc0 Tidy up virtual method tests. (#7196)
Move the tests from `class/` to `class/method` and add SemIR dump
ranges.
2026-05-13 13:58:14 +00:00
Richard Smith 71ba07239f Support pass-by-move when calling a C++ function taking by value. (#7135)
Previously, we picked a single Carbon parameter pattern for each C++
parameter pattern. This doesn't work well in cases where the Carbon
semantics and the C++ semantics are not perfectly aligned. In
particular, when a parameter is passed by value in C++, that might mean
either pass-by-move (which in Carbon would best be modeled by a `var`
pattern, as no other form of parameter would perform a move) or
pass-by-copy (which in Carbon would best be modeled by a value
parameter, as a `var` parameter would force an extra copy).

After this change, we compute a passing mode for each parameter based on
the implicit conversion sequence from the argument to the parameter as
determined by C++ overload resolution, and use that to determine the
Carbon pattern corresponding to each C++ parameter. This results in
potentially generating multiple different thunks for the same C++
function if it's called in different ways, but we already did that to
handle default arguments and list-initialization. The passing modes are
included in the thunk mangling.

Add a new value store for clang decl signatures, which capture the
information about parameter passing mode as well as the other existing
information about different ways that a C++ function might be imported
to Carbon.

Most of the rules for computing passing modes are the same as before:
const references use pass by value, non-const lvalue references use
pass-by-ref, non-const rvalue references use pass-by-var. But for C++
non-reference parameters, pick between pass-by-value and pass-by-var
based on whether the implicit conversion sequence was effectively
performing a copy. Prefer pass-by-value if either would work and they'd
do the same thing. We still use pass-by-value for const references, even
when the argument is an lvalue and we could pass a reference; we may
want to change this in future.

For virtual functions, we try to pick a worst-case passing mode, as we
can only pick a single signature for what goes in the vtable. Calls to
virtual functions will still use a thunk to C++, allowing variance in
the calling convention at call sites. We don't allow variance in the
overriders as we don't implement support for thunks for virtual
functions yet. We currently use pass-by-value for const reference
parameters here, but that should probably change at some point.

Assisted-by: Gemini via Antigravity
2026-05-13 01:44:07 +00:00
Dana Jansens 71eed5b04a Add tests that demonstrate missing diagnostics for impl as a named constraint (#7195)
Any non-extend require decls must be satisfied when the impl definition
starts, but they are not checked. We only check for require decls in the
target interface being impld.
2026-05-12 22:15:09 +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 dd7cfdb149 Relax alias restrictions. (#7190)
Implement the alias rules from proposal #5389, wherein an alias is
permitted so long as the target has a constant value. While that
proposal is not yet accepted, this seems like a reasonable basis for
further iteration, and will be useful for the examples we're currently
pursuing.
2026-05-12 17:22:44 +00:00
Dana Jansens d4063cad65 Remove completed TODO in import test (#7193)
The generic args are now in the stringified name
2026-05-12 17:02:57 +00:00
David Blaikie df8b25522e Import C++ vtables (#7174)
This correctly renders the vtable in SemIR, including allowing overrides
in
Carbon-derived-from-C++ classes.

It doesn't work in lowering because clang walks the methods of the
CXXRecordDecl - and we currently don't export anything into the
CXXRecordDecl's methods (we do export the fields) - so that's next.

This also doesn't teach Clang to affirmatively emit the vtable
regardless of the types use in C++ code - or to have Carbon use the
vtable in an object's initialization.
2026-05-11 17:33:08 +00:00
David Blaikie 0f5de499d6 Roundtrip (export/reimport) class declarations (#7182)
Roundtrip (export/reimport) class declarations

The remapping was previously implemented using name_scopes, which aren't
created for class declarations, only definitions - causing the reimport
to import a fresh copy of the type that mismatched with the original (as
seen in the test baseline).

By changing the mapping to use the reverse part of the clang_decls
mapping this should generalize better (& we probably should further
migrate to that mapping). Though it did trip over some issue with
exactly which instruction is used as the key in the clang_decls map -
this change moves towards standardizing on the first decl id of the
class as its map key.
2026-05-11 16:35:47 +00:00
Dana Jansens eea1e58376 Correctly handle ImplWitnessAccess in impl lookup (#7181)
We were treating ImplWitnessAccess as a concrete type, but that is
incorrect if its accessing a symbolic type value. This results in
concrete impl lookup queries failing to match a generic impl that is
built with a symbolic ImplWitnessAccess in its type structure, when the
query does not have the equivalent ImplWitnessAccess in its own type
structure.

We need to look in the top level facet being accessed through
ImplWitnessAccess for witnesses, such as in `T:! Z where .Z1 impls Y`
where `T` provides the witness for `T.Z1 as Y`. But we also need to look
in the facet type of the ImplWitnessAccess for witnesses, such as in
`T:! Z` for `interface Z { let Z1:! Y }`, where `T.Z1` provides the
witness for `T.Z1 as Y`.

To support that we give TypeIterator an iteration step for
ImplWitnessAccess before recursing into it, like we do for FacetValue.

While doing this, we make TypeIterator more recursive, by making less
special casing around the step from one inst into the next. Instead of
eagerly finding a SymbolicType, we consistently recurse back into the
big switch statement and have it decide the next iteration step. This
allows it to recurse into instructions like ImplWitnessAccess and
FacetValue in a consistent manner.
2026-05-11 14:17:18 +00:00
Christopher Di Bella 219d1cdee1 Teach comparison interfaces about C++ operators (#7163) 2026-05-10 21:54:50 +00:00
Dana Jansens a19a6ab6d1 Search all facets in the impl lookup query for witnesses (#7178)
This enables searching facets like `T:! Z where .Z1 impls Y` for queries
like `T.Z1 as Y`, etc.

Any facet in the query self or the query target type may provide a
witness for the requirements of the impl lookup, so search through them
all.

We accept partially identified facet types in the query self, since
`Self` can be used inside a named constraint before it's fully
identified. But any use of `Self` being converted would put it in the
query self, not the query target, which would be some generic parameter
facet type that a type involving `Self` is being converted to.

TypeIterator is expanded to support this use case, by giving it the
ability to walk through FacetType's extend/impls constraints. We return
the facet values that we find in the iterator instead of a type id. And
we also include FacetValue instructions as an iterator step for clients
that want them, while also recursing through them.
2026-05-07 22:33:47 +00:00
Richard Smith bc06f6c5ec Mangle the signature decl when mangling a thunk. (#7177)
Fixes mangling collisions when two thunks with the same name (eg, `Op`)
are created in the same context, which in turn would lead to LLVM
verifier failures and miscompiles.

To support this, add a new value store to track a little more
information about thunks beyond what's in the `Function`.
2026-05-07 21:58:29 +00:00
Geoff Romer 031ec0a140 Implement BundleStore (#7173)
See
[here](https://docs.google.com/document/d/1eWW8MTko3PIqxZ32-GhsdaRSYqoDicxMB1VeessMTOg/edit?tab=t.0#heading=h.igl2myxbaf58)
for the background and design. The only usage of `BundleStore` in this
PR is artificial, but I'm working on a PR involving an action inst with
3 arguments, which requires something like `BundleStore`.
2026-05-07 19:42:23 +00:00
Dana Jansens 6776e2b804 Detect impl redecls in non-declarative scopes (#7170)
Avoid crashing on the fact that block scopes have no related InstId. So
we can't push the InstId of the current scope in the ImplIntroducer
node, as it can be None. Instead we have to find the parent InstId when
we're building the ImplDecl, because the ImplDecl has a node at the top
of the scope stack for the DeclNameStack.

Impls are allowed in sequential (non-declarative) scopes (functions,
blocks), but [redeclarations are not
allowed](https://github.com/carbon-language/carbon-lang/blob/db24042fe56d22275aa801696e2f8f5c4171e35b/proposals/p3763.md?plain=1#L279).
We now diagnose these redecls as invalid.
2026-05-07 13:44:40 +00:00
Dana Jansens db24042fe5 Diagnose overlapping impls in the api/impl files of the same library (#7164)
An `impl` decl in an impl file can refer only to things defined in the
api file, without the orphan rule rejecting it. If they are in different
scopes (such as one being in a class and one not), then they are treated
as separate `impl` decls. But if they have the same type structure, then
they fully overlap which is an error unless they are in a match_first
block.

This catches the overlap when two `impl` decls are in the same library
but are split between the api and the impl file of the library.
Previously we only diagnosed if they were in the same _file_ but now we
diagnose if they are in the same _library_.
2026-05-06 14:17:54 +00:00
Richard Smith 341901e337 Fix crash if an inst in a pending block needs a cleanup. (#7166)
Insert the cleanup if and when the pending block is inserted, not
eagerly. And if the pending block is inserted by overwriting an existing
instruction, create a cleanup for that instruction rather than for the
instruction in the pending block that we are discarding.

Assisted-by: Gemini via Antigravity
2026-05-04 21:50:13 +00:00
Dana Jansens f8dd4d85bf Do not treat impls in different scopes as redeclarations (#7161)
An impl in a different scope, with the same parameters, will overlap and
get diagnosed for that later by the [prioritization
rule](https://docs.carbon-lang.dev/docs/design/generics/details.html#prioritization-rule),
if they are not in a match_first block. But they are not considered as
redeclarations.

See [proposal
p5366](https://github.com/carbon-language/carbon-lang/blob/62b94f79322039acc3fc8e175896a64a32df470e/proposals/p5366.md)
for the rule.
2026-05-04 19:11:51 +00:00
Dana Jansens 4d1a61de29 Don't consider designators in a nested facet type as constraining the current type (#7139)
The design says:
> We don’t allow a where constraint unless it applies a restriction to
the current type. This means referring to some
[designator](https://docs.carbon-lang.dev/docs/design/generics/details.html#kinds-of-where-constraints),
like .MemberName, or
[.Self](https://docs.carbon-lang.dev/docs/design/generics/details.html#recursive-constraints).
--
https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator

A nested facet type in a constraint does not constrain the current type,
with the exception of the LHS of a nested `where` in an impls
constraint. Diagnose this appropriately by not recursing into unrelated
parts of nested facet types to look for designators.

Before this change, this facet type is accepted:
```carbon
fn F(unused T:! Z where C impls (Y where .Y1 = .Y2)) {}
```

But then no calls to `F` work, since the `.Y1` and `.Y2` designators are
never resolved to anything from the caller, as they do not depend on `T`
in any way.
2026-05-04 16:42:06 +00:00
Dana Jansens 88931a4196 Give the .Self instruction a location (#7147)
This lets us stop eliding it in textual semir tests with dump ranges.
Previously it would always get elided, even though it was part of the
range being dumped, and was referred to by other instructions in the
dump range.

Since each `.Self` is unique (can change its type if not its value) in a
facet type, having each one distinct by location also aids
understanding.
2026-05-04 14:45:06 +00:00
Dana Jansens 46bb0fecd4 Properly diagnose ambiguous .Self in T impls X where... (#7132)
A `where` expression nested inside a `T impls X` constraint makes
`.Self` ambiguous on the right-hand side of the `where` if `T` is
anything other than `.Self`. After the `where`, the value of a `.Self`
could be `T` or could be the value of `.Self` before the `impls`
constraint: the so-called top-level value of `.Self`.

Implicit use of `.Self` in designators is always allowed, and they are
bound (and replaced by a reference) to the inner-most possible value of
`.Self`. On the right-hand side of the nested `where` above, they have
the value `T as X`.

`.Self impls ...` is also always allowed, since it acts more as a
keyword here, and it always refers to the inner-most possible value of
`.Self`.

Any other explicit use of `.Self` is diagnosed when ambiguous, in any
kind of constraint. This is done in the handling of `WhereExpr` since it
has enough context to allow `.Self impls` (which is an explicit use)
while disallowing other explicit uses. And because it has non-canonical
instructions to work with, so it is able to diagnose errors with precise
locations.

Since `.Self` is no longer going to be marked with depth modifiers, the
eval of `WhereExpr` does not need an input facet value instruction
representing `.Self` to compare with, as they are now going to all be
equivalent. So revert it back to just looking for the `PeriodSelf` name
id, through a shared helper being introduced as `IsPeriodSelf`. And drop
the period self InstId from the `WhereExpr` instruction. This causes
most of the formatted SemIR changes.

Move helpers for working with and replacing `.Self` to their own file,
out of the `facet_type.h` header/cpp files. These are working with
`.Self` facet values more than facet types, though `.Self` is a name
that only exists inside the scope of a facet type.
2026-05-01 21:22:32 +00:00
Nicholas Bishop 2445ad9703 Prevent ref self methods from being called from C++ with an rvalue (#7130)
If the Carbon method takes a `ref self`, give the C++ thunk an lvalue
ref-qualifier.
2026-04-30 00:50:28 +00:00