mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 06:34:41 +01:00
Avoid crash when deduce fails for imported generic (#5001)
An imported generic has bindings which are of type ImportRefLoaded, and if they come from another package, they have no entity name attached to them. Since a binding name is always a constant-time value, we can get the constant value instruction for the imported instruction to get a canonical non-imported instruction. And that one will have a local `NameId`. --------- Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
This commit is contained in:
@@ -506,6 +506,25 @@ auto DeductionContext::Deduce() -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gets the entity name of a generic binding. The generic binding may be an
|
||||
// imported instruction.
|
||||
static auto GetEntityNameForGenericBinding(Context& context,
|
||||
SemIR::InstId binding_id)
|
||||
-> SemIR::NameId {
|
||||
// If `binding_id` is imported, it may not have an entity name. Get a
|
||||
// canonical local instruction from its constant value which does.
|
||||
if (context.insts().Is<SemIR::ImportRefLoaded>(binding_id)) {
|
||||
binding_id = context.constant_values().GetConstantInstId(binding_id);
|
||||
}
|
||||
|
||||
if (auto bind_name =
|
||||
context.insts().TryGetAs<SemIR::AnyBindName>(binding_id)) {
|
||||
return context.entity_names().Get(bind_name->entity_name_id).name_id;
|
||||
} else {
|
||||
CARBON_FATAL("Instruction without entity name in generic binding position");
|
||||
}
|
||||
}
|
||||
|
||||
auto DeductionContext::CheckDeductionIsComplete() -> bool {
|
||||
// Check we deduced an argument value for every parameter, and convert each
|
||||
// argument to match the final parameter type after substituting any deduced
|
||||
@@ -518,16 +537,12 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool {
|
||||
context().generics().Get(generic_id_).bindings_id)[binding_index];
|
||||
if (!deduced_arg_id.has_value()) {
|
||||
if (diagnose_) {
|
||||
auto entity_name_id = context()
|
||||
.insts()
|
||||
.GetAs<SemIR::AnyBindName>(binding_id)
|
||||
.entity_name_id;
|
||||
CARBON_DIAGNOSTIC(DeductionIncomplete, Error,
|
||||
"cannot deduce value for generic parameter `{0}`",
|
||||
SemIR::NameId);
|
||||
auto diag = context().emitter().Build(
|
||||
loc_id_, DeductionIncomplete,
|
||||
context().entity_names().Get(entity_name_id).name_id);
|
||||
GetEntityNameForGenericBinding(context(), binding_id));
|
||||
NoteGenericHere(context(), generic_id_, diag);
|
||||
diag.Emit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user