Basic name poisoning support (#4654)

https://github.com/carbon-language/carbon-lang/issues/4622
When using an unqualified name, disallow declaring that name in all
scopes that would make it ambiguous in retrospect.
Doesn't include support for poisoning in `impl library` (see new test
for that with TODO).
Implemented by introduce `InstId::PoisonedName` and entries with it to
`NameScope`.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: josh11b <josh11b@users.noreply.github.com>
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
This commit is contained in:
Boaz Brickner
2024-12-17 21:08:26 +00:00
committed by GitHub
co-authored by Dana Jansens Richard Smith Geoff Romer Jon Ross-Perkins josh11b josh11b Chandler Carruth Carbon Infra Bot
parent 6b3307c520
commit 9c8773da1b
20 changed files with 1006 additions and 100 deletions
+24 -5
View File
@@ -33,6 +33,9 @@ auto DeclNameStack::NameContext::prev_inst_id() -> SemIR::InstId {
case NameContext::State::Unresolved:
return SemIR::InstId::Invalid;
case NameContext::State::Poisoned:
return SemIR::InstId::PoisonedName;
case NameContext::State::Finished:
CARBON_FATAL("Finished state should only be used internally");
}
@@ -167,12 +170,15 @@ auto DeclNameStack::AddName(NameContext name_context, SemIR::InstId target_id,
}
}
auto DeclNameStack::AddNameOrDiagnoseDuplicate(NameContext name_context,
SemIR::InstId target_id,
SemIR::AccessKind access_kind)
-> void {
auto DeclNameStack::AddNameOrDiagnose(NameContext name_context,
SemIR::InstId target_id,
SemIR::AccessKind access_kind) -> void {
if (auto id = name_context.prev_inst_id(); id.is_valid()) {
context_->DiagnoseDuplicateName(target_id, id);
if (id.is_poisoned()) {
context_->DiagnosePoisonedName(target_id);
} else {
context_->DiagnoseDuplicateName(target_id, id);
}
} else {
AddName(name_context, target_id, access_kind);
}
@@ -260,6 +266,9 @@ auto DeclNameStack::ApplyAndLookupName(NameContext& name_context,
// Invalid indicates an unresolved name. Store it and return.
name_context.unresolved_name_id = name_id;
name_context.state = NameContext::State::Unresolved;
} else if (resolved_inst_id.is_poisoned()) {
name_context.unresolved_name_id = name_id;
name_context.state = NameContext::State::Poisoned;
} else {
// Store the resolved instruction and continue for the target scope
// update.
@@ -277,8 +286,14 @@ static auto CheckQualifierIsResolved(
CARBON_FATAL("No qualifier to resolve");
case DeclNameStack::NameContext::State::Resolved:
if (name_context.resolved_inst_id.is_poisoned()) {
context.DiagnoseNameNotFound(name_context.loc_id,
name_context.unresolved_name_id);
return false;
}
return true;
case DeclNameStack::NameContext::State::Poisoned:
case DeclNameStack::NameContext::State::Unresolved:
// Because more qualifiers were found, we diagnose that the earlier
// qualifier failed to resolve.
@@ -367,6 +382,10 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context,
return InvalidResult;
}
if (name_context.resolved_inst_id.is_poisoned()) {
return InvalidResult;
}
auto new_params = DeclParams(
name.name_loc_id, name.first_param_node_id, name.last_param_node_id,
name.implicit_param_patterns_id, name.param_patterns_id);