diff --git a/toolchain/check/testdata/where_expr/designator.carbon b/toolchain/check/testdata/where_expr/designator.carbon index 79db1d8f6199..6738ec521a9f 100644 --- a/toolchain/check/testdata/where_expr/designator.carbon +++ b/toolchain/check/testdata/where_expr/designator.carbon @@ -427,15 +427,7 @@ class C(T: type); // CHECK:STDERR: alias A(U: type) = C(U); -// CHECK:STDERR: fail_todo_generic_alias_preserves_self.carbon:[[@LINE+8]]:15: error: expected expression [ExpectedExpr] -// CHECK:STDERR: fn F(unused T:! I where C == A(.Self)) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_todo_generic_alias_preserves_self.carbon:[[@LINE+4]]:15: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] -// CHECK:STDERR: fn F(unused T:! I where C == A(.Self)) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn F(unused T:! I where C == A(.Self)) {} +fn F(unused T: I where C == A(.Self)) {} // --- fail_generic_alias_without_self.carbon library "[[@TEST_NAME]]"; @@ -453,15 +445,7 @@ alias A(U: type) = C; // TODO: Once we can write a generic alias, this should become an error because // there is no constraint against `.Self`. -// CHECK:STDERR: fail_generic_alias_without_self.carbon:[[@LINE+8]]:15: error: expected expression [ExpectedExpr] -// CHECK:STDERR: fn F(unused T:! I where C == A(.Self)) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -// CHECK:STDERR: fail_generic_alias_without_self.carbon:[[@LINE+4]]:15: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] -// CHECK:STDERR: fn F(unused T:! I where C == A(.Self)) {} -// CHECK:STDERR: ^ -// CHECK:STDERR: -fn F(unused T:! I where C == A(.Self)) {} +fn F(unused T: I where C == A(.Self)) {} // CHECK:STDOUT: --- success.carbon // CHECK:STDOUT: diff --git a/toolchain/docs/check/README.md b/toolchain/docs/check/README.md index 959a6eef6bad..57c576ad65d2 100644 --- a/toolchain/docs/check/README.md +++ b/toolchain/docs/check/README.md @@ -284,7 +284,7 @@ you would look for a `struct` definition that uses `"assoc_const_decl"` as its `ir_name`. In this case, this is the `AssociatedConstantDecl` instruction: ```cpp -// An associated constant declaration in an interface, such as `let T:! type;`. +// An associated constant declaration in an interface, such as `let T: type;`. struct AssociatedConstantDecl { static constexpr auto Kind = InstKind::AssociatedConstantDecl.Define( @@ -300,7 +300,7 @@ corresponds to the type written between the `:` and the `=`. In the example above, that type is `i32`. The other arguments to the instruction are written after the `ir_name` -- in this example the `name_id` is `N`. From this we find that the instruction corresponds to an associated constant declaration in an -interface like `let N:! i32;`. +interface like `let N: i32;`. In fact, the notation after the `:` records not just the instruction's type, but also some information about its category, and the storage argument if it's an diff --git a/toolchain/docs/check/pattern_matching.md b/toolchain/docs/check/pattern_matching.md index 9a321ad9411a..4d5863b144dd 100644 --- a/toolchain/docs/check/pattern_matching.md +++ b/toolchain/docs/check/pattern_matching.md @@ -288,7 +288,7 @@ enum by having separate node kinds `IdentifierNameMaybeBeforeSignature` and `IdentifierNameNotBeforeSignature`. If the parameterized name is a name qualifier (such as the first part of -`Foo(X:! i32).Bar(y: i32)`), the node immediately after it will be the qualifier +`Foo(X: i32).Bar(y: i32)`), the node immediately after it will be the qualifier node. As of this writing, we bifurcate qualifier nodes into `NameQualifierWithParams` and `NameQualifierWithoutParams`, much like we do with identifier names, but we don't actually use that information, and instead use @@ -320,7 +320,7 @@ arguments and parameters). For example, consider this function: ```carbon -fn F(T:! type, U:! type) -> Core.String; +fn F(T: type, U: type) -> Core.String; ``` The `Call` instruction is a runtime-phase operation, so it notionally runs after diff --git a/toolchain/lex/testdata/fail_mismatched_brackets.carbon b/toolchain/lex/testdata/fail_mismatched_brackets.carbon index 80674022ef5a..f5a93f61bb16 100644 --- a/toolchain/lex/testdata/fail_mismatched_brackets.carbon +++ b/toolchain/lex/testdata/fail_mismatched_brackets.carbon @@ -402,28 +402,27 @@ fn F() { // As above for `forall`, which wants a `[` rather than a `(`. -// CHECK:STDERR: fail_missing_open_square_after_forall.carbon:[[@LINE+7]]:21: error: closing symbol without a corresponding opening symbol [UnmatchedClosing] -// CHECK:STDERR: impl forall T:! type] X as Y { -// CHECK:STDERR: ^ +// CHECK:STDERR: fail_missing_open_square_after_forall.carbon:[[@LINE+7]]:20: error: closing symbol without a corresponding opening symbol [UnmatchedClosing] +// CHECK:STDERR: impl forall T: type] X as Y { +// CHECK:STDERR: ^ // CHECK:STDERR: fail_missing_open_square_after_forall.carbon:[[@LINE+4]]:13: note: possibly missing `[` here [PossiblyMissingBracketHere] -// CHECK:STDERR: impl forall T:! type] X as Y { +// CHECK:STDERR: impl forall T: type] X as Y { // CHECK:STDERR: ^ // CHECK:STDERR: -impl forall T:! type] X as Y { +impl forall T: type] X as Y { // CHECK:STDOUT: - { index: 1, kind: "Impl", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "impl", has_leading_space: true } // CHECK:STDOUT: - { index: 2, kind: "Forall", line: {{ *}}[[@LINE-2]], column: 6, indent: 1, spelling: "forall", has_leading_space: true } -// CHECK:STDOUT: - { index: 3, kind: "OpenSquareBracket", line: {{ *}}[[@LINE-3]], column: 12, indent: 1, spelling: "[", closing_token: 8, has_leading_space: true, recovery: true } +// CHECK:STDOUT: - { index: 3, kind: "OpenSquareBracket", line: {{ *}}[[@LINE-3]], column: 12, indent: 1, spelling: "[", closing_token: 7, has_leading_space: true, recovery: true } // CHECK:STDOUT: - { index: 4, kind: "Identifier", line: {{ *}}[[@LINE-4]], column: 13, indent: 1, spelling: "T", identifier: 0 } // CHECK:STDOUT: - { index: 5, kind: "Colon", line: {{ *}}[[@LINE-5]], column: 14, indent: 1, spelling: ":" } -// CHECK:STDOUT: - { index: 6, kind: "Exclaim", line: {{ *}}[[@LINE-6]], column: 15, indent: 1, spelling: "!" } -// CHECK:STDOUT: - { index: 7, kind: "Type", line: {{ *}}[[@LINE-7]], column: 17, indent: 1, spelling: "type", has_leading_space: true } -// CHECK:STDOUT: - { index: 8, kind: "CloseSquareBracket", line: {{ *}}[[@LINE-8]], column: 21, indent: 1, spelling: "]", opening_token: 3 } -// CHECK:STDOUT: - { index: 9, kind: "Identifier", line: {{ *}}[[@LINE-9]], column: 23, indent: 1, spelling: "X", identifier: 1, has_leading_space: true } -// CHECK:STDOUT: - { index: 10, kind: "As", line: {{ *}}[[@LINE-10]], column: 25, indent: 1, spelling: "as", has_leading_space: true } -// CHECK:STDOUT: - { index: 11, kind: "Identifier", line: {{ *}}[[@LINE-11]], column: 28, indent: 1, spelling: "Y", identifier: 2, has_leading_space: true } -// CHECK:STDOUT: - { index: 12, kind: "OpenCurlyBrace", line: {{ *}}[[@LINE-12]], column: 30, indent: 1, spelling: "{", closing_token: 13, has_leading_space: true } +// CHECK:STDOUT: - { index: 6, kind: "Type", line: {{ *}}[[@LINE-6]], column: 16, indent: 1, spelling: "type", has_leading_space: true } +// CHECK:STDOUT: - { index: 7, kind: "CloseSquareBracket", line: {{ *}}[[@LINE-7]], column: 20, indent: 1, spelling: "]", opening_token: 3 } +// CHECK:STDOUT: - { index: 8, kind: "Identifier", line: {{ *}}[[@LINE-8]], column: 22, indent: 1, spelling: "X", identifier: 1, has_leading_space: true } +// CHECK:STDOUT: - { index: 9, kind: "As", line: {{ *}}[[@LINE-9]], column: 24, indent: 1, spelling: "as", has_leading_space: true } +// CHECK:STDOUT: - { index: 10, kind: "Identifier", line: {{ *}}[[@LINE-10]], column: 27, indent: 1, spelling: "Y", identifier: 2, has_leading_space: true } +// CHECK:STDOUT: - { index: 11, kind: "OpenCurlyBrace", line: {{ *}}[[@LINE-11]], column: 29, indent: 1, spelling: "{", closing_token: 12, has_leading_space: true } } -// CHECK:STDOUT: - { index: 13, kind: "CloseCurlyBrace", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "}", opening_token: 12, has_leading_space: true } +// CHECK:STDOUT: - { index: 12, kind: "CloseCurlyBrace", line: {{ *}}[[@LINE-1]], column: 1, indent: 1, spelling: "}", opening_token: 11, has_leading_space: true } // --- fail_missing_brace_after_if.carbon // CHECK:STDOUT: - filename: fail_missing_brace_after_if.carbon diff --git a/toolchain/parse/handle_binding_pattern.cpp b/toolchain/parse/handle_binding_pattern.cpp index a5ef270811ed..73c9cd14a2f3 100644 --- a/toolchain/parse/handle_binding_pattern.cpp +++ b/toolchain/parse/handle_binding_pattern.cpp @@ -196,6 +196,9 @@ auto HandleBindingPattern(Context& context) -> void { // the default would otherwise be generic) is reported by `check` as a // misplaced `self` — the relevant error — rather than also producing a // `ref`-on-generic error from that default. + // + // TODO: This is wrong: it rejects `fn F(template self: Self)` and treats + // `fn F(generic self: Self)` as being non-generic. if (self_token) { resolved_generic = false; } diff --git a/toolchain/parse/state.def b/toolchain/parse/state.def index 31d49121b33c..85d8a67374c0 100644 --- a/toolchain/parse/state.def +++ b/toolchain/parse/state.def @@ -1323,7 +1323,7 @@ CARBON_PARSE_STATE(ParenExprFinish) // ^ // 1. UnusedPattern // -// [identifier|self] [:|:!|:?] +// [identifier|self] [:|:?] // ^ // template <...> // ^ @@ -1350,21 +1350,31 @@ CARBON_PARSE_STATE(ExprPattern) // TODO: treat `ref` as a unary pattern operator in order to avoid ambiguity // with `ref` in expression patterns. See issue #6342. // -// [ref] name: <...> -// ^~~~~~~~~~~ -// [ref] self: <...> -// ^~~~~~~~~~~ -// [ref] _: <...> -// ^~~~~~~~ +// name: <...> (not contextually a generic parameter) +// ^~~~~ +// _: <...> (not contextually a generic parameter) +// ^~ +// ref name: <...> (not contextually a generic parameter) +// ^~~~~~~~~ +// ref _: <...> (not contextually a generic parameter) +// ^~~~~~ +// runtime [ref] name: <...> +// ^~~~~~~~~~~~~~~~~~~ +// runtime [ref] _: <...> +// ^~~~~~~~~~~~~~~~ +// [runtime] [ref] self: <...> +// ^~~~~~~~~~~~~~~~~~~~~ // 1. Expr // 2. BindingPatternFinishAsRegular // -// [template] name:! <...> -// ^~~~~~~~~~~~~~~~~ -// [template] self:! <...> -// ^~~~~~~~~~~~~~~~~ -// [template] _:! <...> -// ^~~~~~~~~~~~~~ +// name: <...> (contextually a generic parameter) +// ^~~~~ +// _: <...> (contextually a generic parameter) +// ^~ +// template/generic name: <...> +// ^~~~~~~~~~~~~~~~~~~~~~ +// template/generic _: <...> +// ^~~~~~~~~~~~~~~~~~~ // 1. Expr // 2. BindingPatternFinishAsGeneric // @@ -1377,6 +1387,10 @@ CARBON_PARSE_STATE(ExprPattern) // 1. Expr // 2. BindingPatternFinishAsForm // +// [ref] self (not followed by `:` or `:?`) +// ^~~~~~~~~~ +// 1. (state done) +// // // ^ // 1. BindingPatternFinishAsRegular