mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 20:20:10 +01:00
Handle parsing of require...impls declarations (#6255)
Check is not implemented yet, but some tests are added.
This commit is contained in:
@@ -54,7 +54,7 @@ auto HandleParseNode(Context& context, Parse::ForallId /*node_id*/) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::TypeImplAsId node_id) -> bool {
|
||||
auto HandleParseNode(Context& context, Parse::ImplTypeAsId node_id) -> bool {
|
||||
auto [self_node, self_id] = context.node_stack().PopExprWithNodeId();
|
||||
auto self_type_inst_id = ExprAsType(context, self_node, self_id).inst_id;
|
||||
context.node_stack().Push(node_id, self_type_inst_id);
|
||||
@@ -67,7 +67,7 @@ auto HandleParseNode(Context& context, Parse::TypeImplAsId node_id) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::DefaultSelfImplAsId node_id)
|
||||
auto HandleParseNode(Context& context, Parse::ImplDefaultSelfAsId node_id)
|
||||
-> bool {
|
||||
auto self_inst_id = SemIR::TypeInstId::None;
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/handle.h"
|
||||
#include "toolchain/parse/node_ids.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::RequireIntroducerId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "require");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::RequireDefaultSelfImplsId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "require");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::RequireTypeImplsId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "require");
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::RequireDeclId node_id) -> bool {
|
||||
return context.TODO(node_id, "require");
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -433,7 +433,7 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
|
||||
const auto& impl = context.impls().Get(impl_id);
|
||||
|
||||
if (context.parse_tree().node_kind(self_type_node_id) ==
|
||||
Parse::NodeKind::TypeImplAs) {
|
||||
Parse::NodeKind::ImplTypeAs) {
|
||||
CARBON_DIAGNOSTIC(ExtendImplSelfAs, Error,
|
||||
"cannot `extend` an `impl` with an explicit self type");
|
||||
auto diag = context.emitter().Build(extend_node, ExtendImplSelfAs);
|
||||
@@ -448,7 +448,7 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
|
||||
// The explicit self type is the same as the default self type, so suggest
|
||||
// removing it and recover as if it were not present.
|
||||
if (auto self_as =
|
||||
context.parse_tree_and_subtrees().ExtractAs<Parse::TypeImplAs>(
|
||||
context.parse_tree_and_subtrees().ExtractAs<Parse::ImplTypeAs>(
|
||||
self_type_node_id)) {
|
||||
CARBON_DIAGNOSTIC(ExtendImplSelfAsDefault, Note,
|
||||
"remove the explicit `Self` type here");
|
||||
|
||||
@@ -461,17 +461,17 @@ static auto CheckRedeclParamSyntax(Context& context,
|
||||
// https://github.com/carbon-language/carbon-lang/blob/trunk/proposals/p3763.md#redeclarations
|
||||
auto new_node_kind = context.parse_tree().node_kind(new_node_id);
|
||||
auto prev_node_kind = context.parse_tree().node_kind(prev_node_id);
|
||||
if (new_node_kind == Parse::NodeKind::DefaultSelfImplAs &&
|
||||
if (new_node_kind == Parse::NodeKind::ImplDefaultSelfAs &&
|
||||
prev_node_kind == Parse::NodeKind::SelfTypeNameExpr &&
|
||||
context.parse_tree().node_kind(prev_iter[1]) ==
|
||||
Parse::NodeKind::TypeImplAs) {
|
||||
Parse::NodeKind::ImplTypeAs) {
|
||||
++prev_iter;
|
||||
continue;
|
||||
}
|
||||
if (prev_node_kind == Parse::NodeKind::DefaultSelfImplAs &&
|
||||
if (prev_node_kind == Parse::NodeKind::ImplDefaultSelfAs &&
|
||||
new_node_kind == Parse::NodeKind::SelfTypeNameExpr &&
|
||||
context.parse_tree().node_kind(new_iter[1]) ==
|
||||
Parse::NodeKind::TypeImplAs) {
|
||||
Parse::NodeKind::ImplTypeAs) {
|
||||
++new_iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -523,6 +523,9 @@ class NodeStack {
|
||||
case Parse::NodeKind::ParenExprStart:
|
||||
case Parse::NodeKind::PatternListComma:
|
||||
case Parse::NodeKind::Placeholder:
|
||||
case Parse::NodeKind::RequireIntroducer:
|
||||
case Parse::NodeKind::RequireDefaultSelfImpls:
|
||||
case Parse::NodeKind::RequireTypeImpls:
|
||||
case Parse::NodeKind::RequirementAnd:
|
||||
case Parse::NodeKind::RequirementEqual:
|
||||
case Parse::NodeKind::RequirementEqualEqual:
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/facet/require_invalid.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/require_invalid.carbon
|
||||
|
||||
// --- fail_todo_require_outside_scope.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
// CHECK:STDERR: fail_todo_require_outside_scope.carbon:[[@LINE+4]]:1: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y;
|
||||
|
||||
// --- fail_todo_require_in_class.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
class C {
|
||||
// TODO: require is not allowed outside of `interface` or `constraint`.
|
||||
// CHECK:STDERR: fail_todo_require_in_class.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y;
|
||||
}
|
||||
|
||||
// --- fail_require_in_fn.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
fn F() {
|
||||
// require is not allowed outside of `interface` or `constraint`.
|
||||
// CHECK:STDERR: fail_require_in_fn.carbon:[[@LINE+8]]:3: error: expected expression [ExpectedExpr]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_require_in_fn.carbon:[[@LINE+4]]:3: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y;
|
||||
}
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/require.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/require.carbon
|
||||
|
||||
// --- fail_todo_implicit_self_impls.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_implicit_self_impls.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn F(T:! Z) {
|
||||
T.(Y.YY)();
|
||||
}
|
||||
|
||||
// --- fail_todo_explicit_self_impls.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_explicit_self_impls.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require Self impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require Self impls Y;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn F(T:! Z) {
|
||||
T.(Y.YY)();
|
||||
}
|
||||
|
||||
// --- fail_todo_implicit_self_no_extend_name_lookup_fails.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_implicit_self_no_extend_name_lookup_fails.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y;
|
||||
}
|
||||
|
||||
fn F(T:! Z) {
|
||||
// TODO: This should fail name lookup since Z does not extend Y.
|
||||
T.YY();
|
||||
}
|
||||
|
||||
// --- fail_todo_explicit_self_no_extend_name_lookup_fails.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_explicit_self_no_extend_name_lookup_fails.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require Self impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require Self impls Y;
|
||||
}
|
||||
|
||||
fn F(T:! Z) {
|
||||
// TODO: This should fail name lookup since Z does not extend Y.
|
||||
T.YY();
|
||||
}
|
||||
|
||||
// --- fail_todo_explicit_self_specific_impls.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
class C(T:! type);
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_explicit_self_specific_impls.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require C(Self) impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require C(Self) impls Y;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_impls_where.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y { let Y1:! type; }
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_impls_where.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Y where .Y1 = ();
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require impls Y where .Y1 = ();
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_other_impls_with_self.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z(T:! type) {
|
||||
// CHECK:STDERR: fail_todo_other_impls_with_self.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require T impls Z(Self);
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require T impls Z(Self);
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_other_impls_without_self.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z(T:! type) {
|
||||
// TODO: Either the type `T` or the facet type `Y` must mention `Self`, but
|
||||
// they don't.
|
||||
// CHECK:STDERR: fail_todo_other_impls_without_self.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require T impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
require T impls Y;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- fail_todo_extend.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_todo_extend.carbon:[[@LINE+4]]:10: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: extend require impls Y;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
extend require impls Y;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
fn F(T:! Z) {
|
||||
T.YY();
|
||||
T.(Y.YY)();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- fail_todo_implicit_self_impls.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Z {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst6000001D
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_explicit_self_impls.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Z {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst5000001D
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_explicit_self_specific_impls.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Z {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst68000023
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_impls_where.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Z {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst5800001A
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_other_impls_with_self.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic interface @Z(<unexpected>.inst78000017.loc6_13: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst78000021
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Z(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_other_impls_without_self.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generic interface @Z(<unexpected>.inst44000017.loc6_13: type) {
|
||||
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst44000021
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Z(constants.%T) {
|
||||
// CHECK:STDOUT: %T => constants.%T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_extend.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface @Z {
|
||||
// CHECK:STDOUT: !members:
|
||||
// CHECK:STDOUT: .Self = <unexpected>.inst6400001D
|
||||
// CHECK:STDOUT: witness = invalid
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -43,11 +43,7 @@ library "[[@TEST_NAME]]";
|
||||
interface Z {}
|
||||
|
||||
constraint E {
|
||||
// CHECK:STDERR: fail_todo_unspecified.carbon:[[@LINE+8]]:3: error: unrecognized declaration introducer [UnrecognizedDecl]
|
||||
// CHECK:STDERR: require impls Z;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_unspecified.carbon:[[@LINE+4]]:3: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_unspecified.carbon:[[@LINE+4]]:3: error: semantics TODO: `require` [SemanticsTodo]
|
||||
// CHECK:STDERR: require impls Z;
|
||||
// CHECK:STDERR: ^~~~~~~
|
||||
// CHECK:STDERR:
|
||||
|
||||
@@ -162,6 +162,7 @@ CARBON_DIAGNOSTIC_KIND(ImplExpectedAfterForall)
|
||||
CARBON_DIAGNOSTIC_KIND(ImplExpectedAs)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedAssociatedConstantIdentifier)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedAssociatedConstantColonExclaim)
|
||||
CARBON_DIAGNOSTIC_KIND(RequireExpectedImpls)
|
||||
|
||||
// Alias diagnostics.
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedAliasInitializer)
|
||||
|
||||
@@ -130,6 +130,8 @@ static constexpr auto DeclIntroducers = [] {
|
||||
StateKind::TypeAfterIntroducerAsInterface);
|
||||
set(Lex::TokenKind::Namespace, NodeKind::NamespaceStart,
|
||||
StateKind::Namespace);
|
||||
set(Lex::TokenKind::Require, NodeKind::RequireIntroducer,
|
||||
StateKind::RequireAfterIntroducer);
|
||||
set_contextual(Lex::TokenKind::Let, RegularContext, NodeKind::LetIntroducer,
|
||||
StateKind::Let);
|
||||
set_contextual(Lex::TokenKind::Let, ClassContext, NodeKind::LetIntroducer,
|
||||
@@ -225,6 +227,7 @@ static auto ResolveAmbiguousTokenAsDeclaration(Context& context,
|
||||
case Lex::TokenKind::Let:
|
||||
case Lex::TokenKind::Library:
|
||||
case Lex::TokenKind::Namespace:
|
||||
case Lex::TokenKind::Require:
|
||||
case Lex::TokenKind::Var:
|
||||
#define CARBON_PARSE_NODE_KIND(Name)
|
||||
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name) case Lex::TokenKind::Name:
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Carbon::Parse {
|
||||
static auto ExpectAsOrTypeExpression(Context& context) -> void {
|
||||
if (context.PositionIs(Lex::TokenKind::As)) {
|
||||
// as <expression> ...
|
||||
context.AddLeafNode(NodeKind::DefaultSelfImplAs, context.Consume());
|
||||
context.AddLeafNode(NodeKind::ImplDefaultSelfAs, context.Consume());
|
||||
context.PushState(StateKind::Expr);
|
||||
} else {
|
||||
// <expression> as <expression>...
|
||||
@@ -62,7 +62,7 @@ auto HandleImplAfterForall(Context& context) -> void {
|
||||
auto HandleImplBeforeAs(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
if (auto as = context.ConsumeIf(Lex::TokenKind::As)) {
|
||||
context.AddNode(NodeKind::TypeImplAs, *as, state.has_error);
|
||||
context.AddNode(NodeKind::ImplTypeAs, *as, state.has_error);
|
||||
context.PushState(StateKind::Expr);
|
||||
} else {
|
||||
if (!state.has_error) {
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "toolchain/parse/context.h"
|
||||
#include "toolchain/parse/handle.h"
|
||||
|
||||
namespace Carbon::Parse {
|
||||
|
||||
auto HandleRequireAfterIntroducer(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
state.kind = StateKind::RequireDecl;
|
||||
context.PushState(state);
|
||||
|
||||
if (context.PositionIs(Lex::TokenKind::Impls)) {
|
||||
// impls <expression> ...
|
||||
context.AddLeafNode(NodeKind::RequireDefaultSelfImpls, context.Consume());
|
||||
context.PushState(StateKind::Expr);
|
||||
} else {
|
||||
// <expression> impls <expression>...
|
||||
context.PushState(StateKind::RequireBeforeImpls);
|
||||
context.PushStateForExpr(PrecedenceGroup::ForRequirements());
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleRequireBeforeImpls(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
if (auto impls = context.ConsumeIf(Lex::TokenKind::Impls)) {
|
||||
context.AddNode(NodeKind::RequireTypeImpls, *impls, state.has_error);
|
||||
context.PushState(StateKind::Expr);
|
||||
} else {
|
||||
if (!state.has_error) {
|
||||
CARBON_DIAGNOSTIC(RequireExpectedImpls, Error,
|
||||
"expected `impls` in `require` declaration");
|
||||
context.emitter().Emit(*context.position(), RequireExpectedImpls);
|
||||
}
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleRequireDecl(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
context.AddNodeExpectingDeclSemi(state, NodeKind::RequireDecl,
|
||||
Lex::TokenKind::Require,
|
||||
/*is_def_allowed=*/false);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Parse
|
||||
@@ -15,18 +15,21 @@ namespace Carbon::Parse {
|
||||
// #define CARBON_NODE_CATEGORY_FOR_XYZ(Name) ...
|
||||
// CARBON_NODE_CATEGORY(CARBON_NODE_CATEGORY_FOR_XYZ)
|
||||
// #undef CARBON_NODE_CATEGORY_FOR_XYZ
|
||||
#define CARBON_NODE_CATEGORY(X) \
|
||||
X(Decl) \
|
||||
X(Expr) \
|
||||
X(ImplAs) \
|
||||
X(IntConst) \
|
||||
X(MemberExpr) \
|
||||
X(MemberName) \
|
||||
X(Modifier) \
|
||||
X(NonExprName) \
|
||||
X(PackageName) \
|
||||
X(Pattern) \
|
||||
X(Requirement) \
|
||||
#define CARBON_NODE_CATEGORY(X) \
|
||||
X(Decl) \
|
||||
X(Expr) \
|
||||
/* `impl <type> as` or just `impl as` */ \
|
||||
X(ImplAs) \
|
||||
X(IntConst) \
|
||||
X(MemberExpr) \
|
||||
X(MemberName) \
|
||||
X(Modifier) \
|
||||
X(NonExprName) \
|
||||
X(PackageName) \
|
||||
X(Pattern) \
|
||||
/* `require <type> impls` or just `require impls` */ \
|
||||
X(RequireImpls) \
|
||||
X(Requirement) \
|
||||
X(Statement)
|
||||
|
||||
// We expect this to grow, so are using a bigger size than needed.
|
||||
|
||||
@@ -108,6 +108,7 @@ using AnyModifierId = NodeIdInCategory<NodeCategory::Modifier>;
|
||||
using AnyPatternId = NodeIdInCategory<NodeCategory::Pattern>;
|
||||
using AnyStatementId =
|
||||
NodeIdInCategory<NodeCategory::Statement | NodeCategory::Decl>;
|
||||
using AnyRequireImplsId = NodeIdInCategory<NodeCategory::RequireImpls>;
|
||||
using AnyRequirementId = NodeIdInCategory<NodeCategory::Requirement>;
|
||||
using AnyNonExprNameId = NodeIdInCategory<NodeCategory::NonExprName>;
|
||||
using AnyPackageNameId = NodeIdInCategory<NodeCategory::PackageName>;
|
||||
|
||||
@@ -367,8 +367,13 @@ CARBON_PARSE_NODE_KIND(ImplDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND(ImplDefinition)
|
||||
CARBON_PARSE_NODE_KIND(ImplDecl)
|
||||
CARBON_PARSE_NODE_KIND(Forall)
|
||||
CARBON_PARSE_NODE_KIND(TypeImplAs)
|
||||
CARBON_PARSE_NODE_KIND(DefaultSelfImplAs)
|
||||
CARBON_PARSE_NODE_KIND(ImplTypeAs)
|
||||
CARBON_PARSE_NODE_KIND(ImplDefaultSelfAs)
|
||||
|
||||
CARBON_PARSE_NODE_KIND(RequireIntroducer)
|
||||
CARBON_PARSE_NODE_KIND(RequireTypeImpls)
|
||||
CARBON_PARSE_NODE_KIND(RequireDefaultSelfImpls)
|
||||
CARBON_PARSE_NODE_KIND(RequireDecl)
|
||||
|
||||
CARBON_PARSE_NODE_KIND(NamedConstraintIntroducer)
|
||||
CARBON_PARSE_NODE_KIND(NamedConstraintDefinitionStart)
|
||||
|
||||
@@ -58,6 +58,10 @@ class PrecedenceGroup {
|
||||
// `impl` and `as`.
|
||||
static auto ForImplAs() -> PrecedenceGroup;
|
||||
|
||||
// Get the precedence level at which to parse the type expression between
|
||||
// `require` and `impls`.
|
||||
static auto ForRequireImpls() -> PrecedenceGroup;
|
||||
|
||||
// Get the precedence level at which to parse expressions in requirements
|
||||
// after `where` or `require`.
|
||||
static auto ForRequirements() -> PrecedenceGroup;
|
||||
|
||||
@@ -359,6 +359,10 @@ CARBON_PARSE_STATE(DeclNameAndParamsAfterParams)
|
||||
// ^~~~~~~
|
||||
// 1. Package
|
||||
//
|
||||
// require ...
|
||||
// ^~~~~~~
|
||||
// 1. RequireAfterIntroducer
|
||||
//
|
||||
// var ... (variant is Regular)
|
||||
// ^~~
|
||||
// 1. VarAsRegular
|
||||
@@ -1336,7 +1340,7 @@ CARBON_PARSE_STATE(BaseDecl)
|
||||
// ^~
|
||||
// 1. Expr
|
||||
// 2. DeclOrDefinitionAsImpl
|
||||
// impl type_expression as ...
|
||||
// impl TypeExpression as ...
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. ImplBeforeAs
|
||||
@@ -1349,7 +1353,7 @@ CARBON_PARSE_STATE(ImplAfterIntroducer)
|
||||
// impl forall [ ... ] as ...
|
||||
// ^~
|
||||
// 1. Expr
|
||||
// impl forall [ ... ] type_expression as ...
|
||||
// impl forall [ ... ] TypeExpression as ...
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. ImplBeforeAs
|
||||
@@ -1363,6 +1367,34 @@ CARBON_PARSE_STATE(ImplAfterForall)
|
||||
// 1. Expr
|
||||
CARBON_PARSE_STATE(ImplBeforeAs)
|
||||
|
||||
// Handles processing of a `require...impls` declaration after the introducer.
|
||||
//
|
||||
// require impls ...
|
||||
// ^~~~~
|
||||
// 1. Expr
|
||||
// 2. RequireDecl
|
||||
// require TypeExpression impls ...
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. RequireBeforeImpls
|
||||
// 3. RequireDecl
|
||||
CARBON_PARSE_STATE(RequireAfterIntroducer)
|
||||
|
||||
// Handles processing of the `impls` in a `require` declaration after the type
|
||||
// expression.
|
||||
//
|
||||
// require TypeExpression impls ...
|
||||
// ^~~~~
|
||||
// 1. Expr
|
||||
CARBON_PARSE_STATE(RequireBeforeImpls)
|
||||
|
||||
// Handles processing of a completed `require` declaration.
|
||||
//
|
||||
// require TypeExpression impls FacetTypeExpression ;
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(RequireDecl)
|
||||
|
||||
// Handles the start of a `var` or `returned var` in a non-class context.
|
||||
//
|
||||
// var ... (variant is Regular)
|
||||
|
||||
+3
-3
@@ -86,14 +86,14 @@ fn F() {
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'A'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'FinalModifier', text: 'final'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'A'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 7},
|
||||
@@ -139,7 +139,7 @@ fn F() {
|
||||
// CHECK:STDOUT: {kind: 'BaseDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'ExtendModifier', text: 'extend'},
|
||||
// CHECK:STDOUT: {kind: 'DefaultSelfImplAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefaultSelfAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'NamespaceStart', text: 'namespace'},
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ fn TestRecoveryFromSpuriousEquals();
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ impl i32 as Interface {
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
|
||||
+5
-5
@@ -26,23 +26,23 @@ class C {
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'C'},
|
||||
// CHECK:STDOUT: {kind: 'ClassDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'DefaultSelfImplAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefaultSelfAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'ForwardDeclared'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'C'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'ExplicitType'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'ExplicitSelf'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'ExtendModifier', text: 'extend'},
|
||||
// CHECK:STDOUT: {kind: 'DefaultSelfImplAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefaultSelfAs', text: 'as'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'ExtendImpl'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
@@ -54,7 +54,7 @@ class C {
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'ExtendModifier', text: 'extend'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'C'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'InvalidButDiagnosedInCheck'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'ClassDefinition', text: '}', subtree_size: 36},
|
||||
|
||||
@@ -15,7 +15,7 @@ impl bool as Interface;
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
|
||||
@@ -16,7 +16,7 @@ impl str as Interface {
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'StringTypeLiteral', text: 'str'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 6},
|
||||
|
||||
+4
-4
@@ -108,12 +108,12 @@ impl
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
@@ -146,7 +146,7 @@ impl
|
||||
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'f16', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f16'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Quux'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
@@ -178,7 +178,7 @@ impl
|
||||
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 12},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
|
||||
@@ -50,7 +50,7 @@ fn C.(Self as Interface).F() {}
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
@@ -67,7 +67,7 @@ fn C.(Self as Interface).F() {}
|
||||
// CHECK:STDOUT: {kind: 'ClassDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ impl forall [T:! type, U:! Interface] U as Interface(T) {
|
||||
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 12},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
@@ -42,7 +42,7 @@ impl forall [T:! type, U:! Interface] U as Interface(T) {
|
||||
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 11},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'U'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'CallExprStart', text: '(', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/generics/interface/require.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/generics/interface/require.carbon
|
||||
|
||||
// --- implicit_self_impls.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
require impls Y;
|
||||
}
|
||||
|
||||
// --- explicit_self_impls.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
require Self impls Y;
|
||||
}
|
||||
|
||||
// --- impls_where.carbon
|
||||
|
||||
interface Y { let Y1:! type; }
|
||||
|
||||
interface Z {
|
||||
require impls Y where .Y1 = ();
|
||||
}
|
||||
|
||||
// --- other_impls.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z(T:! type) {
|
||||
require T impls Y;
|
||||
}
|
||||
|
||||
// --- extend.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
extend require impls Y;
|
||||
}
|
||||
|
||||
// --- fail_missing_impls.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_missing_impls.carbon:[[@LINE+4]]:12: error: expected `impls` in `require` declaration [RequireExpectedImpls]
|
||||
// CHECK:STDERR: require Y;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
require Y;
|
||||
}
|
||||
|
||||
// --- fail_wrong_keyword.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_wrong_keyword.carbon:[[@LINE+4]]:11: error: expected expression [ExpectedExpr]
|
||||
// CHECK:STDERR: require as Y;
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR:
|
||||
require as Y;
|
||||
}
|
||||
|
||||
// --- fail_as_in_self.carbon
|
||||
|
||||
interface Y {}
|
||||
|
||||
interface Z {
|
||||
// CHECK:STDERR: fail_as_in_self.carbon:[[@LINE+4]]:16: error: expected `impls` in `require` declaration [RequireExpectedImpls]
|
||||
// CHECK:STDERR: require Self as Y impls Y;
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR:
|
||||
require Self as Y impls Y;
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: implicit_self_impls.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDefaultSelfImpls', text: 'impls'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 8},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: explicit_self_impls.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'RequireTypeImpls', text: 'impls', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: impls_where.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'AssociatedConstantIntroducer', text: 'let'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y1'},
|
||||
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
|
||||
// CHECK:STDOUT: {kind: 'AssociatedConstantNameAndType', text: ':!', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'AssociatedConstantDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDefaultSelfImpls', text: 'impls'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y1'},
|
||||
// CHECK:STDOUT: {kind: 'DesignatorExpr', text: '.', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'RequirementEqual', text: '=', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'WhereExpr', text: 'where', subtree_size: 8},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', subtree_size: 11},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 15},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: other_impls.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'},
|
||||
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
|
||||
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 6},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
||||
// CHECK:STDOUT: {kind: 'RequireTypeImpls', text: 'impls', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 15},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: extend.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'ExtendModifier', text: 'extend'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDefaultSelfImpls', text: 'impls'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_missing_impls.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_wrong_keyword.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'as', has_error: yes},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: - filename: fail_as_in_self.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Y'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Z'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'RequireIntroducer', text: 'require'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'RequireDecl', text: ';', has_error: yes, subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 7},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
+2
-2
@@ -42,7 +42,7 @@ impl package.Name as package.Interface {}
|
||||
// CHECK:STDOUT: {kind: 'PackageDecl', text: ';', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinitionStart', text: '{', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 6},
|
||||
@@ -59,7 +59,7 @@ impl package.Name as package.Interface {}
|
||||
// CHECK:STDOUT: {kind: 'PackageExpr', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Name'},
|
||||
// CHECK:STDOUT: {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'PackageExpr', text: 'package'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'MemberAccessExpr', text: '.', subtree_size: 3},
|
||||
|
||||
+5
-5
@@ -38,7 +38,7 @@ impl f64 as Interface where .T = (type where .Self impls type) {
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 9},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'},
|
||||
@@ -51,7 +51,7 @@ impl f64 as Interface where .T = (type where .Self impls type) {
|
||||
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 13},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'},
|
||||
@@ -63,7 +63,7 @@ impl f64 as Interface where .T = (type where .Self impls type) {
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'TupleLiteralStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'TupleLiteral', text: ')', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
@@ -79,7 +79,7 @@ impl f64 as Interface where .T = (type where .Self impls type) {
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'StructLiteralStart', text: '{'},
|
||||
// CHECK:STDOUT: {kind: 'StructLiteral', text: '}', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParenExprStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
@@ -100,7 +100,7 @@ impl f64 as Interface where .T = (type where .Self impls type) {
|
||||
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', subtree_size: 22},
|
||||
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
||||
// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f64'},
|
||||
// CHECK:STDOUT: {kind: 'TypeImplAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
||||
// CHECK:STDOUT: {kind: 'WhereOperand', text: 'where', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'T'},
|
||||
|
||||
@@ -1446,6 +1446,40 @@ struct InterfaceDefinition {
|
||||
Lex::CloseCurlyBraceTokenIndex token;
|
||||
};
|
||||
|
||||
// `require`...`impls` statements
|
||||
// ------------------------------
|
||||
|
||||
// `require`
|
||||
using RequireIntroducer =
|
||||
LeafNode<NodeKind::RequireIntroducer, Lex::RequireTokenIndex>;
|
||||
|
||||
// `impls` with no type before it
|
||||
using RequireDefaultSelfImpls =
|
||||
LeafNode<NodeKind::RequireDefaultSelfImpls, Lex::ImplsTokenIndex,
|
||||
NodeCategory::RequireImpls>;
|
||||
|
||||
// `<type> impls`.
|
||||
struct RequireTypeImpls {
|
||||
static constexpr auto Kind = NodeKind::RequireTypeImpls.Define(
|
||||
{.category = NodeCategory::RequireImpls, .child_count = 1});
|
||||
|
||||
AnyExprId type_expr;
|
||||
Lex::ImplsTokenIndex token;
|
||||
};
|
||||
|
||||
// `require T impls I where...`
|
||||
struct RequireDecl {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::RequireDecl.Define({.category = NodeCategory::Decl,
|
||||
.bracketed_by = RequireIntroducer::Kind});
|
||||
|
||||
RequireIntroducerId introducer;
|
||||
llvm::SmallVector<AnyModifierId> modifiers;
|
||||
AnyRequireImplsId impls;
|
||||
AnyExprId facet_type;
|
||||
Lex::SemiTokenIndex token;
|
||||
};
|
||||
|
||||
// `impl`...`as` declarations and definitions
|
||||
// ------------------------------------------
|
||||
|
||||
@@ -1462,12 +1496,12 @@ struct ImplForall {
|
||||
};
|
||||
|
||||
// `as` with no type before it
|
||||
using DefaultSelfImplAs = LeafNode<NodeKind::DefaultSelfImplAs,
|
||||
using ImplDefaultSelfAs = LeafNode<NodeKind::ImplDefaultSelfAs,
|
||||
Lex::AsTokenIndex, NodeCategory::ImplAs>;
|
||||
|
||||
// `<type> as`
|
||||
struct TypeImplAs {
|
||||
static constexpr auto Kind = NodeKind::TypeImplAs.Define(
|
||||
struct ImplTypeAs {
|
||||
static constexpr auto Kind = NodeKind::ImplTypeAs.Define(
|
||||
{.category = NodeCategory::ImplAs, .child_count = 1});
|
||||
|
||||
AnyExprId type_expr;
|
||||
|
||||
Reference in New Issue
Block a user