mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 10:54:49 +01:00
consistently uses the caller's specific to get the callee's pattern type id (#7036)
`DoVarPreWorkImpl` was provided an incorrect pattern type while trying to match `var` parameters, which caused the toolchain to crash in `Convert`. This commit changes `DoVarPreWorkImpl`'s API so it derives the pattern type from the work item's pattern ID, rather than relying on an external source. --------- Co-authored-by: Dana Jansens <danakj@orodu.net>
This commit is contained in:
co-authored by
Dana Jansens
parent
12d7574636
commit
3cdb159067
@@ -19,6 +19,7 @@
|
||||
#include "toolchain/check/type.h"
|
||||
#include "toolchain/diagnostics/format_providers.h"
|
||||
#include "toolchain/sem_ir/expr_info.h"
|
||||
#include "toolchain/sem_ir/inst_kind.h"
|
||||
#include "toolchain/sem_ir/pattern.h"
|
||||
|
||||
namespace Carbon::Check {
|
||||
@@ -180,15 +181,21 @@ class MatchContext {
|
||||
return value_id;
|
||||
}
|
||||
|
||||
// Performs the core logic of matching a variable pattern whose type is
|
||||
// `pattern_type_id`, but returns the scrutinee that its subpattern should be
|
||||
// matched with, rather than pushing it onto the worklist. This is factored
|
||||
// out so it can be reused when handling a `FormBindingPattern` or
|
||||
// `FormParamPattern` with an initializing form.
|
||||
// Performs the core logic of matching a variable pattern, returning the
|
||||
// scrutinee that its subpattern should be matched with, rather than pushing
|
||||
// it onto the worklist. This is factored out so it can be reused when
|
||||
// handling a `FormBindingPattern` or `FormParamPattern` with an initializing
|
||||
// form.
|
||||
auto DoVarPreWorkImpl(State state, SemIR::TypeId pattern_type_id,
|
||||
SemIR::InstId scrutinee_id, WorkItem entry) const
|
||||
-> SemIR::InstId;
|
||||
|
||||
// Returns the scrutinee type from `pattern_id` when passed a `CallerState`,
|
||||
// and `param_pattern_type_id` otherwise.
|
||||
auto GetSpecificPatternTypeId(State state, SemIR::InstId pattern_id,
|
||||
SemIR::TypeId param_pattern_type_id)
|
||||
-> SemIR::TypeId;
|
||||
|
||||
// The stack of work to be processed.
|
||||
llvm::SmallVector<WorkItem> stack_;
|
||||
|
||||
@@ -444,10 +451,28 @@ static auto ParamKindFor(Context& context, SemIR::Inst param_pattern,
|
||||
}
|
||||
}
|
||||
|
||||
auto MatchContext::GetSpecificPatternTypeId(State state,
|
||||
SemIR::InstId pattern_id,
|
||||
SemIR::TypeId param_pattern_type_id)
|
||||
-> SemIR::TypeId {
|
||||
CARBON_KIND_SWITCH(state) {
|
||||
case CARBON_KIND(CallerState* caller): {
|
||||
auto& sem_ir = context_.sem_ir();
|
||||
return ExtractScrutineeType(
|
||||
sem_ir, SemIR::GetTypeOfInstInSpecific(
|
||||
sem_ir, caller->callee_specific_id, pattern_id));
|
||||
}
|
||||
default:
|
||||
return param_pattern_type_id;
|
||||
}
|
||||
}
|
||||
|
||||
auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
|
||||
SemIR::InstId scrutinee_id, WorkItem entry)
|
||||
-> void {
|
||||
AddAsPostWork(entry);
|
||||
auto pattern_type_id =
|
||||
GetSpecificPatternTypeId(state, entry.pattern_id, param_pattern.type_id);
|
||||
|
||||
// If `param_pattern` has initializing form, match it as a `VarPattern`
|
||||
// before matching it as a parameter pattern.
|
||||
@@ -463,7 +488,7 @@ auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
|
||||
}
|
||||
case SemIR::VarParamPattern::Kind: {
|
||||
scrutinee_id =
|
||||
DoVarPreWorkImpl(state, param_pattern.type_id, scrutinee_id, entry);
|
||||
DoVarPreWorkImpl(state, pattern_type_id, scrutinee_id, entry);
|
||||
entry.allow_unmarked_ref = true;
|
||||
break;
|
||||
}
|
||||
@@ -477,15 +502,10 @@ auto MatchContext::DoPreWork(State state, SemIR::AnyParamPattern param_pattern,
|
||||
if (scrutinee_id == SemIR::ErrorInst::InstId) {
|
||||
caller_state->call_args.push_back(SemIR::ErrorInst::InstId);
|
||||
} else {
|
||||
auto scrutinee_type_id = ExtractScrutineeType(
|
||||
context_.sem_ir(),
|
||||
SemIR::GetTypeOfInstInSpecific(context_.sem_ir(),
|
||||
caller_state->callee_specific_id,
|
||||
entry.pattern_id));
|
||||
caller_state->call_args.push_back(
|
||||
Convert(context_, SemIR::LocId(scrutinee_id), scrutinee_id,
|
||||
{.kind = ConversionKindFor(context_, param_pattern, entry),
|
||||
.type_id = scrutinee_type_id}));
|
||||
.type_id = pattern_type_id}));
|
||||
}
|
||||
// Do not traverse farther or schedule PostWork, because the caller side
|
||||
// of the pattern ends here.
|
||||
@@ -603,8 +623,10 @@ auto MatchContext::DoPostWork(State state,
|
||||
auto MatchContext::DoPreWork(State state, SemIR::VarPattern var_pattern,
|
||||
SemIR::InstId scrutinee_id, WorkItem entry)
|
||||
-> void {
|
||||
auto pattern_type_id =
|
||||
GetSpecificPatternTypeId(state, entry.pattern_id, var_pattern.type_id);
|
||||
auto new_scrutinee_id =
|
||||
DoVarPreWorkImpl(state, var_pattern.type_id, scrutinee_id, entry);
|
||||
DoVarPreWorkImpl(state, pattern_type_id, scrutinee_id, entry);
|
||||
if (need_subpattern_results()) {
|
||||
AddAsPostWork(entry);
|
||||
}
|
||||
@@ -638,8 +660,7 @@ auto MatchContext::DoVarPreWorkImpl(State state, SemIR::TypeId pattern_type_id,
|
||||
case CARBON_KIND(CallerState* _): {
|
||||
storage_id = AddInst<SemIR::TemporaryStorage>(
|
||||
context_, SemIR::LocId(entry.pattern_id),
|
||||
{.type_id =
|
||||
ExtractScrutineeType(context_.sem_ir(), pattern_type_id)});
|
||||
{.type_id = pattern_type_id});
|
||||
CARBON_CHECK(scrutinee_id.has_value());
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user