mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
This change adds a `BindSymbolicName` instruction for generic bindings, paralleling the existing `BindName`. A mechanism is also added to allow both kinds of binding to be accessed uniformly, for convenience in the case where the two different kinds of binding are treated the same. Generic bindings of type `type` are allowed to be used as types, although no operations are provided for such types. For now lowering treats these types as empty structs, which seems like a reasonable lowering for non-monomorphized unconstrained types.
73 lines
2.8 KiB
C++
73 lines
2.8 KiB
C++
// 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/convert.h"
|
|
#include "toolchain/check/modifiers.h"
|
|
#include "toolchain/sem_ir/inst.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
auto HandleLetDecl(Context& context, Parse::LetDeclId parse_node) -> bool {
|
|
auto value_id = context.node_stack().PopExpr();
|
|
if (context.node_stack().PeekIs<Parse::NodeKind::TuplePattern>()) {
|
|
return context.TODO(parse_node, "tuple pattern in let");
|
|
}
|
|
SemIR::InstId pattern_id = context.node_stack().PopPattern();
|
|
context.node_stack()
|
|
.PopAndDiscardSoloParseNode<Parse::NodeKind::LetIntroducer>();
|
|
// Process declaration modifiers.
|
|
CheckAccessModifiersOnDecl(context, Lex::TokenKind::Let);
|
|
RequireDefaultFinalOnlyInInterfaces(context, Lex::TokenKind::Let);
|
|
LimitModifiersOnDecl(
|
|
context, KeywordModifierSet::Access | KeywordModifierSet::Interface,
|
|
Lex::TokenKind::Let);
|
|
|
|
auto modifiers = context.decl_state_stack().innermost().modifier_set;
|
|
if (!!(modifiers & KeywordModifierSet::Access)) {
|
|
context.TODO(context.decl_state_stack().innermost().saw_access_modifier,
|
|
"access modifier");
|
|
}
|
|
if (!!(modifiers & KeywordModifierSet::Interface)) {
|
|
context.TODO(context.decl_state_stack().innermost().saw_decl_modifier,
|
|
"interface modifier");
|
|
}
|
|
context.decl_state_stack().Pop(DeclState::Let);
|
|
|
|
// Convert the value to match the type of the pattern.
|
|
auto pattern = context.insts().Get(pattern_id);
|
|
value_id =
|
|
ConvertToValueOfType(context, parse_node, value_id, pattern.type_id());
|
|
|
|
// Update the binding with its value and add it to the current block, after
|
|
// the computation of the value.
|
|
// TODO: Support other kinds of pattern here.
|
|
auto bind_name = pattern.As<SemIR::AnyBindName>();
|
|
CARBON_CHECK(!bind_name.value_id.is_valid())
|
|
<< "Binding should not already have a value!";
|
|
bind_name.value_id = value_id;
|
|
context.insts().Set(pattern_id, bind_name);
|
|
context.inst_block_stack().AddInstId(pattern_id);
|
|
|
|
// Add the name of the binding to the current scope.
|
|
auto name_id = context.bind_names().Get(bind_name.bind_name_id).name_id;
|
|
context.AddNameToLookup(pattern.parse_node(), name_id, pattern_id);
|
|
return true;
|
|
}
|
|
|
|
auto HandleLetIntroducer(Context& context, Parse::LetIntroducerId parse_node)
|
|
-> bool {
|
|
context.decl_state_stack().Push(DeclState::Let);
|
|
// Push a bracketing node to establish the pattern context.
|
|
context.node_stack().Push(parse_node);
|
|
return true;
|
|
}
|
|
|
|
auto HandleLetInitializer(Context& /*context*/,
|
|
Parse::LetInitializerId /*parse_node*/) -> bool {
|
|
return true;
|
|
}
|
|
|
|
} // namespace Carbon::Check
|