mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 14:51:03 +01:00
Sorting out how bindings are added to name lookup. (#2869)
This shifts logic so that bindings are added to name lookup only after the scope is complete, removing logic around adding/removing/re-adding names in certain scopes. This does mean that things like a function's forward declaration will need to go through an extra hoop for name conflict checks, because under this approach a function definition does conflict checking when it adds names for the body's use. But, that seems easy to address, and better than the current hoops.
This commit is contained in:
@@ -75,7 +75,9 @@ auto SemanticsContext::AddNodeAndPush(ParseTree::Node parse_node,
|
||||
auto SemanticsContext::AddNameToLookup(ParseTree::Node name_node,
|
||||
SemanticsStringId name_id,
|
||||
SemanticsNodeId target_id) -> void {
|
||||
if (!AddNameToLookupImpl(name_id, target_id)) {
|
||||
if (current_scope().names.insert(name_id).second) {
|
||||
name_lookup_[name_id].push_back(target_id);
|
||||
} else {
|
||||
CARBON_DIAGNOSTIC(NameRedefined, Error, "Redefining {0} in the same scope.",
|
||||
llvm::StringRef);
|
||||
CARBON_DIAGNOSTIC(PreviousDefinition, Note, "Previous definition is here.");
|
||||
@@ -88,49 +90,6 @@ auto SemanticsContext::AddNameToLookup(ParseTree::Node name_node,
|
||||
}
|
||||
}
|
||||
|
||||
auto SemanticsContext::AddNameToLookupImpl(SemanticsStringId name_id,
|
||||
SemanticsNodeId target_id) -> bool {
|
||||
if (current_scope().names.insert(name_id).second) {
|
||||
name_lookup_[name_id].push_back(target_id);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto SemanticsContext::BindName(ParseTree::Node name_node,
|
||||
SemanticsTypeId type_id,
|
||||
SemanticsNodeId target_id)
|
||||
-> SemanticsStringId {
|
||||
CARBON_CHECK(parse_tree_->node_kind(name_node) == ParseNodeKind::DeclaredName)
|
||||
<< parse_tree_->node_kind(name_node);
|
||||
auto name_str = parse_tree_->GetNodeText(name_node);
|
||||
auto name_id = semantics_ir_->AddString(name_str);
|
||||
|
||||
AddNode(
|
||||
SemanticsNode::BindName::Make(name_node, type_id, name_id, target_id));
|
||||
AddNameToLookup(name_node, name_id, target_id);
|
||||
return name_id;
|
||||
}
|
||||
|
||||
auto SemanticsContext::TempRemoveLatestNameFromLookup() -> SemanticsNodeId {
|
||||
// Save the storage ID.
|
||||
auto it = name_lookup_.find(
|
||||
node_stack_.Peek<SemanticsStringId>(ParseNodeKind::PatternBinding));
|
||||
CARBON_CHECK(it != name_lookup_.end());
|
||||
CARBON_CHECK(!it->second.empty());
|
||||
auto storage_id = it->second.back();
|
||||
|
||||
// Pop the name from lookup.
|
||||
if (it->second.size() == 1) {
|
||||
// Erase names that no longer resolve.
|
||||
name_lookup_.erase(it);
|
||||
} else {
|
||||
it->second.pop_back();
|
||||
}
|
||||
return storage_id;
|
||||
}
|
||||
|
||||
auto SemanticsContext::LookupName(ParseTree::Node parse_node,
|
||||
llvm::StringRef name) -> SemanticsNodeId {
|
||||
CARBON_DIAGNOSTIC(NameNotFound, Error, "Name {0} not found", llvm::StringRef);
|
||||
@@ -185,7 +144,7 @@ auto SemanticsContext::ImplicitAsForArgs(
|
||||
if (arg_refs.size() != param_refs.size()) {
|
||||
CARBON_CHECK(diagnostic != nullptr) << "Should have validated first";
|
||||
CARBON_DIAGNOSTIC(CallArgCountMismatch, Note,
|
||||
"Callable cannot be used: Received {0} argument(s), but "
|
||||
"Function cannot be used: Received {0} argument(s), but "
|
||||
"require {1} argument(s).",
|
||||
int, int);
|
||||
diagnostic->Note(param_parse_node, CallArgCountMismatch, arg_refs.size(),
|
||||
@@ -204,7 +163,7 @@ auto SemanticsContext::ImplicitAsForArgs(
|
||||
ImplicitAsKind::Incompatible) {
|
||||
CARBON_CHECK(diagnostic != nullptr) << "Should have validated first";
|
||||
CARBON_DIAGNOSTIC(CallArgTypeMismatch, Note,
|
||||
"Callable cannot be used: Cannot implicityly convert "
|
||||
"Function cannot be used: Cannot implicityly convert "
|
||||
"argument {0} from `{1}` to `{2}`.",
|
||||
size_t, std::string, std::string);
|
||||
diagnostic->Note(param_parse_node, CallArgTypeMismatch, i,
|
||||
|
||||
Reference in New Issue
Block a user