mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Replace :! binding syntax with phase keywords and contextual defaults (#7479)
Implement the toolchain side of proposal #7254, removing the `:!` binding syntax for generic and template parameters in favor of the keywords `generic`, `template`, and `runtime` plus contextual defaults for phase. For valid programs this is semantics-preserving: each binding resolves to the same phase, and produces the same SemIR, as it did under `:!`/`:`. The parser derives a binding's phase from its syntactic context plus any explicit phase keyword; new diagnostics and error recovery for misused keywords are described below. Implementation details for each component: - Lexer: remove the `:!` (`ColonExclaim`) token, move its virtual parse-node budget onto `:`, and add the `generic` and `runtime` keywords. - Parser: thread a `BindingContext` (`ExplicitParam`, `DeducedParam`, or `CompileTimeEntityParam`) from declaration introducers down through parameter lists to each binding pattern, using a one-token lookahead to distinguish a name-qualifier parameter list from a declaration's own final list. Parameters of a compile-time entity (`class`, `interface`, `constraint`, `choice`, `alias`, `export`, `namespace`) and deduced `[]` parameters default to checked generic; explicit function parameters and local bindings default to runtime. `HandleBindingPattern` resolves the phase from that context plus the keyword: a `generic` keyword needs no node of its own (the phase is carried by the binding's node kind), while a `runtime` keyword is preserved as a `RuntimeBindingName` node so `check` can name it in a diagnostic. A phase keyword that is merely redundant with the contextual default is diagnosed here, without invalidating the parse tree. - Check: a phase keyword that is invalid for its context (for example `runtime` on a checked-generic parameter) is diagnosed here, and recovers by building an error binding that still introduces the name so that later uses of it do not produce cascading errors. The removed `:!` syntax is now rejected as an ordinary parse error. The `form`/`:?`/`->?` ("extended types") portion of proposal #7254 is left for a separate change. Assisted-by: Claude Code
This commit is contained in:
@@ -14,33 +14,33 @@
|
||||
|
||||
interface NotGeneric;
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE+7]]:1: error: redeclaration differs because of parameter list [RedeclParamListDiffers]
|
||||
// CHECK:STDERR: interface NotGeneric(T:! type) {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: interface NotGeneric(T: type) {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE-4]]:1: note: previously declared without parameter list [RedeclParamListPrevious]
|
||||
// CHECK:STDERR: interface NotGeneric;
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
interface NotGeneric(T:! type) {}
|
||||
interface NotGeneric(T: type) {}
|
||||
|
||||
interface Generic(T:! type);
|
||||
interface Generic(T: type);
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE+7]]:1: error: redeclaration differs because of missing parameter list [RedeclParamListDiffers]
|
||||
// CHECK:STDERR: interface Generic {}
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE-4]]:1: note: previously declared with parameter list [RedeclParamListPrevious]
|
||||
// CHECK:STDERR: interface Generic(T:! type);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: interface Generic(T: type);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
interface Generic {}
|
||||
|
||||
interface DifferentParams(T:! type);
|
||||
interface DifferentParams(T: type);
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE+7]]:27: error: type `<pattern for ()>` of parameter 1 in redeclaration differs from previous parameter type `<pattern for type>` [RedeclParamDiffersType]
|
||||
// CHECK:STDERR: interface DifferentParams(T:! ()) {}
|
||||
// CHECK:STDERR: ^~~~~~
|
||||
// CHECK:STDERR: interface DifferentParams(T: ()) {}
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR: fail_generic_redeclaration.carbon:[[@LINE-4]]:27: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
||||
// CHECK:STDERR: interface DifferentParams(T:! type);
|
||||
// CHECK:STDERR: ^~~~~~~~
|
||||
// CHECK:STDERR: interface DifferentParams(T: type);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
interface DifferentParams(T:! ()) {}
|
||||
interface DifferentParams(T: ()) {}
|
||||
|
||||
// CHECK:STDOUT: --- fail_generic_redeclaration.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -82,18 +82,18 @@ interface DifferentParams(T:! ()) {}
|
||||
// CHECK:STDOUT: %NotGeneric.decl.loc23: %NotGeneric.type.fec = interface_decl @NotGeneric.loc23 [concrete = constants.%NotGeneric.generic] {
|
||||
// CHECK:STDOUT: %T.patt.loc23_23.1: %pattern_type.98f = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc23_23.2 (constants.%T.patt.d47)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc23_26.1: type = splice_block %.loc23_26.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.loc23_25.1: type = splice_block %.loc23_25.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %.loc23_26.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: %.loc23_25.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc23_23.2: type = symbolic_binding T, 0 [symbolic = %T.loc23_23.1 (constants.%T.67d)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Generic.decl.loc25: %Generic.type.30d = interface_decl @Generic.loc25 [concrete = constants.%Generic.generic] {
|
||||
// CHECK:STDOUT: %T.patt.loc25_20.1: %pattern_type.98f = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc25_20.2 (constants.%T.patt.d47)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc25_23.1: type = splice_block %.loc25_23.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.loc25_22.1: type = splice_block %.loc25_22.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %.loc25_23.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: %.loc25_22.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc25_20.2: type = symbolic_binding T, 0 [symbolic = %T.loc25_20.1 (constants.%T.67d)]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -101,19 +101,19 @@ interface DifferentParams(T:! ()) {}
|
||||
// CHECK:STDOUT: %DifferentParams.decl.loc35: %DifferentParams.type.998819.1 = interface_decl @DifferentParams.loc35 [concrete = constants.%DifferentParams.generic.54c122.1] {
|
||||
// CHECK:STDOUT: %T.patt.loc35_28.1: %pattern_type.98f = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc35_28.2 (constants.%T.patt.d47)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc35_31.1: type = splice_block %.loc35_31.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.loc35_30.1: type = splice_block %.loc35_30.2 [concrete = type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %.loc35_31.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: %.loc35_30.2: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc35_28.2: type = symbolic_binding T, 0 [symbolic = %T.loc35_28.1 (constants.%T.67d)]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %DifferentParams.decl.loc43: %DifferentParams.type.998819.2 = interface_decl @DifferentParams.loc43 [concrete = constants.%DifferentParams.generic.54c122.2] {
|
||||
// CHECK:STDOUT: %T.patt.loc43_28.1: %pattern_type.cb1 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc43_28.2 (constants.%T.patt.8f8)]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc43_32.1: type = splice_block %.loc43_32.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.loc43_31.1: type = splice_block %.loc43_31.3 [concrete = constants.%empty_tuple.type] {
|
||||
// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
|
||||
// CHECK:STDOUT: %.loc43_32.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc43_32.3: type = converted %.loc43_32.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc43_31.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc43_31.3: type = converted %.loc43_31.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %T.loc43_28.2: %empty_tuple.type = symbolic_binding T, 0 [symbolic = %T.loc43_28.1 (constants.%T.d5f)]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -127,14 +127,14 @@ interface DifferentParams(T:! ()) {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %NotGeneric.type: type = facet_type <@NotGeneric.loc23, @NotGeneric.loc23(%T.loc23_23.1)> [symbolic = %NotGeneric.type (constants.%NotGeneric.type.e75)]
|
||||
// CHECK:STDOUT: %Self.loc23_32.2: @NotGeneric.loc23.%NotGeneric.type (%NotGeneric.type.e75) = symbolic_binding Self, 1 [symbolic = %Self.loc23_32.2 (constants.%Self.b8f)]
|
||||
// CHECK:STDOUT: %Self.loc23_31.2: @NotGeneric.loc23.%NotGeneric.type (%NotGeneric.type.e75) = symbolic_binding Self, 1 [symbolic = %Self.loc23_31.2 (constants.%Self.b8f)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: %Self.loc23_32.1: @NotGeneric.loc23.%NotGeneric.type (%NotGeneric.type.e75) = symbolic_binding Self, 1 [symbolic = %Self.loc23_32.2 (constants.%Self.b8f)]
|
||||
// CHECK:STDOUT: %Self.loc23_31.1: @NotGeneric.loc23.%NotGeneric.type (%NotGeneric.type.e75) = symbolic_binding Self, 1 [symbolic = %Self.loc23_31.2 (constants.%Self.b8f)]
|
||||
// CHECK:STDOUT: %NotGeneric.WithSelf.decl = interface_with_self_decl @NotGeneric.loc23 [concrete]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = %Self.loc23_32.1
|
||||
// CHECK:STDOUT: .Self = %Self.loc23_31.1
|
||||
// CHECK:STDOUT: witness = ()
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !requires:
|
||||
@@ -176,14 +176,14 @@ interface DifferentParams(T:! ()) {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %DifferentParams.type: type = facet_type <@DifferentParams.loc43, @DifferentParams.loc43(%T.loc43_28.1)> [symbolic = %DifferentParams.type (constants.%DifferentParams.type.7d4)]
|
||||
// CHECK:STDOUT: %Self.loc43_35.2: @DifferentParams.loc43.%DifferentParams.type (%DifferentParams.type.7d4) = symbolic_binding Self, 1 [symbolic = %Self.loc43_35.2 (constants.%Self.a37)]
|
||||
// CHECK:STDOUT: %Self.loc43_34.2: @DifferentParams.loc43.%DifferentParams.type (%DifferentParams.type.7d4) = symbolic_binding Self, 1 [symbolic = %Self.loc43_34.2 (constants.%Self.a37)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: %Self.loc43_35.1: @DifferentParams.loc43.%DifferentParams.type (%DifferentParams.type.7d4) = symbolic_binding Self, 1 [symbolic = %Self.loc43_35.2 (constants.%Self.a37)]
|
||||
// CHECK:STDOUT: %Self.loc43_34.1: @DifferentParams.loc43.%DifferentParams.type (%DifferentParams.type.7d4) = symbolic_binding Self, 1 [symbolic = %Self.loc43_34.2 (constants.%Self.a37)]
|
||||
// CHECK:STDOUT: %DifferentParams.WithSelf.decl = interface_with_self_decl @DifferentParams.loc43 [concrete]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = %Self.loc43_35.1
|
||||
// CHECK:STDOUT: .Self = %Self.loc43_34.1
|
||||
// CHECK:STDOUT: witness = ()
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !requires:
|
||||
|
||||
Reference in New Issue
Block a user