Commit Graph
48 Commits
Author SHA1 Message Date
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
Richard Smith 181a592b8c Support for parsing expression patterns (#6977)
When parsing a pattern, if we encounter something that isn't pattern
syntax, try parsing as an expression instead. We only need one-token
lookahead to distinguish pattern syntax from expression syntax.

Track a precedence group through pattern parsing so that we can allow
different kinds of expressions in a top-level pattern (such as the
operand of `let`) and in a nested pattern (such as a subpattern of a
tuple pattern or within grouping parens). For example, we do not allow
`case if ...`, and for now I've chosen to also not allow logical or
relational operators at the top level of a pattern, so `case 1 + 1` is
OK, but `case 1 == 1` and `case true and false` require parentheses.
This decision should be ratified or revisited by a design proposal.

Very basic check support is also provided, only sufficient to form an
`ExprPattern` instruction and nothing beyond that. For now, all pattern
matching against an `ExprPattern` fails with a TODO error. To support
that, I've switched from calling `BeginSubpattern` in the parent handler
of a pattern and `EndSubpatternAs*` in the pattern handler itself to
calling both functions in parent handlers, with `EndSubpattern`
converting an expression into an expression pattern where needed.

Depends on #6976.

Assisted-by: Gemini via Google Antigravity
2026-03-28 00:06:06 +00:00
Geoff Romer 4a0cf6c1fb Track the start of a signature more accurately (#6760)
This change ensures that a function signature always starts with an
`IdentifierNameMaybeBeforeSignature` node (renamed from
`IdentifierNameBeforeParams`), even in the case of function declarations
like `fn F -> T` that have no parameter list. As a consequence, this
ensures that we push new entries onto `pattern_block_stack` and
`full_pattern_stack` when we start processing the function signature.
2026-02-23 22:46:03 +00:00
Geoff Romer 7938d9a8d0 Lex/parse support for ->?, :?, and form literals (#6695)
See #5389 (pending) for the language design.
2026-02-07 02:41:22 +00:00
Geoff RomerandRichard Smith 43ffd721a4 Support ref tags on arguments to ref params (#6312)
The issue of whether/how to include `ref` tags in the textual and
in-memory SemIR (see discussion
[here](https://discord.com/channels/655572317891461132/655578254970716160/1431316355742961805))
is left as future work.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-11-11 20:30:19 +00:00
Richard Smith bac828d244 Add support for char keyword per #5903. (#6078)
Make inst namer and stringify print `Core.Char` and `Core.String` as
`char` and `str` respectively. Plus a few cleanups.
2025-09-16 20:45:01 +00:00
Richard Smith 41ed82e033 Add basic support for strings to core, check, and lower. (#5963)
Add a `Core.String` class to the prelude representing a string view, and
rename the `String` keyword to `str` and make it evaluate to
`Core.String`.

`Core.String` is represented as a pair of a pointer to a character
(actually, to the first character of a string, but we don't have a way
of modeling that yet) and a size (which should be pointer-width, but is
currently always a `u64` as we don't have a `usize` equivalent yet).
`Core.String` values are generated directly by the toolchain for string
literal expressions.

This follows the direction established at the recent summit, but the
design implemented here has not been through the proposal process yet.
2025-08-20 00:18:50 +00:00
37d5046ceb Support parse/check/lower for char (#5901)
toolchain/check/testdata/builtins/char/basics.carbon and
toolchain/lower/testdata/builtins/char.carbon are probably the most
interesting tests here. The parse tests is required because this adds a
new node kind, and we need coverage of it; but the attached info is
minor. There's a fair amount of test churn here because I'm adding the
Core.Char and Core.CharLiteral types as new singletons.

My intent here is that `CharId` is always a unicode code point, even
when the type is a `Char` and thus must be a single UTF-8 code unit
(single byte). This mainly means the stored value of a `CharValue` can
be printed internally without knowing the type.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-08-06 20:39:01 +00:00
Jon Ross-Perkins 806bee1063 Shift from ARGS to EXTRA-ARGS where possible (#5602)
Adds minimal defaults for codegen so that those tests don't need to
specify the full command line.

Moves driver/testdata/compile to check/testdata/basics/raw_sem_ir, which
seems like it better reflects the focus. Removes the textual IR test
because we have plenty of those now.

Moves a multiline token diagnostic test to parse because (a) diagnostics
doesn't have other tests and (b) this is really testing the way that
parse structures the location.

Drops `--include-diagnostic-kind` from some driver tests that aren't
testing a diagnostic, so the flag felt a bit like noise (even before
this change, there are a few tests that don't specify it because they're
not intended to test an emitted diagnostic, just high-level diagnostic
behaviors).

Adds some comments to reflect my understanding of why a test exists,
when I was pausing to think about it.

Modifies the stdin test to do more dumps; which happens to expose we
currently misbehave.
2025-06-03 22:09:57 +00:00
Dana Jansensandzygoloid 24bde46181 Change array syntax from [T; N] to array(T, N) (#4981)
In line with the proposal in #4682, this changes the array syntax to be
array(T, N). `array` is a builtin keyword which must be followed by
parens containing two expressions and a separating comma.

The array type expression is still fully builtin, it does not forward to
a Core.Array library type yet. It merely adds the `ArrayType`
instruction, as was done with the previous syntax.

Followup work will change the instruction to reference to Core.Array,
once the library type exists and can be used directly.

---------

Co-authored-by: zygoloid <richard@metafoo.co.uk>
2025-02-20 22:42:47 +00:00
Geoff RomerandJon Ross-Perkins 74e1a9949f Support tuple patterns outside parameter lists (#4923)
Parameter lists need substantially different treatment than tuple
patterns in other contexts, so this change splits them into separate
parse node kinds.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-02-20 03:17:45 +00:00
Geoff Romer 943acf1ec2 Separate node kind for bindings inside var (#4822)
This is a step toward making binding pattern handling more robust, by
removing its reliance on the node stack for context.
2025-01-21 20:15:19 +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
David BlaikieandJon Ross-Perkins e6c1f0630a Add a newline after diagnostic output when testing (#4818)
This removes some churn when adding new diagnostic cases to test files
(where previous to this change the newly added newline would cause the
previous diagnostic CHECKs to be updated including changes to the line
number because the CHECK for the blank line meant an extra line between
CHECK and source line).

A few alternatives discussed here:
https://discord.com/channels/655572317891461132/655578254970716160/1329573358475673723

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-01-16 23:23:57 +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
Jon Ross-Perkins dd43bb92b5 Refactor struct literal parse nodes. (#4470)
Split StructComma into StructLiteralComma and StructTypeLiteralComma in
order to easily differentiate handling (remains the same in this PR).

Add "Literal" to StructField and StructTypeField because it feels
inconsistent versus the other non-shared things. StructFieldDesignator
remains shared between value literals and type literals.

Note I probably would've made StructFieldDesignator non-shared too, but
that'd require either a lookahead of 2 (to see the separator`) or a
writeback after parsing the separator, neither of which felt especially
crucial for this, when what I'm really trying to do is split type
literal handling a little further.
2024-11-04 16:06:57 +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
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
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
josh11bandJosh L 7611aac355 Clarify what was missing in binding pattern errors (#4314)
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-09-14 03:31:43 +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
Jon Ross-Perkins 83413479d7 Move some of the test information to TIP lines (#4007)
This has is a nice-to-have for me. Frequently I want to run a specific
test, and end up digging through output to be able to copy-paste the run
line. This uses TIP lines to inject the command into the file when using
AUTOUPDATE.

Note, one of the reasons I want this is because "bazel test
//toolchain/testing:file_test --test_output=all" has been regularly
exceeding bazel's output limit for me (workaround is either opening the
output file or specifying an obscure output limit flag), making it a
little harder for me to get the commands. However, frequently I'm adding
a file and want to iterate on it, so that's really the use case I have
in mind here.
2024-06-04 17:57:23 +00:00
Jon Ross-Perkins 37aa309c81 Add recovery tokens using AddToken to get correct parse tree sizes. (#3851)
The expected parse tree size is validated for valid parse trees, which
is possible even if lex encounters an error. In that case, we were
missing recovery tokens, resulting in a crash. AddToken should be the
only place we call `token_infos_.push_back`.
2024-04-04 16:03:54 +00:00
Jon Ross-Perkins b42612bcec Change tuple/paren expr parsing to use placeholders. (#3849)
I've been thinking about this since we decided to add placeholders in
the parse tree. This allows a clearer division of work in check
handling, where we were doing work for ExprOpenParen that's only
necessary for tuples (splitting/renaming handle_paren.cpp accordingly).
2024-04-03 18:31:16 +00:00
Jon Ross-Perkins b8ceb8dd8b Print a blank line after a diagnostic. (#3806)
The purpose of the newline is to make it clearer where a given
diagnostic begins and ends, particularly as the first message of a
diagnostic may not be the error.

This is a trivial code change, but ripples edits through test files.
2024-03-22 18:10:49 +00:00
Jon Ross-Perkins 03347793cc Switch VariableInitializer order to accommodate GlobalInit (#3708)
This undoes parts of #3515 in order to allow PushGlobalInit to be called
when the initializer is called, instead of at the end of the binding
pattern. The current approach is fragile because supported patterns will
become more complex. We also will likely want similar support in `let`,
which puts the initializer first, so this offers a consistent approach
for both.

[Looking
back](https://discord.com/channels/655572317891461132/655578254970716160/1184237511766179840),
this is more or less the second option in that message, but using the
PeekNextIs to avoid vagueness about what's being popped first.

Note I'm putting in PeekNextIs for what I'm hoping will be a pretty
narrow use-case. I could've added depth arguments to the Peek functions,
but that would've rippled through a number of APIs and it's not clear to
me that this has generic utility. I mean, right now it could just be
PeekNextIsVariableInitializer, since it's only optional in that case.
2024-02-21 22:03:32 +00:00
Geoff RomerandRichard Smith 927d633762 Simplify handling of VariableInitializer (#3515)
Also stop supporting `var` with initializer inside `for`.

Resolves TODO in `handle_variable.cpp`

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2024-01-05 17:58:22 +00:00
josh11bandJon Ross-Perkins 6067ca3f49 Change return of SkipPastLikelyEnd to be last consumed token (#3493)
This approach means the parse subtree includes the full token range
consumed.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-11 22:11:09 +00:00
Geoff RomerandRichard Smith 6e65a30b5d Rename ParamList to TuplePattern (#3479)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-12-08 23:35:47 +00:00
Geoff Romer 5897e57c21 Clarify naming around paren expressions (#3444)
(Split out of #3410)

Consistently use `ParenExpr` solely for parenthesized single
expressions, and use more syntax-oriented terminology for states and
nodes that might represent either a `ParenExpr` or a tuple literal.
2023-12-08 21:46:28 +00:00
Geoff RomerandRichard Smith 39750b9925 Parse support for tuple patterns in var and let (#3448)
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2023-12-08 01:16:03 +00:00
Richard Smith fe6f7b4330 Rename Name -> IdentifierName given that we have several other kinds of parse nodes that represent names. (#3453)
Factor out common checking handling for the different kinds of
unqualified names
2023-12-07 01:48:14 +00:00
Jon Ross-Perkins d73729179a Switch modifiers to use distinct parse nodes. (#3461)
This is supporting a direction that all parse nodes should correspond to
a single token, allowing for reduced tokenized buffer access during
checking (it's still necessary for diagnostics, and some literals).

One of the justifications for a unified parse node was implementation
LOC: note this is slightly smaller, using macros to reduce some
duplication. While this does add more switching in HandleDeclScopeLoop,
that's offset by less explicit switching in the check handlers. Also, I
think the duplication in HandleDeclScopeLoop can be reduced by shifting
the flow there, which I'll do in a separate PR.
2023-12-06 22:14:53 +00:00
josh11bandJon Ross-Perkins fada410559 Support declaration modifier keywords (#3412)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-12-05 22:45:57 +00:00
Geoff Romer b8d4e2f41b Binding pattern naming cleanup (#3410)
- Rename `PatternBinding` to `BindingPattern`.
- Use `BindingPattern` rather than `Pattern` in the names of
binding-pattern-specific parse states.
2023-12-01 21:36:51 +00:00
Jon Ross-Perkins 0db63ff17a Abbreviate Integer and FloatingPoint (#3435)
I was suggesting this because `FloatingPoint` is pretty long. `int` and
`float` should be familiar abbreviations. `unsigned` should be familiar
to developers too, but `UnsignedInt` still feels usefully clearer for
the additional chars.
2023-11-29 23:29:48 +00:00
Jon Ross-Perkins 161f46ed37 FloatingPointLiteral to RealLiteral fixup (#3430) 2023-11-29 17:00:03 +00:00
Jacob Schneider 1d443a3617 Underline the entire token when producing diagnostic messages. (#3413)
This is an incremental improvement on our diagnostic messages that
simply underlines an entire token if the token is larger than 1 char
(else it points to the single char with a caret like it used to).
2023-11-27 16:36:26 +00:00
Jon Ross-Perkins a204689893 Use more specific node kinds for literals. (#3419)
Sounding out the approach, to make it clearer what a literal node
corresponds to.
2023-11-22 01:27:28 +00:00
josh11bandJon Ross-Perkins c53b248800 Abbreviate "parameter" -> "param" (#3392)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2023-11-13 19:06:54 +00:00
josh11b 5020fdb3be Use abbreviation "decl" instead of "declaration" (#3382)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.
2023-11-10 10:43:25 +00:00
josh11b 11ca083855 Use abbreviation "expr" instead of "expression" (#3375)
Part of switching to the [abbreviations we've decided to
use](https://docs.google.com/document/d/1RRYMm42osyqhI2LyjrjockYCutQ5dOf8Abu50kTrkX0/edit?resourcekey=0-kHyqOESbOHmzZphUbtLrTw#heading=h.pph7i5m5un7q).

I will rename files in a follow-up PR.
2023-11-10 01:32:32 +00:00
Chandler Carruth a46ca6bf7a Add a start-of-file token and parse node. (#3263)
This removes a (very) hot branch in the lexer where we need to special
case when a token is the first token and can't look at its previous
token. It also seems like a generally nice change to the structure of
both the token buffer and parse tree as there are now bracketing
elements for both ends and we should be able to avoid similar branching
in the future.

Mostly mechanical updates to the lexer and parser code to handle this,
but also needed to special case the location information in the
autoupdate code. And then the usual large body of auto-updated tests.

No benchmark data for this change alone as in isolation and in the
current lexer structure it doesn't make a big difference. But this
branch was particularly difficult to handle when trying to update the
whitespace skipping code to be faster, and so I think it is worth
systematically avoiding the special case here.
2023-10-04 23:36:35 +00:00
Geoff Romer 7899154a21 Add "ERROR" to all error diagnostics (#3251)
This makes the difference between errors and lower-level diagnostics
visible to users, and aligns the toolchain's behavior with the
expectations in `driver_fuzzer.cpp`.
2023-09-26 16:52:49 +00:00
Jon Ross-Perkins ec9d73e471 When there are split files, put unattached stdout at the end of the last file. (#3234)
This is consistent with the goal of trying to push unattached stdout to
the bottom of the test file. The current logic had a single file in
mind, and was not adapted for split file logic.

Addresses
https://github.com/carbon-language/carbon-lang/pull/3217#discussion_r1323584624

Note this depends on #3233
2023-09-15 21:56:42 +00:00
Jon Ross-Perkins 0b340a2ed2 Update parse tree yaml for multi-file. (#3215)
Building on #3214, updates parse tree yaml to be:

```
- filename: name
  parse_tree: [ ... ]
```
2023-09-13 16:35:15 +00:00
Jon Ross-Perkins 87d4c2dfc6 Improve testing and handling of unsigned APInt values (#3202) 2023-09-07 18:53:38 +00:00
Jon Ross-Perkins c555b39a2c Rename parser dir to parse (#3178)
Continuing with #3070. Just a dir and file rename (mostly removing
prefixes, although for parse_tree_fuzzer and parse_tree_file_test I'm
dropping "tree" instead of "parse"). Everything in the parse dir should
be marked as a move.
2023-09-01 01:35:45 +00:00