mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Drop GetDeclContext from parse, errors will be diagnosed in check (#3468)
The criteria being enforced is not correct since `final` and `default` functions in interfaces have definitions.
This commit is contained in:
@@ -106,7 +106,6 @@ CARBON_DIAGNOSTIC_KIND(ExpectedDeclName)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedDeclSemi)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedDeclSemiOrDefinition)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedInitializerAfterLet)
|
||||
CARBON_DIAGNOSTIC_KIND(MethodImplNotAllowed)
|
||||
CARBON_DIAGNOSTIC_KIND(ParamsRequiredAfterImplicit)
|
||||
CARBON_DIAGNOSTIC_KIND(ParamsRequiredByIntroducer)
|
||||
CARBON_DIAGNOSTIC_KIND(ExpectedAfterBase)
|
||||
|
||||
@@ -417,30 +417,6 @@ auto Context::ConsumeListToken(NodeKind comma_kind, Lex::TokenKind close_kind,
|
||||
}
|
||||
}
|
||||
|
||||
auto Context::GetDeclContext() -> DeclContext {
|
||||
// i == 0 is the file-level DeclScopeLoop. Additionally, i == 1 can be
|
||||
// skipped because it will never be a DeclScopeLoop.
|
||||
for (int i = state_stack_.size() - 1; i > 1; --i) {
|
||||
// The declaration context is always the state _above_ a
|
||||
// DeclScopeLoop.
|
||||
if (state_stack_[i].state == State::DeclScopeLoop) {
|
||||
switch (state_stack_[i - 1].state) {
|
||||
case State::TypeDefinitionFinishAsClass:
|
||||
return DeclContext::Class;
|
||||
case State::TypeDefinitionFinishAsInterface:
|
||||
return DeclContext::Interface;
|
||||
case State::TypeDefinitionFinishAsNamedConstraint:
|
||||
return DeclContext::NamedConstraint;
|
||||
default:
|
||||
llvm_unreachable("Missing handling for a declaration scope");
|
||||
}
|
||||
}
|
||||
}
|
||||
CARBON_CHECK(!state_stack_.empty() &&
|
||||
state_stack_[0].state == State::DeclScopeLoop);
|
||||
return DeclContext::File;
|
||||
}
|
||||
|
||||
auto Context::RecoverFromDeclError(StateStackEntry state,
|
||||
NodeKind parse_node_kind,
|
||||
bool skip_past_likely_end) -> void {
|
||||
|
||||
@@ -47,14 +47,6 @@ class Context {
|
||||
Let
|
||||
};
|
||||
|
||||
// Supported return values for GetDeclContext.
|
||||
enum class DeclContext : int8_t {
|
||||
File, // Top-level context.
|
||||
Class,
|
||||
Interface,
|
||||
NamedConstraint,
|
||||
};
|
||||
|
||||
// Used for restricting ordering of `package` and `import` directives.
|
||||
enum class PackagingState : int8_t {
|
||||
FileStart,
|
||||
@@ -300,15 +292,6 @@ class Context {
|
||||
<< "Excessive stack size: likely infinite loop";
|
||||
}
|
||||
|
||||
// Returns the current declaration context according to state_stack_.
|
||||
// This is expected to be called in cases which are close to a context.
|
||||
// Although it looks like it could be O(n) for state_stack_'s depth, valid
|
||||
// parses should only need to look down a couple steps.
|
||||
//
|
||||
// This currently assumes it's being called from within the declaration's
|
||||
// DeclScopeLoop.
|
||||
auto GetDeclContext() -> DeclContext;
|
||||
|
||||
// Propagates an error up the state stack, to the parent state.
|
||||
auto ReturnErrorOnState() -> void { state_stack_.back().has_error = true; }
|
||||
|
||||
|
||||
@@ -46,18 +46,6 @@ auto HandleFunctionSignatureFinish(Context& context) -> void {
|
||||
break;
|
||||
}
|
||||
case Lex::TokenKind::OpenCurlyBrace: {
|
||||
if (auto decl_context = context.GetDeclContext();
|
||||
decl_context == Context::DeclContext::Interface ||
|
||||
decl_context == Context::DeclContext::NamedConstraint) {
|
||||
CARBON_DIAGNOSTIC(
|
||||
MethodImplNotAllowed, Error,
|
||||
"Method implementations are not allowed in interfaces.");
|
||||
context.emitter().Emit(*context.position(), MethodImplNotAllowed);
|
||||
context.RecoverFromDeclError(state, NodeKind::FunctionDecl,
|
||||
/*skip_past_likely_end=*/true);
|
||||
break;
|
||||
}
|
||||
|
||||
context.AddNode(NodeKind::FunctionDefinitionStart, context.Consume(),
|
||||
state.subtree_start, state.has_error);
|
||||
// Any error is recorded on the FunctionDefinitionStart.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
// 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
|
||||
|
||||
interface Foo {
|
||||
// CHECK:STDERR: fail_no_impl_allowed.carbon:[[@LINE+3]]:39: ERROR: Method implementations are not allowed in interfaces.
|
||||
// CHECK:STDERR: fn Add[self: Self](b: Self) -> Self {
|
||||
// CHECK:STDERR: ^
|
||||
fn Add[self: Self](b: Self) -> Self {
|
||||
print("You can't do that.");
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: fail_no_impl_allowed.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Add'},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'SelfValueName', text: 'self'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'b'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: 'fn', has_error: yes, subtree_size: 15},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 19},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,43 @@
|
||||
// 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
|
||||
|
||||
interface Foo {
|
||||
final fn Add[self: Self](b: Self) -> Self {
|
||||
print("Allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: final_member_definition.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceIntroducer', text: 'interface'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'FinalModifier', text: 'final'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Add'},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'SelfValueName', text: 'self'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'b'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 16},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'print'},
|
||||
// CHECK:STDOUT: {kind: 'CallExprStart', text: '(', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'StringLiteral', text: '"Allowed."'},
|
||||
// CHECK:STDOUT: {kind: 'CallExpr', text: ')', subtree_size: 4},
|
||||
// CHECK:STDOUT: {kind: 'ExprStatement', text: ';', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22},
|
||||
// CHECK:STDOUT: {kind: 'InterfaceDefinition', text: '}', subtree_size: 26},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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
|
||||
|
||||
constraint Foo {
|
||||
fn Add[self: Self](b: Self) -> Self {}
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: defined_method.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintIntroducer', text: 'constraint'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Add'},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'SelfValueName', text: 'self'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'b'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 15},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 16},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintDefinition', text: '}', subtree_size: 20},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
// 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
|
||||
|
||||
constraint Foo {
|
||||
// CHECK:STDERR: fail_no_impl_allowed.carbon:[[@LINE+3]]:39: ERROR: Method implementations are not allowed in interfaces.
|
||||
// CHECK:STDERR: fn Add[self: Self](b: Self) -> Self {}
|
||||
// CHECK:STDERR: ^
|
||||
fn Add[self: Self](b: Self) -> Self {}
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: - filename: fail_no_impl_allowed.carbon
|
||||
// CHECK:STDOUT: parse_tree: [
|
||||
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintIntroducer', text: 'constraint'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Foo'},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintDefinitionStart', text: '{', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'Add'},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
||||
// CHECK:STDOUT: {kind: 'SelfValueName', text: 'self'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'ParamListStart', text: '('},
|
||||
// CHECK:STDOUT: {kind: 'IdentifierName', text: 'b'},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'BindingPattern', text: ':', subtree_size: 3},
|
||||
// CHECK:STDOUT: {kind: 'ParamList', text: ')', subtree_size: 5},
|
||||
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
|
||||
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
|
||||
// CHECK:STDOUT: {kind: 'FunctionDecl', text: 'fn', has_error: yes, subtree_size: 15},
|
||||
// CHECK:STDOUT: {kind: 'NamedConstraintDefinition', text: '}', subtree_size: 19},
|
||||
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
||||
// CHECK:STDOUT: ]
|
||||
Reference in New Issue
Block a user