mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:40:10 +01:00
Have Specific track whether regions contain errors (#6982)
This removes some loops in type completion, but is motivated by the thought that eval probably wants to query it. Assisted-by: Google Antigravity with Gemini
This commit is contained in:
@@ -2599,7 +2599,7 @@ auto TryEvalInstUnsafe(Context& context, SemIR::InstId inst_id,
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id,
|
||||
SemIR::GenericInstIndex::Region region)
|
||||
-> SemIR::InstBlockId {
|
||||
-> std::pair<SemIR::InstBlockId, bool> {
|
||||
auto generic_id = context.specifics().Get(specific_id).generic_id;
|
||||
auto eval_block_id = context.generics().Get(generic_id).GetEvalBlock(region);
|
||||
auto eval_block = context.inst_blocks().Get(eval_block_id);
|
||||
@@ -2621,15 +2621,19 @@ auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
builder.Context(loc_id, ResolvingSpecificHere, specific_id);
|
||||
});
|
||||
|
||||
bool has_error = false;
|
||||
for (auto [i, inst_id] : llvm::enumerate(eval_block)) {
|
||||
auto const_id = TryEvalInstInContext(eval_context, inst_id,
|
||||
context.insts().Get(inst_id));
|
||||
if (const_id == SemIR::ErrorInst::ConstantId) {
|
||||
has_error = true;
|
||||
}
|
||||
result[i] = context.constant_values().GetInstId(const_id);
|
||||
CARBON_CHECK(result[i].has_value(), "Failed to evaluate {0} in eval block",
|
||||
context.insts().Get(inst_id));
|
||||
}
|
||||
|
||||
return context.inst_blocks().Add(result);
|
||||
return {context.inst_blocks().Add(result), has_error};
|
||||
}
|
||||
|
||||
// Information about the function call we are currently executing. Unlike
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define CARBON_TOOLCHAIN_CHECK_EVAL_H_
|
||||
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/sem_ir/generic.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/inst.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
@@ -51,13 +52,11 @@ auto TryEvalInst(Context& context, InstT inst) -> SemIR::ConstantId {
|
||||
|
||||
// Evaluates the eval block for a region of a specific. Produces a block
|
||||
// containing the evaluated constant values of the instructions in the eval
|
||||
// block.
|
||||
//
|
||||
// TODO: Return whether any of the instructions produced contain an ErrorInst.
|
||||
// block. The returned bool indicates whether the region has an error.
|
||||
auto TryEvalBlockForSpecific(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::SpecificId specific_id,
|
||||
SemIR::GenericInstIndex::Region region)
|
||||
-> SemIR::InstBlockId;
|
||||
-> std::pair<SemIR::InstBlockId, bool>;
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
|
||||
@@ -666,9 +666,7 @@ auto ResolveSpecificDecl(Context& context, SemIR::LocId loc_id,
|
||||
// recursively resolve the same specific.
|
||||
specific.decl_block_id = SemIR::InstBlockId::Empty;
|
||||
|
||||
// TODO: Store in the specific whether the declaration contains any
|
||||
// ErrorInst values.
|
||||
specific.decl_block_id =
|
||||
std::tie(specific.decl_block_id, specific.decl_block_has_error) =
|
||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||
SemIR::GenericInstIndex::Region::Declaration);
|
||||
}
|
||||
@@ -734,10 +732,10 @@ auto ResolveSpecificDefinition(Context& context, SemIR::LocId loc_id,
|
||||
// The generic is not defined yet.
|
||||
return false;
|
||||
}
|
||||
// TODO: Store in the specific whether the definition contains any ErrorInst
|
||||
// values.
|
||||
specific.definition_block_id = TryEvalBlockForSpecific(
|
||||
context, loc_id, specific_id, SemIR::GenericInstIndex::Definition);
|
||||
std::tie(specific.definition_block_id,
|
||||
specific.definition_block_has_error) =
|
||||
TryEvalBlockForSpecific(context, loc_id, specific_id,
|
||||
SemIR::GenericInstIndex::Definition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1068,9 +1068,12 @@ static auto TryFinishSpecific(ImportRefResolver& resolver,
|
||||
if (!local_specific.decl_block_id.has_value()) {
|
||||
local_specific.decl_block_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_specific.decl_block_id, decl_block);
|
||||
local_specific.decl_block_has_error = import_specific.decl_block_has_error;
|
||||
}
|
||||
local_specific.definition_block_id = GetLocalCanonicalInstBlockId(
|
||||
resolver, import_specific.definition_block_id, definition_block);
|
||||
local_specific.definition_block_has_error =
|
||||
import_specific.definition_block_has_error;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+39
-39
@@ -371,45 +371,45 @@ fn Foo[T:! type](p: T*) -> (T*, ()) {
|
||||
// CHECK:STDOUT: generic78000009: {decl: inst7800011F, bindings: inst_block7800007F, self_specific_id: specific78000017, decl_block_id: inst_block78000083, definition_block_id: inst_block78000085}
|
||||
// CHECK:STDOUT: generic7800000A: {decl: inst78000126, bindings: inst_block78000070, self_specific_id: specific7800001A, decl_block_id: inst_block78000072, definition_block_id: inst_block7800007C}
|
||||
// CHECK:STDOUT: specifics:
|
||||
// CHECK:STDOUT: specific78000000: {generic: generic78000000, args: inst_block78000016, decl_block_id: inst_block78000018, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000001: {generic: generic78000001, args: inst_block7800001D, decl_block_id: inst_block_empty, definition_block_id: inst_block7800001E}
|
||||
// CHECK:STDOUT: specific78000002: {generic: generic78000002, args: inst_block7800001D, decl_block_id: inst_block78000024, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000025, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000004: {generic: generic78000003, args: inst_block78000028, decl_block_id: inst_block78000029, definition_block_id: inst_block7800002A}
|
||||
// CHECK:STDOUT: specific78000005: {generic: generic78000001, args: inst_block78000028, decl_block_id: inst_block_empty, definition_block_id: inst_block78000030}
|
||||
// CHECK:STDOUT: specific78000006: {generic: generic78000002, args: inst_block78000028, decl_block_id: inst_block78000031, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000007: {generic: generic78000004, args: inst_block78000028, decl_block_id: inst_block78000035, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block78000032, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block78000032, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000038, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800000B: {generic: generic78000005, args: inst_block78000016, decl_block_id: inst_block7800003D, definition_block_id: inst_block78000086}
|
||||
// CHECK:STDOUT: specific7800000C: {generic: generic78000005, args: inst_block78000040, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800000D: {generic: generic78000006, args: inst_block78000016, decl_block_id: inst_block78000047, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800000E: {generic: generic78000007, args: inst_block7800004C, decl_block_id: inst_block7800004E, definition_block_id: inst_block7800004F}
|
||||
// CHECK:STDOUT: specific7800000F: {generic: generic78000001, args: inst_block78000056, decl_block_id: inst_block_empty, definition_block_id: inst_block78000057}
|
||||
// CHECK:STDOUT: specific78000010: {generic: generic78000002, args: inst_block78000056, decl_block_id: inst_block78000058, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000011: {generic: generic78000008, args: inst_block7800004C, decl_block_id: inst_block7800005E, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000059, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000059, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block7800005B, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block7800005B, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block78000061, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000017: {generic: generic78000009, args: inst_block78000069, decl_block_id: inst_block7800006B, definition_block_id: inst_block7800006C}
|
||||
// CHECK:STDOUT: specific78000018: {generic: generic78000001, args: inst_block78000073, decl_block_id: inst_block_empty, definition_block_id: inst_block78000074}
|
||||
// CHECK:STDOUT: specific78000019: {generic: generic78000002, args: inst_block78000073, decl_block_id: inst_block78000075, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001A: {generic: generic7800000A, args: inst_block78000069, decl_block_id: inst_block7800007D, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000076, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000076, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000078, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000078, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block7800007A, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block7800007A, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block78000080, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000087, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000023: {generic: generic78000001, args: inst_block78000089, decl_block_id: inst_block_empty, definition_block_id: inst_block7800008A}
|
||||
// CHECK:STDOUT: specific78000024: {generic: generic78000001, args: inst_block7800008C, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000025: {generic: generic78000002, args: inst_block78000089, decl_block_id: inst_block7800008D, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block7800008C, decl_block_id: inst_block<none>, definition_block_id: inst_block<none>}
|
||||
// CHECK:STDOUT: specific78000000: {generic: generic78000000, args: inst_block78000016, decl_block_id: inst_block78000018, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000001: {generic: generic78000001, args: inst_block7800001D, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800001E, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000002: {generic: generic78000002, args: inst_block7800001D, decl_block_id: inst_block78000024, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000003: {generic: generic78000001, args: inst_block78000025, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000004: {generic: generic78000003, args: inst_block78000028, decl_block_id: inst_block78000029, decl_has_error: 0, definition_block_id: inst_block7800002A, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000005: {generic: generic78000001, args: inst_block78000028, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000030, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000006: {generic: generic78000002, args: inst_block78000028, decl_block_id: inst_block78000031, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000007: {generic: generic78000004, args: inst_block78000028, decl_block_id: inst_block78000035, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000008: {generic: generic78000001, args: inst_block78000032, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000009: {generic: generic78000002, args: inst_block78000032, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000A: {generic: generic78000003, args: inst_block78000038, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000B: {generic: generic78000005, args: inst_block78000016, decl_block_id: inst_block7800003D, decl_has_error: 0, definition_block_id: inst_block78000086, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000C: {generic: generic78000005, args: inst_block78000040, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000D: {generic: generic78000006, args: inst_block78000016, decl_block_id: inst_block78000047, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000E: {generic: generic78000007, args: inst_block7800004C, decl_block_id: inst_block7800004E, decl_has_error: 0, definition_block_id: inst_block7800004F, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800000F: {generic: generic78000001, args: inst_block78000056, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000057, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000010: {generic: generic78000002, args: inst_block78000056, decl_block_id: inst_block78000058, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000011: {generic: generic78000008, args: inst_block7800004C, decl_block_id: inst_block7800005E, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000012: {generic: generic78000001, args: inst_block78000059, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000013: {generic: generic78000002, args: inst_block78000059, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000014: {generic: generic78000001, args: inst_block7800005B, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000015: {generic: generic78000002, args: inst_block7800005B, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000016: {generic: generic78000007, args: inst_block78000061, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000017: {generic: generic78000009, args: inst_block78000069, decl_block_id: inst_block7800006B, decl_has_error: 0, definition_block_id: inst_block7800006C, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000018: {generic: generic78000001, args: inst_block78000073, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block78000074, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000019: {generic: generic78000002, args: inst_block78000073, decl_block_id: inst_block78000075, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001A: {generic: generic7800000A, args: inst_block78000069, decl_block_id: inst_block7800007D, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001B: {generic: generic78000001, args: inst_block78000076, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001C: {generic: generic78000002, args: inst_block78000076, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001D: {generic: generic78000001, args: inst_block78000078, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001E: {generic: generic78000002, args: inst_block78000078, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific7800001F: {generic: generic78000001, args: inst_block7800007A, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000020: {generic: generic78000002, args: inst_block7800007A, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000021: {generic: generic78000009, args: inst_block78000080, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000022: {generic: generic78000005, args: inst_block78000087, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000023: {generic: generic78000001, args: inst_block78000089, decl_block_id: inst_block_empty, decl_has_error: 0, definition_block_id: inst_block7800008A, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000024: {generic: generic78000001, args: inst_block7800008C, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000025: {generic: generic78000002, args: inst_block78000089, decl_block_id: inst_block7800008D, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific78000026: {generic: generic78000002, args: inst_block7800008C, decl_block_id: inst_block<none>, decl_has_error: 0, definition_block_id: inst_block<none>, definition_has_error: 0}
|
||||
// CHECK:STDOUT: specific_interfaces:
|
||||
// CHECK:STDOUT: specific_interface78000000: {interface_id: interface78000000, specific_id: specific<none>}
|
||||
// CHECK:STDOUT: struct_type_fields:
|
||||
|
||||
@@ -104,29 +104,11 @@ static auto DiagnoseIncompleteNamedConstraint(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Have the resolved specific know whether any instructions in the
|
||||
// declaration or definition contain an ErrorInst, instead of having to do a
|
||||
// linear scan here.
|
||||
static auto SpecificContainsError(Context& context,
|
||||
SemIR::SpecificId specific_id) -> bool {
|
||||
if (!specific_id.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& specific = context.specifics().Get(specific_id);
|
||||
auto block_ids = {specific.decl_block_id, specific.definition_block_id};
|
||||
|
||||
for (auto block_id : block_ids) {
|
||||
if (block_id.has_value()) {
|
||||
for (auto inst_id : context.inst_blocks().Get(block_id)) {
|
||||
if (context.constant_values().Get(inst_id) ==
|
||||
SemIR::ErrorInst::ConstantId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// Returns true if either eval block contains an error.
|
||||
static auto SpecificHasError(Context& context, SemIR::SpecificId specific_id)
|
||||
-> bool {
|
||||
return specific_id.has_value() &&
|
||||
context.specifics().Get(specific_id).HasError();
|
||||
}
|
||||
|
||||
static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
|
||||
@@ -146,7 +128,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
if (interface.generic_id.has_value()) {
|
||||
ResolveSpecificDefinition(context, loc_id, extends.specific_id);
|
||||
if (SpecificContainsError(context, extends.specific_id)) {
|
||||
if (SpecificHasError(context, extends.specific_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -158,7 +140,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
|
||||
auto interface_with_self_specific_id = MakeSpecificWithInnerSelf(
|
||||
context, loc_id, interface.generic_id, interface.generic_with_self_id,
|
||||
extends.specific_id, context.constant_values().Get(self_facet));
|
||||
if (SpecificContainsError(context, interface_with_self_specific_id)) {
|
||||
if (SpecificHasError(context, interface_with_self_specific_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +157,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
if (constraint.generic_id.has_value()) {
|
||||
ResolveSpecificDefinition(context, loc_id, extends.specific_id);
|
||||
if (SpecificContainsError(context, extends.specific_id)) {
|
||||
if (SpecificHasError(context, extends.specific_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +169,7 @@ static auto RequireCompleteFacetType(Context& context, SemIR::LocId loc_id,
|
||||
auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
|
||||
context, loc_id, constraint.generic_id, constraint.generic_with_self_id,
|
||||
extends.specific_id, context.constant_values().Get(self_facet));
|
||||
if (SpecificContainsError(context, constraint_with_self_specific_id)) {
|
||||
if (SpecificHasError(context, constraint_with_self_specific_id)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -972,7 +954,7 @@ static auto IdentifyFacetType(Context& context, SemIR::LocId loc_id,
|
||||
auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
|
||||
context, loc_id, constraint.generic_id,
|
||||
constraint.generic_with_self_id, extends.specific_id, self_facet);
|
||||
if (SpecificContainsError(context, constraint_with_self_specific_id)) {
|
||||
if (SpecificHasError(context, constraint_with_self_specific_id)) {
|
||||
return SemIR::IdentifiedFacetTypeId::None;
|
||||
}
|
||||
|
||||
@@ -1031,7 +1013,7 @@ static auto IdentifyFacetType(Context& context, SemIR::LocId loc_id,
|
||||
auto constraint_with_self_specific_id = MakeSpecificWithInnerSelf(
|
||||
context, loc_id, constraint.generic_id,
|
||||
constraint.generic_with_self_id, impls.specific_id, self_facet);
|
||||
if (SpecificContainsError(context, constraint_with_self_specific_id)) {
|
||||
if (SpecificHasError(context, constraint_with_self_specific_id)) {
|
||||
return SemIR::IdentifiedFacetTypeId::None;
|
||||
}
|
||||
|
||||
|
||||
@@ -405,6 +405,16 @@ LLVM_DUMP_METHOD auto Dump(const File& file, RequireImplsId require_impls_id)
|
||||
return out.TakeStr();
|
||||
}
|
||||
|
||||
static auto DumpEvalBlock(const File& file, llvm::StringRef region_name,
|
||||
InstBlockId block_id, bool has_error) -> std::string {
|
||||
RawStringOstream out;
|
||||
if (block_id.has_value()) {
|
||||
out << "\nspecific " << region_name << " block"
|
||||
<< (has_error ? " (has error)" : "") << ": " << Dump(file, block_id);
|
||||
}
|
||||
return out.TakeStr();
|
||||
}
|
||||
|
||||
LLVM_DUMP_METHOD auto Dump(const File& file, SpecificId specific_id)
|
||||
-> std::string {
|
||||
RawStringOstream out;
|
||||
@@ -413,14 +423,11 @@ LLVM_DUMP_METHOD auto Dump(const File& file, SpecificId specific_id)
|
||||
const auto& specific = file.specifics().Get(specific_id);
|
||||
out << '\n'
|
||||
<< Dump(file, specific.args_id) << '\n'
|
||||
<< DumpGenericSummary(file, specific.generic_id);
|
||||
if (specific.decl_block_id.has_value()) {
|
||||
out << "\nspecific decl block: " << Dump(file, specific.decl_block_id);
|
||||
}
|
||||
if (specific.definition_block_id.has_value()) {
|
||||
out << "\nspecific definition block: "
|
||||
<< Dump(file, specific.definition_block_id);
|
||||
}
|
||||
<< DumpGenericSummary(file, specific.generic_id)
|
||||
<< DumpEvalBlock(file, "decl", specific.decl_block_id,
|
||||
specific.decl_block_has_error)
|
||||
<< DumpEvalBlock(file, "definition", specific.definition_block_id,
|
||||
specific.definition_block_has_error);
|
||||
}
|
||||
return out.TakeStr();
|
||||
}
|
||||
|
||||
@@ -72,9 +72,15 @@ class GenericStore : public ValueStore<GenericId, Generic, Tag<CheckIRId>> {
|
||||
// values for the compile-time parameters themselves.
|
||||
struct Specific : Printable<Specific> {
|
||||
auto Print(llvm::raw_ostream& out) const -> void {
|
||||
out << "{generic: " << generic_id << ", args: " << args_id
|
||||
<< ", decl_block_id: " << decl_block_id
|
||||
<< ", definition_block_id: " << definition_block_id << "}";
|
||||
auto print_block = [&](llvm::StringLiteral region, InstBlockId id,
|
||||
bool has_error) {
|
||||
out << ", " << region << "_block_id: " << id << ", " << region
|
||||
<< "_has_error: " << has_error;
|
||||
};
|
||||
out << "{generic: " << generic_id << ", args: " << args_id;
|
||||
print_block("decl", decl_block_id, decl_block_has_error);
|
||||
print_block("definition", definition_block_id, definition_block_has_error);
|
||||
out << "}";
|
||||
}
|
||||
|
||||
// Returns true if this specific has never been resolved. Such specifics are
|
||||
@@ -95,6 +101,11 @@ struct Specific : Printable<Specific> {
|
||||
: definition_block_id;
|
||||
}
|
||||
|
||||
// Returns whether either block has an error.
|
||||
auto HasError() const -> bool {
|
||||
return decl_block_has_error || definition_block_has_error;
|
||||
}
|
||||
|
||||
// The generic that this is a specific version of.
|
||||
GenericId generic_id;
|
||||
// Argument values, corresponding to the bindings in `Generic::bindings_id`.
|
||||
@@ -107,6 +118,11 @@ struct Specific : Printable<Specific> {
|
||||
InstBlockId decl_block_id = InstBlockId::None;
|
||||
// The value block for the definition region of the specific.
|
||||
InstBlockId definition_block_id = InstBlockId::None;
|
||||
|
||||
// Whether the corresponding block contains an error. These are stored
|
||||
// directly on Specific so that they pack together.
|
||||
bool decl_block_has_error = false;
|
||||
bool definition_block_has_error = false;
|
||||
};
|
||||
|
||||
// Provides storage for deduplicated specifics, which represent generics plus
|
||||
|
||||
Reference in New Issue
Block a user