mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 11:40:14 +01:00
Only look in facet types for name scopes when they have constraints (#7819)
This falls back to diagnosing that values of type `type` can not be used for name lookup more consistently.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "toolchain/sem_ir/generic.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/name_scope.h"
|
||||
#include "toolchain/sem_ir/typed_insts.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
|
||||
@@ -323,15 +324,16 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
llvm::SmallVector<LookupScope>* scopes)
|
||||
-> bool {
|
||||
auto lookup_inst_id = context.constant_values().GetInstId(lookup_const_id);
|
||||
auto lookup = context.insts().Get(lookup_inst_id);
|
||||
|
||||
if (auto ns = lookup.TryAs<SemIR::Namespace>()) {
|
||||
if (auto ns = context.insts().TryGetAs<SemIR::Namespace>(lookup_inst_id)) {
|
||||
scopes->push_back(LookupScope{.name_scope_id = ns->name_scope_id,
|
||||
.specific_id = SemIR::SpecificId::None,
|
||||
.self_const_id = SemIR::ConstantId::None});
|
||||
return true;
|
||||
}
|
||||
if (auto class_ty = lookup.TryAs<SemIR::ClassType>()) {
|
||||
|
||||
if (auto class_ty =
|
||||
context.insts().TryGetAs<SemIR::ClassType>(lookup_inst_id)) {
|
||||
if (!extended_scope) {
|
||||
// TODO: Allow name lookup into classes that are being defined even if
|
||||
// they are not complete.
|
||||
@@ -351,8 +353,14 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
.self_const_id = self_type_const_id});
|
||||
return true;
|
||||
}
|
||||
// Extended scopes may point to a FacetType.
|
||||
if (auto facet_type = lookup.TryAs<SemIR::FacetType>()) {
|
||||
|
||||
// Extended scopes may point to a FacetType. If it has constraints, collect
|
||||
// the extended ones as scopes.
|
||||
auto lookup_type_id =
|
||||
context.types().TryGetTypeIdForTypeInstId(lookup_inst_id);
|
||||
if (lookup_type_id.has_value() &&
|
||||
context.types().IsConstrainedFacetType(lookup_type_id)) {
|
||||
auto facet_type = context.types().GetAs<SemIR::FacetType>(lookup_type_id);
|
||||
if (!extended_scope) {
|
||||
// TODO: Allow name lookup into facet types that are being defined even if
|
||||
// they are not complete.
|
||||
@@ -378,7 +386,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
|
||||
auto declared_facet_type =
|
||||
context.declared_facet_types().Get(facet_type->declared_facet_type_id);
|
||||
context.declared_facet_types().Get(facet_type.declared_facet_type_id);
|
||||
// Name lookup into "extend" constraints but not "self impls" constraints.
|
||||
for (const auto& extend : declared_facet_type.extend_constraints) {
|
||||
auto& interface = context.interfaces().Get(extend.interface_id);
|
||||
@@ -413,6 +421,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lookup_const_id == SemIR::ErrorInst::ConstantId) {
|
||||
// Lookup into this scope should fail without producing an error.
|
||||
scopes->push_back(LookupScope{.name_scope_id = SemIR::NameScopeId::None,
|
||||
@@ -420,6 +429,7 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id,
|
||||
.self_const_id = SemIR::ConstantId::None});
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Per the design, if `base_id` is any kind of type, then lookup should
|
||||
// treat it as a name scope, even if it doesn't have members. For example,
|
||||
// `(i32*).X` should fail because there's no name `X` in `i32*`, not because
|
||||
|
||||
@@ -32,7 +32,7 @@ interface Z {
|
||||
let X: type;
|
||||
}
|
||||
|
||||
// CHECK:STDERR: fail_todo_struct_access_through_witness.carbon:[[@LINE+4]]:43: error: member name `t` not found [MemberNameNotFound]
|
||||
// CHECK:STDERR: fail_todo_struct_access_through_witness.carbon:[[@LINE+4]]:43: error: type `type` does not support qualified expressions [QualifiedExprUnsupported]
|
||||
// CHECK:STDERR: fn F(generic T: Z where .X = {.t: ()}) -> T.X.t {
|
||||
// CHECK:STDERR: ^~~~~
|
||||
// CHECK:STDERR:
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ fn F(T: Z) {
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F(T: type) {
|
||||
// CHECK:STDERR: fail_member_access_runtime_type.carbon:[[@LINE+4]]:3: error: member name `G` not found [MemberNameNotFound]
|
||||
// CHECK:STDERR: fail_member_access_runtime_type.carbon:[[@LINE+4]]:3: error: type `type` does not support qualified expressions [QualifiedExprUnsupported]
|
||||
// CHECK:STDERR: T.G();
|
||||
// CHECK:STDERR: ^~~
|
||||
// CHECK:STDERR:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_lookup_in_type.carbon:[[@LINE+4]]:8: error: member name `not_found` not found [MemberNameNotFound]
|
||||
// CHECK:STDERR: fail_lookup_in_type.carbon:[[@LINE+4]]:8: error: type `type` does not support qualified expressions [QualifiedExprUnsupported]
|
||||
// CHECK:STDERR: let T: type.not_found = {};
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -26,7 +26,7 @@ let T: type.not_found = {};
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_lookup_type_where.carbon:[[@LINE+4]]:8: error: member name `missing` not found [MemberNameNotFound]
|
||||
// CHECK:STDERR: fail_lookup_type_where.carbon:[[@LINE+4]]:8: error: type `type` does not support qualified expressions [QualifiedExprUnsupported]
|
||||
// CHECK:STDERR: let U: (type where .Self impls type).missing = {};
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR:
|
||||
@@ -44,10 +44,7 @@ let U: (type where .Self impls type).missing = {};
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .T = %T
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.1: <error> = splice_block <error> [concrete = <error>] {
|
||||
// CHECK:STDOUT: %.loc8: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: %not_found.ref: <error> = name_ref not_found, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %.loc8: type = type_literal type [concrete = type]
|
||||
// CHECK:STDOUT: %T: <error> = wrapper_binding T, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %T.patt: <error> = value_binding_pattern T [concrete = <error>]
|
||||
@@ -88,7 +85,6 @@ let U: (type where .Self impls type).missing = {};
|
||||
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %.loc8_9 [concrete]
|
||||
// CHECK:STDOUT: %impls.loc8_26.2 = requirement_impls %.Self.ref.loc8_20.2, %.loc8_32 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %missing.ref: <error> = name_ref missing, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %U: <error> = wrapper_binding U, <error> [concrete = <error>]
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
|
||||
Reference in New Issue
Block a user