Commit Graph
105 Commits
Author SHA1 Message Date
Jon Ross-Perkins 705c95d6e0 Drop fn destroy support (#6136)
`fn destroy` is being removed per decision on #6124. It seems like the
relevant decision will result in no more keyword-based function names,
so this is removing all related support.
2025-09-25 21:56:48 +00:00
Richard Smith e24ba02352 Fix lowering of thunks in generic impls (#5631)
Build a `SpecificConstant` (if needed) and `NameRef` instruction when
referencing the thunk target from a thunk. The former is necessary if
the impl is generic in order to call the right version of the thunk
target. This previously caused a crash in lowering.

Also add some more check testing for the interaction of thunks and
generics. This testing uncovered an unrelated bug with thunks for
generic interface functions for which I've added a TODO.
2025-06-10 20:54:58 +00:00
Jon Ross-Perkins 89a6818424 Move TokenOnly to LocIdForDiagnostics (#5590)
This reclaims a bit inside `LocId`. I'm hopeful we don't actually need
to store the token-only state.

Note I'm looking at this in the context of desugaring; I was thinking
about changing `ToImplicit` logic a little to push more towards
`GetCanonicalLocId`, and the "desugaring" TODO there. Removing
`ToTokenOnly` makes me feel a little more free to rename `ToImplicit`,
since it eliminates consistency as a question.
2025-06-03 01:14:54 +00:00
Dana JansensandJon Ross-Perkins 315e206ff1 Construct LocId from InstId directly (explicitly) instead of doing lookups when possible (#5355)
Remove calls to `InstStore::GetLocId()` to build a LocId from an InstId
now that they can be constructed directly from the InstId. Most uses of
LocId are just plumbing, so this does not affect them. However places
that want to look inside the LocId do not want to work with the InstId
form. In these places, introduce `InstStore::GetResolvedLocId()` which
converts a LocId (or an InstId as an optimization) into a LocId which is
not backed by an InstId. These locations can be printed (they have a
line and column when they are a NodeId), they can have flags added to
them (`ToImplicit`, `ToTokenOnly`), they can be converted to an
underlying ImportIRInstId, or they may be `None`.

`Dump()` is made to print a resolved location instead of printing the
InstId in the location, since (at least in my experience) the resolved
location is what is interesting in debugging, and this saves manual
`MakeInstId` steps in the debugger every time a location is of interest.

The LocId constructor from InstId is made `explicit` to add clarity to
function calls passing an `inst_id` now directly instead of calling
`context.insts().GetLocId(inst_id)`. To avoid needing to construct
`SemIR::LocId(...)` explicitly in all cases though, the diagnostics code
in Check uses `DiagnosticLocId` as its template parameter which accepts
InstId as well and does the construction of LocId from it.

Because LocId now requires an explicit construction from InstId, any
callers to `AddInst()` functions will have to explicitly convert to
LocId if they had an InstId, but not if they pass a NodeId. To make this
difference clear to callers, we `requires` that the input type can be
converted to LocId. This ensures that passing an InstId results in an
error at the callsite where the InstId is passed, instead of generating
a compiler error when trying to construct `LocIdAndInst` inside
`AddInst()`, which is less clear about what went wrong and doesn't seem
entirely intentional.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-04-28 19:06:24 +00:00
Dana Jansens c38e723dd8 Rename singleton InstId constants to TypeInstId (#5323)
These constant instructions are all TypeInstId already in their type,
and this makes their names match.

Change the name of MakeSingletonInstId as well and update its comment.
2025-04-17 18:57:20 +00:00
Jon Ross-Perkins 4923445e3a Drop Singleton from ErrorInst::SingletonInstId and similar (#5304)
We frequently want to operate on singletons. Per discussion, drop
`Singleton` to make the code shorter.

This started off as wanting to write `inst_id.is_error()`, but the
dependency relationship between ids.h and singleton_insts.h would
require some kind of delayed evaluation to allow the implementation to
remain in headers (which I suspect is helpful to have for inlining). I
could have added something like `IsErrorInst`, forward declared in ids.h
and defined in singleton_insts.h (which would always be included by
typed_insts.h), but the template approach felt like a decent balance
between (a) removing the boilerplate `::SingletonInstId`, (b)
understandability, (c) still visually mirroring if we immediately return
a singleton, and (d) flexibility for more than just `ErrorInst`. But TBH
I'd probably still have written `is_error()` if it didn't require
addressing the cross-header cycle.

Then I tried `SemIR::InstId::Is<SemIR::ErrorInst>`, which generally
worked with types but generated the complaint that it didn't shorten
*all* singleton uses. So pulling back on `::Is`, and instead just
dropping `Singleton`.
2025-04-15 22:40:29 +00:00
Richard Smith c33adfafd3 Replace GetTypeInSpecific with GetTypeOfInstInSpecific. (#5232)
Reduce usage of `GetConstantInSpecific` to a single caller in constant
evaluation, with a TODO to remove that.

This gets us closer to being able to fully perform type-checking against
abstract types instead of types anchored within a particular generic.
2025-04-02 22:52:11 +00:00
Jon Ross-Perkins acbe6530c3 Move diagnostics into a namespace (#5173)
What this really does is avoids shadowing names, so that we can
comfortable have things like `Check::DiagnosticEmitter` or
`Check::DiagnosticLoc` without shadowing being a concern.

Note, down this path I'm also thinking about:

- Renaming misc DiagnosticConsumer/DiagnosticEmitter classes, possibly
just to DiagnosticConsumer/DiagnosticEmitter (so
`Check::DiagnosticEmitter` instead of `SemIRLocDiagnosticEmitter`).
- Dropping `Diagnostic` from `Emitter::DiagnosticBuilder`.
- But not for `Check::DiagnosticBuilder`, because `Check::Builder` would
be ambiguous.
- Renaming diagnostics/diagnostic_* to drop "diagnostic".

[Discussion about SemIRLoc ->
DiagnosticLoc](https://discord.com/channels/655572317891461132/655578254970716160/1353771570463768698)
reminded me of this (in particular the older [Check::DiagnosticBuilder
discussion](https://discord.com/channels/655572317891461132/655578254970716160/1344363562608627763)),
but I'd only do that rename if there's matching consensus about a path
forward where we keep SemIRLoc, and in a way that it's only ever used
for diagnostics (the divergence from which is at the root of current
LocId discussion).

I'm trying to keep that separate from a namespace addition for clarity.
2025-03-26 19:12:10 +00:00
Jon Ross-Perkins 216c499cbf Add declaration checking for fn destroy (#5127)
This adds support for the `destroy` name, and checking of `fn destroy`
structure. It does not add support for the actual destructor calls.
2025-03-14 22:54:12 +00:00
Jon Ross-Perkins 21687e8cb1 Fix use of keyword names in qualifiers with params (#5130)
This is a crash bug, since NameQualifierWithParams needs a specific open
kind. I'd missed that this wasn't actually tested.
2025-03-14 20:16:01 +00:00
Jon Ross-Perkinsandjosh11b c44e688e5d Add parsing for 'fn destroy' (#5045)
Syntax is proposed in #5017, but has already been discussed with leads.
Semantics is left as a TODO.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-03-03 17:37:10 +00:00
Jon Ross-Perkins f7e0b61c3a Refactor HandleIdentifierName away (#5044)
Most of the logic is actually in `GetIdentifierName`. I'm moving the
`CHECK` there for better sharing, also with `IdentifierNameExprId`.

Note this PR is mainly motivated by #5045, which would make this the
only place that needs `AnyNonExprIdentifierNameId` in specific (other
places need to deal with both identifiers and keywords).
2025-02-28 20:06:06 +00:00
Jon Ross-Perkins 311b4ff03d Refactor AddInst-family functions to their own file (#4941)
This in particular uses free functions because it's likely to end up
more consistent with types (versus a wrapper object for InstStore).
Note, this is unlikely to have a performance impact, but if it does, we
can look into related approaches (and we've already discussed using
LTO).

Renames `PendingBlock::AddInst` to `PendingBlock::Add` because
`MakeElementAccessInst` expects the matching name to exist.
2025-02-14 19:44:36 +00:00
Jon Ross-Perkins dc8f47e6ad Move type functions off Context (#4951)
This creates a new check/type.h for most logic, and also moves some
functions to TypeStore in sem_ir/type.h. My approach for TypeStore is to
focus on moving the read-only functions there.
2025-02-13 23:02:38 +00:00
Jon Ross-Perkins afef6cd940 Refactor name lookup logic out of Context (#4930)
This is a pretty straight move of name lookup functionality to
name_lookup.*
2025-02-12 22:03:08 +00:00
Richard SmithandJon Ross-Perkins 8eb4e24cb6 Implement #4864: Core is a keyword (#4909)
Change representation of package names from `IdentifierId` to
`PackageNameId`, and add a special value `PackageNameId::Core` for the
Core package. Add a `Core` expression to name the Core package, and
support for parsing the `Core` keyword in `package` and `import`
declarations.

For now, I've made no changes to instruction fingerprinting or name
mangling. This means that fingerprints and mangled names will collide
between names in the `Core` package and names in a `r#Core` package. See
#4908.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-02-11 21:33:57 +00:00
Boaz Brickner 3d39ab67bf Wrap lookup result in a new ScopeLookupResult (#4831)
Benefits:
* Provide a proper API for accessing lookup information.
* Make assumptions on whether the result is poisoned or not and how we
can use `InstId` explicit.
* Allow safely reusing the `InstId` value for pointing to the poisoning
entity for poisoned results (in a future PR).
* Consolidate `LookupNameInExactScopeResult`, `std::pair<SemIR::InstId,
bool>` and part of `LookupResult`.
Part of #4622.
2025-01-27 10:05:23 +00:00
Geoff Romer 96256652c5 Use FullPatternStack instead of node stack for binding context (#4829) 2025-01-23 17:25:31 +00:00
Jon Ross-Perkins 6b5eb1a101 Id::Invalid -> Id::None (#4834)
High level, replacing `Id::Invalid` with `Id::None` and `Id::is_valid`
with `Id::has_value` for clarity, as discussed
[here](https://discord.com/channels/655572317891461132/655578254970716160/1331664574545395794).
The `IntId` refactoring is needed together with `AnyIdBase` because it's
also used with `ValueStore`.

Note, trying to be careful not to rewrite `EnumBase::InvalidIndex`, or
`is_valid` in general (e.g., `IdKind::is_valid`).

I've tried to sequence commits here:

1. Automatic replacements:

- `((?:Id|Index)(?: |::|\(|Base(?:\(|::)))Invalid((?:Index)?\W)` ->
`$1None$2`
  - `<invalid>` -> `<none>`
  - `InvalidNodeId` -> `NoneNodeId`
  - `/\*invalid\*/` -> `/*none*/`
  - `id((?:_|\(\))(?:\.|->))is_valid` -> `id$1has_value`

2. Manual edits:

  - In `int.h` and `int_test.cpp`
    - `IntT` has `is_value`, which I'm renaming to `is_embedded_value`.
    - Manual edits to comments in this file.
  - `AnyIdBase` and `IdBase`
- Declaration of `is_valid` -> `has_value`, `InvalidIndex` ->
`NoneIndex`.
  - In `ids.h` and `ids.cpp`
    - `is_valid` -> `has_value`
- `// An explicitly invalid ID.` -> `// An ID with no value.`; similar
for index
    - Various math on `InvalidIndex` -> `NoneIndex`
    - Various mentions of "valid" in comments
  - In `value_store.h`, for `IdT::Invalid`, plus one comment
- In `impl.h` and `tokenized_buffer.h`, we had different initialization
of `::None` values (versus `ids.h` syntax) that I fixed manually.
  - Spot checks to compile
- Particularly where `is_valid` replacements didn't catch spots due to
different naming.

3. Autoupdate tests

4. verbose.carbon (NOAUTOUPDATE)

5. Comment spot checks

Note there are probably other mentions of "Invalid" that should be swept
up, but I'd like to argue for merging and separating out remaining
cleanup since this is so sweeping (and likely to hit merge conflicts
from churn). We'll probably have lingering mentions of "invalid" for a
bit regardless, just because there are uses of "invalid" in non-Id APIs.
2025-01-22 23:15:00 +00:00
Geoff RomerandRichard Smith 13434f0e8a Model var as a pattern operator (#4720)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-01-17 17:51:34 +00:00
Geoff RomerandJon Ross-Perkins 4f10735751 Track params in the parser (#4777)
This change splits `NodeKind::IdentifierName` into separate node kinds
depending on whether the identifier is followed by parameters, and
similarly splits `NameQualifier` based on whether the qualifier has
parameters. This enables us to only push a pattern block when it's
actually needed, rather than "defensively" pushing one when it might be
needed.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-01-10 22:11:07 +00:00
David Blaikie 4d0a6db49b Abort checking when encountering an invalid parse node (#4700)
Short term solution/block for #4689
2024-12-18 00:19:12 +00:00
Jon Ross-Perkins 1cba3328f7 Finish removing BuiltinInstKind (#4637) 2024-12-05 22:07:51 +00:00
Jon Ross-Perkins efab39cbd9 Remove InstId::Builtin members (#4632)
- `InstId::Builtin<Inst>` -> `<Inst>::SingletonInstId`
- `InstId::PackageNamespace` -> `Namespace::PackageInstId`
2024-12-05 18:13:46 +00:00
Richard Smithandjosh11b b274622228 Improve infrastructure for formatting types in diagnostics. (#4374)
Instead of stringifying types in the caller in some cases, add new types
to represent:

- `InstIdAsType`: an `InstId` diagnostic argument that represents a type
expression that should be included in the diagnostic
- `InstIdAsTypeOfExpr`: an `InstId` diagnostic argument that represents
an expression whose type should be included in the diagnostic

For these cases, we can produce more user-friendly descriptions of a
type than we can with a canonicalized `TypeId`. Add comments to
discourage using `TypeId` diagnostic arguments when one of the above can
be used, and move over existing uses where it's straightforward to do
so.

Move type stringification code to its own files and out of `SemIR::File`
to make `File` smaller and to further discourage the direct use of the
stringification logic.

Also update type printing to include the `` ` `` delimiters surrounding
the type. The intent is that we will eventually want to include other
information when formatting a type, like Clang does when printing a
typedef (`'string' (aka 'std::basic_string<char>')`), and such
formatting requires that the diagnostic machinery produces the `` ` ``s
itself.

There are a couple of cases where we really want to format valid Carbon
type syntax directly into a diagnostic, rather than an `aka` or similar,
because the diagnostic text includes part of the type itself, for
example: ``"consider using `partial {0}`"``. For such cases, a `Raw`
form of the diagnostic argument types is added: `TypeIdAsRawType` and
`InstIdAsRawType`. In principle we could instead use ``"consider using
`partial {0:raw}`"``, but our diagnostic machinery isn't set up for
that.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2024-10-07 22:55:26 +00:00
Geoff RomerandJon Ross-Perkins dc32aa2690 Initial support for binding patterns in SemIR (#4221)
Introduces the `BindingPattern` and `SymbolicBindingPattern` insts, and
a separate stack of pattern blocks that they are emitted into. The
intent is to generate the corresponding pattern-matching insts (like
`BindName`) from them in a separate pass, but that is deferred to future
PRs.

See
[here](https://docs.google.com/document/d/1U_vQH17V893J9aF1LJXUnFYBNSs2MjKl4bJPaWCB2zo/edit?usp=sharing&resourcekey=0-w0xGYZ0An31Kpz-wvzSXwQ)
for the design this is based on, but note that during review we have
chosen to deviate from that design by putting the patterns in separate
blocks, and omitting the "forward references" from a `BindingPattern` to
its corresponding `BindName`. This in turn necessitates having separate
inst kinds for symbolic and non-symbolic binding patterns.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-25 19:12:58 +00:00
49a8efbe1b where check stage, step 1: designators (#4329)
Right now, there is no checking of `where` requirements. The result of a
where expression is just the type on the left-hand side. It does now
introduce `.Self` so that it is available in expressions on the
right-hand side, in addition to designators corresponding to the members
of type on the left-hand side. Note, though, that diagnostics could
still be improved significantly.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-25 02:44:12 +00:00
Jon Ross-PerkinsandRichard Smith e7aebbe581 Update basic diagnostic capitalization/punctuation (#4328)
This is a primarily automated change:

- Search & replace for capitalization
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s")([A-Z])`
    - `$1\L$2`
- Search & replace for period
-
`(CARBON_DIAGNOSTIC\((?:\n\s+)?\w+,(?:\n\s+)?\s\w+,(?:\n\s+)?\s"(?:[^)]|\n)+)\.("[,)])`
    - `$1$2`
- Limited search & replace for `ERROR: ` -> `error: ` in streamed things
- Leaving a TODO for command_line because there's more cleanup that can
be done there
- Modify diagnostic_consumer.cpp
    - ERROR -> error
    - WARNING -> warning

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-09-19 21:32:53 +00:00
Brymer Meneses 7f930d0f58 Use TupleAccess instead of TupleIndex (#4318)
This change removes the `TupleIndex` instruction, and instead
consolidate it with the `TupleAccess` instruction, per this
[discussion](https://discord.com/channels/655572317891461132/655578254970716160/1271195835975204946).
This change, in turn removes `AnyAggregateIndex`.
2024-09-17 20:26:48 +00:00
4845f40dff Switch CARBON_CHECK to a format string API (#4285)
This switches `DCHECK` and `FATAL` as well.

The goal is to reduce the code size impact of these assertions so that
we can keep more of them enabled. Currently, the largest cost I see from
`CHECK` is not the actual check or the cold code itself, but actually
the failure to inline trivial functions due to the presence of the cold
code. This means that our goal isn't to reduce apparent code size in the
final binary but the LLVM IR cost assessed for these routines in the
inliner, which closely correlates with code size but is a bit different.

As discussed in #4283, experimentation shows that a single function call
with a minimal number of arguments is the lowest cost model for these.
This is easily achieved with a format-string API that internally uses
`llvm::formatv`. This PR is essentially the `CHECK` version of #4283.

However, the check macros are substantially harder to make work with
both format strings and streaming because they also take a condition.
Also, unexpectedly, I was very successful at devising a regular
expression based automated rewrite from the streaming to the format
string form with only low 10s of manual fixes. This includes compacting
strings broken up across lines, etc. Given how well that went, I've
prepared this PR which just directly switches to the format string API
and migrate everything to use it.

One nice side-effect is that the format string approach ends up greatly
simplifying the implementation here as well.

This is ... *shockingly* effective. Parsing speeds up by more than 3%
with just this change. And checking speeds up by **8%** with this change
alone:
```
BM_CompileAPIFileDenseDecls<Phase::Parse>/256      86.3µs ± 1%  82.9µs ± 1%  -3.94%  (p=0.000 n=17+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/1024      431µs ± 1%   415µs ± 1%  -3.76%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/4096     1.77ms ± 1%  1.71ms ± 1%  -3.18%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Parse>/16384    7.44ms ± 1%  7.17ms ± 2%  -3.56%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/65536    30.7ms ± 1%  29.7ms ± 1%  -3.15%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Parse>/262144    131ms ± 1%   127ms ± 1%  -2.81%  (p=0.000 n=18+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/256       878µs ± 2%   800µs ± 1%  -8.91%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/1024     1.88ms ± 2%  1.72ms ± 1%  -8.56%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/4096     5.78ms ± 2%  5.28ms ± 1%  -8.70%  (p=0.000 n=20+18)
BM_CompileAPIFileDenseDecls<Phase::Check>/16384    21.9ms ± 1%  20.1ms ± 1%  -8.02%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/65536    90.4ms ± 2%  83.1ms ± 1%  -8.04%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Check>/262144    381ms ± 2%   352ms ± 1%  -7.79%  (p=0.000 n=19+19)
```

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2024-09-12 16:42:08 +00:00
Brymer Meneses c353f6bd78 change tuple index (#4218)
This changes the tuple index from tuple[0] to tuple.0 in accordance with
the accepted propsal
https://github.com/carbon-language/carbon-lang/pull/3646

I messed up syncing to trunk on my original PR
https://github.com/carbon-language/carbon-lang/pull/4186, that's why I'm
starting on a blank state. Please let me know if I missed incorporating
a change from my prior PR.
2024-08-15 16:06:02 +00:00
Richard Smith 3cb769a053 Rename "generic instance" to "specific" throughout the toolchain. (#4165)
As discussed in toolchain meeting, we want to avoid overloading the
meaning of "instance", and "specific" was the best name we found. It's a
little unorthodox and inventive, but hopefully over time will become as
unsurprising as the term "generic" is.
2024-07-25 16:42:01 +00:00
Richard Smith 3cc90f9017 Move GetTypeInInstance from Check to SemIR. (#4144)
In preparation for this function being used by other parts of `SemIR`
and by lowering.
2024-07-17 23:27:14 +00:00
Jon Ross-Perkins 99696b9812 Rename check handlers to HandleParseNode overloads. (#4121)
This is for consistency with #4120. Similar to that, we can use
overloads on the typed NodeId rather than individually named handlers.
There isn't the same caller benefit here though, since the calls from
check.cpp are already boilerplate.
2024-07-12 22:38:06 +00:00
Richard SmithandJon Ross-Perkins 50d56aa7c9 Add an instruction to represent a use of a dependent value from a generic instance. (#4122)
We can't use the instruction from the generic directly, because it
doesn't have the right constant value. Instead add an instruction that
models the transition from the constant value in the generic to the
constant value in the generic instance.

Also start associating the self generic instance with unqualified
lookups that find results in an enclosing generic, so that we track the
information necessary to create the new instruction.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-07-12 14:59:01 +00:00
Jon Ross-Perkins a81d67c629 Rename Builtin to BuiltinInst, particularly to get BuiltinInstKind (#4115)
I'm trying to increase the distinction between BuiltinKind and
BuiltinFunctionKind. BuiltinKind is for instructions,
BuiltinFunctionKind is for function definitions. To get to this point,
I'm doing a few changes:

- BuiltinKind -> BuiltinInstKind
    - builtin_kind.* -> builtin_inst_kind.*: filename consistency
- Builtin -> BuiltinInst: mainly for consistency with the above
- Builtin::builtin_kind -> BuiltinInst::builtin_inst_kind: somewhat
repetitive but seems like a consistent edit
- Function::builtin_kind -> Function::builtin_function_kind: seems a
useful distinction

I'm leaving alone things like (and mentioning in case there's a desire
for more renames):

- InstId::BuiltinError, InstId::ForBuiltin: these I think are more
apparent because they're directly associated with Inst.
- GetBuiltinICmpPredicate in lowering: maybe builtin function handling
should be in its own file, but these local names don't feel problematic
to me.
- GetBuiltinType, BuildBuiltinValueRepr, PerformBuiltinIntComparison:
similar to the above, names don't feel too problematic
2024-07-11 18:24:17 +00:00
Richard Smith 6d3c915bbf When performing name lookup, determine the generic instance within which the lookup result was found. (#4118)
Require types into which qualified lookup is performed to be completely
defined. Eventually this will trigger substitution into the definition
for generic types.
2024-07-10 18:35:55 +00:00
Richard Smith 7322a1e220 Build a list of dependent constants to recompute in each instance of a generic. (#4110)
For each generic, build a list of instructions describing the
computations we need to do when resolving an instance of the generic:
this is a list of the instance-specific constants and types that the
generic uses. Another way of viewing this list is as a block of Carbon
SemIR code that is evaluated in order to form an instance of the generic
-- this is referenced in the code as the "eval block" for the generic.

For each instruction in the generic whose type or value is a symbolic
constant, replace that type or constant value with a symbolic reference
that says "to find the actual type or value, look at index N in the list
of values for the generic instance".

For an instruction with a symbolic constant value, we can just add that
instruction to our list. For an instruction with a symbolic constant
type, however, we may not have a corresponding instruction computing the
type within the generic and may need to build a new instruction, but
will reuse one where possible. In the case where we build a new
instruction, we use the existing substitution code to build the type
within the eval block.

For now, this transformation is only done in the declaration region of
the generic, not in the definition region. Also, we map back from the
symbolic references to the underlying constant value in a few places
where we will eventually need to do a lookup into a generic instance, in
order to avoid regressing the tests.
2024-07-08 22:29:37 +00:00
Chandler Carruth 8c64f0bfdd Add -Wmissing-prototypes and fix issues it finds. (#4019)
Most of these are places where we failed to include a header file and
simply never got an error about this. The fix is to include the header
file.

Most other cases are functions that should have been marked `static` but
were not. Finding all of these was a main motivation for me enabling the
warning despite how much work it is.

One complicating factor was that we weren't including the `handle.h` for
all the state-based handler functions. While this isn't a tiny amount of
code, it is just declarations and doesn't add any extra dependencies. It
also lets us have the checking for which functions need to be `static`
and which don't. For the `parse` library I had to add the `handle.h`
header as well, I tried to match the design of it in `check`.

I have also had to work around a bug in the warning, but given the value
it seems to be providing, that seems reasonable. I've filed the bug
upstream: https://github.com/llvm/llvm-project/issues/94138

I also had to use some hacks to work around limitations of Bazel rules
that wrap `cc_library` rules and don't expose `copts`. I filed a bug for
`cc_proto_library` specifically:
~https://github.com/bazelbuild/bazel/issues/22610~ 
https://github.com/bazelbuild/bazel/issues/4446
2024-06-04 20:04:45 +00:00
Jon Ross-PerkinsandRichard Smith 5bb318cae6 Switch AddInst struct init style. (#4012)
Trying to conform with #4009. Changes SemIR::LocIdAndInst construction
to root out struct init cases with AddInst and related functions. I'm
using templating of AddInst functions in order to avoid `AddInst(loc_id,
InstName{...})` and instead have `AddInst<InstName>(loc_id, {...})` with
I think similar readability results. There are a couple cases where inst
construction is templated and so designated initializers couldn't be
used, so this may be better for those in particular due to the extra
type enforcement.

This probably doesn't clean up every last case, but I was trying to get
the bulk at once without bleeding over into less related changes.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-05-31 22:49:44 +00:00
Richard Smith 28cefe98df Factor out pushing / popping of names plus parameters. (#4005)
Previously we did some of this in decl_name_stack and some of it in the
callers of decl_name_stack. Factor out a single place to pop a name and
its optional following parameters.

Part of making this behavior consistent is that we now track whether an
implicit parameter list was present or absent rather than mapping an
absent list to `InstBlockId::Empty`. This improves our redeclaration
checking and the precision of some diagnostics.
2024-05-30 16:05:35 +00:00
Richard SmithandJon Ross-Perkins 28170c7867 Parse parameters in name qualifiers. (#3988)
Parse the name of a declaration as a sequence of `NameQualifier`s --
which have a name, possibly parameters, and a trailing period --
followed by a name and possibly parameters. This prepares us for parsing
declarations of members of generic classes and similar cases, but
actually supporting such member redeclarations is left to a future
change.

We previously required functions to have parameters, but no longer do,
following the direction of #3848. Cases like namespaces that can't
actually have parameters are now diagnosed in check instead of in parse.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-05-29 00:47:29 +00:00
CJ Johnson d0e8afc51b Handle arrow operator (#3768)
This change implements the check behavior for the arrow operator.

`ptr->Foo()` is rewritten as `(*ptr).Foo()` and `ptr->(X.y)` is
rewritten as `(*ptr).(X.y)`
2024-03-18 17:40:00 +00:00
Richard Smith 3884d3c27e Parse and check support for compound member access. (#3790)
On the parsing side, we treat `a.(b)` as a member access whose second
operand is a `ParenExpr` rather than a `MemberName`. A new node category
is added for the union of `MemberName` and `ParenExpr` to support this.

Checking is mostly reusing the same pieces we already have for simple
member access. Compound member access is in most ways a simplified form
of simple member access because it doesn't need to do any lookup.
2024-03-16 22:38:23 +00:00
Richard Smith 6c6b3b6618 Factor member name lookup out of handle_name.cpp. (#3774)
The member access logic is fairly large, and will be growing with the
addition of impl lookup. Factor it out to separate the logic for dealing
with handling the parse node and updating the node stack from the logic
that checks and builds the member access expression.
2024-03-13 21:38:22 +00:00
Jon Ross-Perkins 86a7c9ff45 Rename parse_node -> node_id (#3760)
This was previously discussed at
https://discord.com/channels/655572317891461132/655578254970716160/1209975051588210729.
I'm initiating this mainly because we typically use "id" suffixes to
indicate an `IdBase` being passed around and the non-id suffix of
`parse_node` suggests at it carrying more data than it actually does.
There used to be more reason for avoiding `node_id` because
`SemIR::InstId` used to be named `NodeId`, but that's no longer
necessary. As a consequence, I'd like to rename `parse_node` to more
precisely reflect its type.

In full, this is doing:

```
parse_node_kind -> node_kind
parse_node -> node_id
ParseNodeCategory -> NodeCategory
ParseNodeKind -> NodeKind
ParseNode -> NodeId
```

This is primarily in check and sem_ir, but with some `parse_node_kind`
references in parse too.

Pluralization is consistent with name forms on both sides, so that
wasn't part of my replacements.
2024-03-09 00:21:29 +00:00
Richard Smith 90369815ad Support for name lookup into interfaces. (#3729)
Follow the existing support for classes.

None of this is especially useful until other features land: we don't
yet have any use for defining methods of an interface out of line,
because we don't support `default` or `final` interface methods, and we
don't have impl lookup, so referring to an interface member is also not
especially useful. But this is a nice piece to factor out that's a
prerequisite for effectively testing other interface features.
2024-02-27 21:28:46 +00:00
Jon Ross-Perkins 364ea5d3f2 Assign a constant to ClassDecl/InterfaceDecl for name references. (#3722)
By adding a constant to ClassDecl/InterfaceDecl, we're able to remove
name reference special-casing. Use TryEvalInst on the Decl to generate
the Type. For ClassDecl, then use the generated constant for
self_type_id.
2024-02-24 00:00:18 +00:00
Jon Ross-Perkins 8ad0c70f9f Add ClassDecl/Type import functionality. (#3709)
I believe this PR is sufficient to pull in all current class features,
including the current bits of inheritance which have been implemented.
Because a class declaration can reference its own type, this creates an
incomplete type prior to constant loading.

Right now, the object representation is imported proactively, but
individual fields are left as ImportRefUnused. This means that member
functions and similar will only be imported if called.

This also adjusts how function parameters are being handled, to match
the expectations of Self param structure.

When formatting, I'm starting to look into constants. Otherwise we get
"unexpected instref".

Overall, there are a few things that may be worth further discussion:

- The lack of a constant corresponding to the ClassType on ClassDecl is
inconvenient -- I'd like to see how zygoloid feels about trying to
restructure this. i.e., I'm setting a constant in order to be able to
track things down later, it'd be nice if the normal IR did this simply
for consistency, or if we were able to combine these rather than having
separate instructions.
- Should we shift the parse node tracking further, and go with a setup
wherein imports can embed import references into that? e.g., negative
values go to another array which includes a ImportIRId for printing
diagnostics, replacing the invalid NodeId.
- Can the formatter switch to a more general scan of instructions for
naming, to eliminate the ImportRef constant approach added here?
- GetExprValueForLookupResult special-casing instructions felt
surprising, I might see if there's a way to restructure to avoid that.

But I think these issues are things that can be separated out.
2024-02-22 22:29:06 +00:00
Jon Ross-Perkins 7e7e87056a Add diagnostic support to pass in NameId. (#3696)
Builds on #3695 to provide equivalent support for NameId.
2024-02-09 17:26:03 +00:00