mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 09:24:46 +01:00
Improve diagnostic for unknown name in name qualifier. (#2579)
As requested in #2572.
This commit is contained in:
@@ -52,14 +52,21 @@ auto StaticScope::Resolve(std::string_view name,
|
||||
return *result;
|
||||
}
|
||||
|
||||
auto StaticScope::ResolveHere(std::string_view name, SourceLocation source_loc,
|
||||
auto StaticScope::ResolveHere(std::optional<ValueNodeView> this_scope,
|
||||
std::string_view name, SourceLocation source_loc,
|
||||
bool allow_undeclared) const
|
||||
-> ErrorOr<ValueNodeView> {
|
||||
CARBON_ASSIGN_OR_RETURN(std::optional<ValueNodeView> result,
|
||||
TryResolveHere(name, source_loc, allow_undeclared));
|
||||
if (!result) {
|
||||
return ProgramError(source_loc)
|
||||
<< "could not resolve '" << name << "' in this scope";
|
||||
if (this_scope) {
|
||||
return ProgramError(source_loc)
|
||||
<< "name '" << name << "' has not been declared in "
|
||||
<< PrintAsID(this_scope->base());
|
||||
} else {
|
||||
return ProgramError(source_loc)
|
||||
<< "name '" << name << "' has not been declared in this scope";
|
||||
}
|
||||
}
|
||||
return *result;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ class StaticScope {
|
||||
// error at `source_loc` if the name is not declared in this scope. If
|
||||
// `allow_undeclared` is `true`, names that have been added but not yet marked
|
||||
// declared or usable do not result in an error.
|
||||
auto ResolveHere(std::string_view name, SourceLocation source_loc,
|
||||
auto ResolveHere(std::optional<ValueNodeView> this_scope,
|
||||
std::string_view name, SourceLocation source_loc,
|
||||
bool allow_undeclared) const -> ErrorOr<ValueNodeView>;
|
||||
|
||||
// Returns the value node of the BindingPattern of the returned var definition
|
||||
|
||||
@@ -113,14 +113,16 @@ auto NameResolver::ResolveQualifier(DeclaredName name,
|
||||
bool allow_undeclared)
|
||||
-> ErrorOr<Nonnull<StaticScope*>> {
|
||||
Nonnull<StaticScope*> scope = &enclosing_scope;
|
||||
std::optional<ValueNodeView> scope_node;
|
||||
for (const auto& [loc, qualifier] : name.qualifiers()) {
|
||||
// TODO: If we permit qualified names anywhere other than the top level, we
|
||||
// will need to decide whether the first name in the qualifier is looked up
|
||||
// only in the innermost enclosing scope or in all enclosing scopes.
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
ValueNodeView node,
|
||||
scope->ResolveHere(qualifier, loc, allow_undeclared));
|
||||
scope->ResolveHere(scope_node, qualifier, loc, allow_undeclared));
|
||||
|
||||
scope_node = node;
|
||||
if (const auto* namespace_decl =
|
||||
dyn_cast<NamespaceDeclaration>(&node.base())) {
|
||||
scope = &namespace_scopes_[namespace_decl];
|
||||
@@ -282,7 +284,8 @@ auto NameResolver::ResolveNames(Expression& expression,
|
||||
<< "name resolved to undeclared namespace";
|
||||
CARBON_ASSIGN_OR_RETURN(
|
||||
const auto value_node,
|
||||
ns_it->second.ResolveHere(access.member_name(), access.source_loc(),
|
||||
ns_it->second.ResolveHere(scope, access.member_name(),
|
||||
access.source_loc(),
|
||||
/*allow_undeclared=*/false));
|
||||
access.set_value_node(value_node);
|
||||
return {value_node};
|
||||
|
||||
+1
-1
@@ -11,6 +11,6 @@ package ExplorerTest api;
|
||||
namespace N;
|
||||
|
||||
fn Main() -> i32 {
|
||||
// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/namespace/fail_unknown_member.carbon:[[@LINE+1]]: could not resolve 'value' in this scope
|
||||
// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/namespace/fail_unknown_member.carbon:[[@LINE+1]]: name 'value' has not been declared in namespace N
|
||||
return N.value;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
package ExplorerTest api;
|
||||
|
||||
// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/namespace/fail_unknown_namespace.carbon:[[@LINE+1]]: could not resolve 'N' in this scope
|
||||
// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/namespace/fail_unknown_namespace.carbon:[[@LINE+1]]: name 'N' has not been declared in this scope
|
||||
fn N.F() {}
|
||||
|
||||
fn Main() -> i32 {
|
||||
|
||||
Reference in New Issue
Block a user