Commit Graph
409 Commits
Author SHA1 Message Date
josh11bandJosh L ea0b0b4b48 Add facet type values and an instruction that produces them (#4460)
Still to do:
* Represent facet type values in a canonical form
* Produce & consume facet type values instead of interface values
* `type` should be associated with a canonical facet type value
* Support `&` on facet type values
* Type check and enforce requirements in facet types

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-11-04 21:43:55 +00:00
Richard Smith 26d7717d60 Insert a value_of_initializer after a call to ImplicitAs where possible. (#4473)
This avoids going through memory when performing an implicit conversion
to a type with a by-copy value representation, such as i32.
2024-11-04 16:06:19 +00:00
Chandler Carruth 1b2eb42c5a Start avoiding parse diagnostics on error tokens (#4431)
An invalid parse due to an error token isn't likely a great diagnostic
as it will already have been diagnosed by the lexer. A common case to
start handling that is when the parser encounters an invalid token when
expecting an expression.

This removes a number of unhelpful diagnostics after the lexer has done
a good job diagnosing.

This also means that there may be parse tree errors that aren't
diagnosed when there are lexer-diagnosed errors, so track that.

Follow-up to #4430 that almost finishes addressing its diagnostic TODO.
2024-11-02 05:53:27 +00:00
Richard Smith 44fe65fbe5 Rename BigInt to IntLiteral. (#4476)
In preparation for changing the type of integer literals to
`IntLiteral`.
2024-11-02 02:09:10 +00:00
Richard Smith db76e81630 Rename IntLiteral to IntValue. (#4475)
This instruction represents integer values, whether they come from
literals or calculations, so it the old name is inaccurate. I also plan
to rename `BigInt` to `IntLiteral` based on recent discussion and this
change aims to avoid confusion stemming from the same name being used
for two different things.

I'm not renaming `FloatLiteral` because recent discussion suggests we
may want distinct `FloatLiteral` versus `FloatValue` representations in
SemIR.
2024-11-02 01:19:39 +00:00
Richard Smith 261fe38508 Fix use-after-free in return statement handling. (#4472)
Initialization can import a function and thus invalidate the reference
we're holding to the enclosing function. Don't use the reference after
initialization completes.
2024-11-01 23:11:27 +00:00
Richard Smith 32e5212daa Fix lowering of a conversion from a type with a pointer value representation to a type with a copy value representation. (#4467)
We previously generated a `value_bind` instruction of the wrong type,
resulting in lowering building bad LLVM IR.

Also fix another issue exposed by this change, where we would import
constants without marking their types as complete, and then crash in
lowering while trying to lower them. This happens in particular for the
`FunctionType`s of functions in `ImplDecl`s. Address this by skipping
lowering for constants with incomplete types.
2024-11-01 14:52:57 +00:00
Richard Smith fab07726c9 Add import support for int_type. (#4466) 2024-10-31 23:05:25 +00:00
Richard Smith 3192cfc776 Add import support for specific_function constants. (#4465)
These can currently only be imported as part of the eval block for a
generic, because they only show up as the callee of a call instruction.
2024-10-31 20:13:05 +00:00
Jon Ross-Perkins 99e96605bf Don't create a compile time binding after CompileTimeBindingInVarDecl (#4463)
Related to #4461, more generally try not to produce a compile-time
binding when the code shouldn't be able to do so.
2024-10-31 18:27:43 +00:00
Jon Ross-Perkins f70221c040 Fix deduction crash for function with missing parameters. (#4461)
This is because `var x:! () = ();` modifies the binding index, which
causes `A` to be generic, which causes the params to be used, which
crashes. There may be another issue to fix here so that the invalid
binding doesn't modify the binding index, but at least
`param_patterns_id` should probably be set consistently with
`params_id`.
2024-10-31 17:12:49 +00:00
Jon Ross-Perkins d944347e7b Elide prelude components in the IR formatter. (#4453)
This is in particular to avoid churn from changes such as #4370. I think
the import list can be helpful (particularly to understand what the
library is aware of), but it's a different trade-off for the prelude
package due to the implicit imports.
2024-10-30 22:45:26 +00:00
Geoff RomerandJon Ross-Perkins e20e8bfbea Consolidate caller match in one function call (#4446)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-29 23:31:50 +00:00
Brymer MenesesandJon Ross-Perkins 89eed4220f Expose indexing as a language interface (#4370)
This PR makes it so that types can implement the `IndexWith` interface
so that they can provide their custom indexing behavior.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-29 21:25:02 +00:00
josh11bandJosh L c30b1d1124 Fix where crash when empty decl_name_stack (#4451)
Bug found by fuzzer.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-29 19:38:02 +00:00
Richard Smith df68bf9f71 Switch to using Core.BigInt as the type of the size of a type literal. (#4450)
This removes one of the few ways in which `i32` is special and gets us
closer to removing it as a special case.
2024-10-28 23:35:08 +00:00
Richard Smith a0609b9155 Don't eagerly import all impls. (#4447)
Instead, eagerly import only the impls from the api file corresponding
to the current file, if any, because we need those for impl
redeclaration lookup. For all other cases, load only the impls in
libraries that are referenced as part of an impl lookup query.
2024-10-26 00:38:24 +00:00
Chandler Carruth 577fda1ca2 Speed up type literal lexing and make it more strict. (#4430)
This rejects type literals with more digits than we can lex without
APInt's help, and using a custom diagnostic. This is a pretty arbitrary
implementation limit, I'm wide open to even more strict rules here.

Despite no special casing and a very simplistic approach, by not using
APInt this completely eliminates the lexing overhead for `i32` in the
generated compilation benchmark where that specific type literal is very
common. We see a 10% improvement in lexing there:
```
BM_CompileAPIFileDenseDecls<Phase::Lex>/256        39.0µs ± 4%  34.8µs ± 2%  -10.86%  (p=0.000 n=19+20)
BM_CompileAPIFileDenseDecls<Phase::Lex>/1024        180µs ± 1%   158µs ± 2%  -12.22%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Lex>/4096        731µs ± 2%   641µs ± 1%  -12.31%  (p=0.000 n=18+20)
BM_CompileAPIFileDenseDecls<Phase::Lex>/16384      3.20ms ± 2%  2.86ms ± 2%  -10.47%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Lex>/65536      13.8ms ± 1%  12.4ms ± 2%   -9.78%  (p=0.000 n=18+19)
BM_CompileAPIFileDenseDecls<Phase::Lex>/262144     64.0ms ± 2%  58.4ms ± 2%   -8.70%  (p=0.000 n=19+18)
```

This starts to fix a TODO in the diagnostic for these by giving a
reasonably good diagnostic about a very large type literal. However, in
practice it regresses the diagnostics because error tokens produce noisy
extraneous diagnostics from parse and check currently. Leaving the TODO
there, and I have a follow-up PR to start improving the extraneous
diagnostics.
2024-10-24 21:43:35 +00:00
Geoff Romer b67d03126e Separate inst kind for out params (#4442) 2024-10-24 15:22:32 +00:00
Richard Smith 2e63da1a40 Move diagnostic kind name to the end of the diagnostic. (#4437)
Also surround it in square brackets rather than parentheses. This
matches the format used by Clang and GCC, and means diagnostics will
still match the `file:line:col: error: ` pattern used by some IDE tools.

Before:
```console
fail_builtins.carbon:11:11: error(AliasRequiresNameRef): alias initializer must be a name reference
```

After:
```console
fail_builtins.carbon:11:11: error: alias initializer must be a name reference [AliasRequiresNameRef]
```

Also tighten up test regex to only match on `STDERR` lines that list a
file name.
2024-10-23 16:56:23 +00:00
Geoff Romer 9266f867f9 Model the return slot as an output parameter (#4432)
Also fix `Param` insts to have meaningful names in pretty-printing, to
help clarify relationship with return slot.
2024-10-23 16:53:34 +00:00
Jon Ross-Perkins 9fefef162f Add tests to catch untested diagnostics. (#4426)
Use the diagnostic kind printing in #4425 to catch when we have
diagnostics with no tests.

This merges a couple other use-cases of filegroup manifests into a
common rule.

Note I do add a few tests for things, and also some things are
_actually_ unit tested (just not in the file_test structure). But I
stopped when I realized that dealing with merge conflicts is going to be
a pain. I might end up reverting test changes (as part of merge conflict
resolution) and doing narrow test additions in a separate PR, after both
this and #4425 are merged.
2024-10-21 20:16:18 +00:00
Geoff Romer 223c5cb04b Restructure handling of runtime parameters (#4422)
- Generate runtime indices as part of pattern matching, rather than as a
separate postprocessing/rewriting step.
- In contexts where runtime parameters aren't permitted, avoid emitting
insts for them to begin with, rather than trying to detect the problem
and rewrite the IR to remove them later on.
2024-10-21 19:53:38 +00:00
Jon Ross-PerkinsandGeoff Romer 302aa1bb30 Remove uses of StringLiteral in format strings. (#4416)
Building on #4411, avoid using StringLiteral in format strings. This
includes a diagnostic check to prevent regressions (which is also how I
gathered issues).

Note, I haven't looked at `std::string` uses yet, but we might need
things like that to be able to pass strings in code back to the user.
StringLiteral though means that it's literally written down in the
toolchain, at which point it should probably be written in the format
string instead of separately.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2024-10-21 19:39:53 +00:00
Jon Ross-Perkins 62c36eceda Support printing the diagnostic kind for verification. (#4425)
This is to help identify which diagnostics we're actually using.

Note that driver/testdata still has tests which don't pass this flag,
and so continue to test the kind-less (default) behavior.
2024-10-18 22:33:56 +00:00
Richard Smith 684cda3d53 Don't deduce values for explicitly-specified generic bindings. (#4415)
Distinguish between deduction against a symbolic binding pattern and
deduction against a symbolic binding name. In the former case, the value
is being explicitly specified and must be constant. In the latter case
we encountered a use of the binding name as a subexpression, and should
deduce against it if it's not explicitly specified.
2024-10-18 15:33:10 +00:00
Jon Ross-PerkinsandRichard Smith b5a837aa89 Refactor modifier formatting to remove string passing. (#4418)
I'm taking the approach of making DiagnosticBase an API so that we can
pass similar diagnostics as parameters. An alternative would be to do
the function_ref approach we've done elsewhere, but these felt more
boilerplate to me.

Note I'm also modifying messages here. Let me know if you'd like
different changes and/or just keeping current formatting (keeping
current formatting would also allow removing some of the templating I've
added, but it felt helpful putting explicit tokens where possible). But
also, things like "`protected` not allowed on `interface` declaration at
file scope" were part of the phrasing issue, I think.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-17 22:47:40 +00:00
Geoff Romer 5a795db0de More focused diagnostic notes for parameters (#4420) 2024-10-17 21:47:20 +00:00
Jon Ross-Perkins 7c22348461 Add s plural format to IntAsSelect (#4423)
Per discussion on #toolchain, add "s" as a special-case for the common
plural format.

Note this removes periods from a few diagnostics; the periods shouldn't
be there per message style. Also, while I'm ignoring llvm::StringLiteral
uses, those should be addressed as #4416 -- this'll probably conflict
and make me clean up one or the other.
2024-10-17 19:51:52 +00:00
Jon Ross-Perkins 780dd3addc Remove mistaken asserts and add regression test (#4424) 2024-10-17 18:49:31 +00:00
Jon Ross-Perkins 5bdeb010c8 Clean up format_provider uses (#4417)
Building on https://github.com/carbon-language/carbon-lang/pull/4411,
replace format_provider uses (other than `TokenKind`, which is more on
the okay side of things)

Also does some edits to `ClassMemberDefinition` to try to better match
diagnostic style
2024-10-17 18:47:29 +00:00
Richard Smith a02dfe0226 Superficial support for Core.BigInt type (#4414)
Add a `Core.BigInt` type and a corresponding builtin type in the
toolchain. See [corresponding section of the
design](https://docs.carbon-lang.dev/docs/design/expressions/literals.html#defined-types).

So far this type is not used for anything, and there is no way to create
an instance of it.
2024-10-16 23:27:01 +00:00
David BlaikieandRichard Smith dfed743de2 Add vtable pointers to class layout (#4407)
A small step to virtual functions - adding vtable pointers to the
layout, but not initializing or otherwise using them at this stage.

A few open design questions I'd love feedback on:

* Is this the right/good enough SemIR representation for now? This patch
adds a `is_dynamic` attribute to `SemIR::Class` and populates/flags it
based on the flag of the base class, or if any virtual function is
declared in the class (or, at least that's my intent). Some other
options include:
* Each `Class` could store a `ClassId` (or `TypeId`?) of the (possibly
indirect, possibly self) base class that is the first one that is
dynamic/has a vtable pointer
* Could make the property narrower, like `has vtable pointer` and have
it `true` only on the type that introduces the vtable - then derived
classes would have to walk their base classes to check if they're the
one that needs to define the vtable pointer or not
* Should the vtable be the first element in the type? If there's a
non-dynamic base type, we could have a layout that's `{<non-dynamic base
type>, vtable ptr, <derived members>}`? Derived types would still be
able to uniquely identify where their vtable pointer is just fine... -
and the vtable pointer is, in a sense, a member of that intermediate
type, so it does seem a bit strange to force it to the front - but I
guess it's probably more efficient in some ways?

Open to any other suggestions/advice/thoughts on the direction, etc.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-16 21:26:17 +00:00
Geoff RomerandJon Ross-Perkins 9d942f4633 Generate parameter pattern-match IR from pattern IR (#4388)
Also propagate the pattern IR along with the pattern-match IR, and use
it where appropriate.

Strictly speaking, some parts of the pattern-match IR are allocated
eagerly, while traversing the pattern's parse tree, but they still
aren't actually emitted until we traverse the associated pattern insts.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-16 19:15:29 +00:00
David BlaikieandRichard Smith d491387a98 Disallow creating instances of abstract classes (#4381)
A good first-pass, at least. (abstract adapters are rejected with this
change, though pending further language design discussion)

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-10-12 15:17:42 +00:00
Richard Smith 1a1bfd2eb2 Track and resolve the specific callee in a call to a generic function (#4395)
Add a new `specific_function` instruction that represents a generic
function plus its deduced argument list as a callee in a function call.
The new instruction can only appear as the immediate operand of a call
instruction, so we give it a builtin placeholder type.

At the end of each file, require definitions for all specific functions
used in that file. Resolve the generic with the argument list to produce
those specific function definitions as needed, and diagnose if the
generic doesn't have a definition available.

A few tests are updated in cases where they declared and used generic
functions but didn't previously provide a function definition.
2024-10-10 20:52:46 +00:00
David Blaikie b1014bf9f5 Disallow abstract or base on class declarations (that are not definitions) (#4378)
Per:
[p3762](https://docs.carbon-lang.dev/proposals/p3762.html#modifier-keywords:~:text=Other%20class%2C%20impl%2C%20and%20interface%20modifiers%20%28abstract%2C%20base%2C%20final%29%20exist%20only%20on%20the%20definition%2C%20not%20on%20the%20forward%20declaration):
"Other class, impl, and interface modifiers (`abstract`, `base`,
`final`) exist only on the definition, not on the forward declaration."
2024-10-10 17:41:38 +00:00
Richard Smith efb5d6d25a Assign locations to instructions in a generic eval block. (#4393)
The locations point to the first instruction in the generic that needed
the relevant constant value or type.

For now, this must makes the formatted SemIR a bit more useful, but in
the future it will also provide locations for diagnostics caused by
monomorphization failure.
2024-10-09 19:03:15 +00:00
Richard SmithandJon Ross-Perkins 6410d6e140 Add support for deduction of most kinds of type constant. (#4389)
This adds deduction in all the cases where we can match the instruction
fields of the parameter against the corresponding instruction fields of
the argument. This handles all current type constants except for struct
types, for which we would want to match by field name.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-10-09 00:42:53 +00:00
Richard Smith 9fadfb5e82 Basic support for argument deduction in generic impls. (#4380)
Refactor the current function call deduction logic to make it reusable.
Call into it from `impl` deduction. Also build a generic region for the
definition portion of a generic `impl` and substitute into it before
accessing the witness in a specific `impl`.

This is enough to get simple uses of generic `impl`s to work. The main
blocker for more complex cases is that we have very little support for
non-trivial deduction, so while we can deduce `forall [T:! type] T as
I`, we can't deduce `forall [T:! type] C as I(T)` yet.
2024-10-08 22:17:37 +00:00
Geoff Romer 6439f9065d Handle block scopes in compile-time binding check (#4379)
This fixes a fuzzer-found crash when a compile-time binding occurs
inside a block (which is represented by an invalid inst ID).
2024-10-07 22:53:22 +00:00
josh11bandJosh L 6dbeda612a where check stage, step 3: some type checking (#4364)
With this, we now check:

* The left argument to `where` is a facet type
* The right argument of a rewrite (`=`) requirement converts to the type
of the left argument.
* The left argument of an `impls` requirement is a type and the right
argument is a facet type.

No checking is done for `==` constraints yet.

In addition, make the "is facet type" query into its own function and
fix some comments noticed as part of this change.

This change reveals that accessing the members of a facet, like `.Self`,
isn't doing the right thing, and will have to be fixed in a follow-on
PR. Some tests have been adjusted or disabled as a result.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-05 01:03:43 +00:00
Richard Smith 17411c5e78 Assign a name to interface_type instructions. (#4369)
This matches what we do for `class_type` and `function_type`.
2024-10-04 23:06:24 +00:00
Richard Smith 568ad197d1 Track the instruction used to name the type and constraint in an impl. (#4368)
This is necessary in order to have access to the specific versions of
their constant values in a generic impl.

Stub out impl deduction.
2024-10-04 00:06:55 +00:00
David Blaikie eab5dd6112 Reject abstract function definitions (#4350)
Not sure about error recovery options - can/should we drop the
definition as a means of recovery when building the SemIR? I guess
probably not, so I guess this change is about right.

Phrasing of the error message I'm certainly open to.
2024-10-03 22:50:46 +00:00
josh11bandJosh L d6d70bf80d Handle runtime implicit parameters, and self outside of methods (#4361)
Closes #4356, #4359

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-03 20:24:28 +00:00
David Blaikie afbea6a9ec Disallow base virtual in adapter (#4343)
According to
https://docs.carbon-lang.dev/docs/design/generics/details.html#adapting-types:
> You can add any declaration that you could add to a class except for
declarations that would change the representation of the type. This
means you can add methods, functions, interface implementations, and
aliases, but not fields, base classes, or virtual functions. The
specific implementations of virtual functions are part of the type
representation, and so no virtual functions may be overridden in an
adapter either.
So, let's check/reject that.

Checking at the end of the class ensures that no matter the order of
methods and adapt statements, the issue will still be correctly
diagnosed.
2024-10-02 18:38:00 +00:00
josh11bandJosh L 49e0c186fc Add comma between the arguments to the bind_symbolic_name instruction (#4358)
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-10-01 23:58:30 +00:00
Richard Smith 4ca711c175 When converting an expression to type type, retain the resulting instruction as well as the TypeId. (#4355)
The `TypeId` is lossy, as it represents only the canonical type, and not
the specific computation that produced it.
2024-10-01 01:49:39 +00:00
Richard SmithandJon Ross-Perkins 9d5ec52232 Use more compact storage for impl lookup buckets. (#4351)
If the bucket is of size zero or one, which is expected to be the common
case, then store it directly. For the remaining cases, use a side table
of lookup buckets.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2024-09-29 17:31:53 +00:00