|
|
@@ -26,7 +26,8 @@ namespace {
|
|
|
// matter except when it influences which error is diagnosed.
|
|
|
class DeductionWorklist {
|
|
|
public:
|
|
|
- explicit DeductionWorklist(Context& context) : context_(context) {}
|
|
|
+ // `context` must not be null.
|
|
|
+ explicit DeductionWorklist(Context* context) : context_(context) {}
|
|
|
|
|
|
struct PendingDeduction {
|
|
|
SemIR::InstId param;
|
|
|
@@ -44,7 +45,7 @@ class DeductionWorklist {
|
|
|
// Adds a single (param, arg) type deduction.
|
|
|
auto Add(SemIR::TypeId param, SemIR::TypeId arg, bool needs_substitution)
|
|
|
-> void {
|
|
|
- Add(context_.types().GetInstId(param), context_.types().GetInstId(arg),
|
|
|
+ Add(context_->types().GetInstId(param), context_->types().GetInstId(arg),
|
|
|
needs_substitution);
|
|
|
}
|
|
|
|
|
|
@@ -54,8 +55,8 @@ class DeductionWorklist {
|
|
|
if (!param.has_value() || !arg.has_value()) {
|
|
|
return;
|
|
|
}
|
|
|
- auto& param_specific = context_.specifics().Get(param);
|
|
|
- auto& arg_specific = context_.specifics().Get(arg);
|
|
|
+ auto& param_specific = context_->specifics().Get(param);
|
|
|
+ auto& arg_specific = context_->specifics().Get(arg);
|
|
|
if (param_specific.generic_id != arg_specific.generic_id) {
|
|
|
// TODO: Decide whether to error on this or just treat the specific as
|
|
|
// non-deduced. For now we treat it as non-deduced.
|
|
|
@@ -81,13 +82,13 @@ class DeductionWorklist {
|
|
|
|
|
|
auto AddAll(SemIR::InstBlockId params, llvm::ArrayRef<SemIR::InstId> args,
|
|
|
bool needs_substitution) -> void {
|
|
|
- AddAll(context_.inst_blocks().Get(params), args, needs_substitution);
|
|
|
+ AddAll(context_->inst_blocks().Get(params), args, needs_substitution);
|
|
|
}
|
|
|
|
|
|
auto AddAll(SemIR::StructTypeFieldsId params, SemIR::StructTypeFieldsId args,
|
|
|
bool needs_substitution) -> void {
|
|
|
- const auto& param_fields = context_.struct_type_fields().Get(params);
|
|
|
- const auto& arg_fields = context_.struct_type_fields().Get(args);
|
|
|
+ const auto& param_fields = context_->struct_type_fields().Get(params);
|
|
|
+ const auto& arg_fields = context_->struct_type_fields().Get(args);
|
|
|
if (param_fields.size() != arg_fields.size()) {
|
|
|
// TODO: Decide whether to error on this or just treat the parameter list
|
|
|
// as non-deduced. For now we treat it as non-deduced.
|
|
|
@@ -108,21 +109,21 @@ class DeductionWorklist {
|
|
|
|
|
|
auto AddAll(SemIR::InstBlockId params, SemIR::InstBlockId args,
|
|
|
bool needs_substitution) -> void {
|
|
|
- AddAll(context_.inst_blocks().Get(params), context_.inst_blocks().Get(args),
|
|
|
- needs_substitution);
|
|
|
+ AddAll(context_->inst_blocks().Get(params),
|
|
|
+ context_->inst_blocks().Get(args), needs_substitution);
|
|
|
}
|
|
|
|
|
|
auto AddAll(SemIR::TypeBlockId params, SemIR::TypeBlockId args,
|
|
|
bool needs_substitution) -> void {
|
|
|
- AddAll(context_.type_blocks().Get(params), context_.type_blocks().Get(args),
|
|
|
- needs_substitution);
|
|
|
+ AddAll(context_->type_blocks().Get(params),
|
|
|
+ context_->type_blocks().Get(args), needs_substitution);
|
|
|
}
|
|
|
|
|
|
auto AddAll(SemIR::FacetTypeId params, SemIR::FacetTypeId args,
|
|
|
bool needs_substitution) -> void {
|
|
|
const auto& param_impls =
|
|
|
- context_.facet_types().Get(params).impls_constraints;
|
|
|
- const auto& arg_impls = context_.facet_types().Get(args).impls_constraints;
|
|
|
+ context_->facet_types().Get(params).impls_constraints;
|
|
|
+ const auto& arg_impls = context_->facet_types().Get(args).impls_constraints;
|
|
|
// TODO: Decide whether to error on these or just treat the parameter list
|
|
|
// as non-deduced. For now we treat it as non-deduced.
|
|
|
if (param_impls.size() != 1 || arg_impls.size() != 1) {
|
|
|
@@ -182,7 +183,7 @@ class DeductionWorklist {
|
|
|
auto PopNext() -> PendingDeduction { return deductions_.pop_back_val(); }
|
|
|
|
|
|
private:
|
|
|
- Context& context_;
|
|
|
+ Context* context_;
|
|
|
llvm::SmallVector<PendingDeduction> deductions_;
|
|
|
};
|
|
|
|
|
|
@@ -191,8 +192,8 @@ class DeductionContext {
|
|
|
public:
|
|
|
// Preparse to perform deduction. If an enclosing specific or self type
|
|
|
// are provided, adds the corresponding arguments as known arguments that will
|
|
|
- // not be deduced.
|
|
|
- DeductionContext(Context& context, SemIR::LocId loc_id,
|
|
|
+ // not be deduced. `context` must not be null.
|
|
|
+ DeductionContext(Context* context, SemIR::LocId loc_id,
|
|
|
SemIR::GenericId generic_id,
|
|
|
SemIR::SpecificId enclosing_specific_id,
|
|
|
SemIR::InstId self_type_id, bool diagnose);
|
|
|
@@ -262,11 +263,11 @@ static auto NoteGenericHere(Context& context, SemIR::GenericId generic_id,
|
|
|
diag.Note(context.generics().Get(generic_id).decl_id, DeductionGenericHere);
|
|
|
}
|
|
|
|
|
|
-DeductionContext::DeductionContext(Context& context, SemIR::LocId loc_id,
|
|
|
+DeductionContext::DeductionContext(Context* context, SemIR::LocId loc_id,
|
|
|
SemIR::GenericId generic_id,
|
|
|
SemIR::SpecificId enclosing_specific_id,
|
|
|
SemIR::InstId self_type_id, bool diagnose)
|
|
|
- : context_(&context),
|
|
|
+ : context_(context),
|
|
|
loc_id_(loc_id),
|
|
|
generic_id_(generic_id),
|
|
|
diagnose_(diagnose),
|
|
|
@@ -277,16 +278,16 @@ DeductionContext::DeductionContext(Context& context, SemIR::LocId loc_id,
|
|
|
|
|
|
// Initialize the deduced arguments to `None`.
|
|
|
result_arg_ids_.resize(
|
|
|
- context.inst_blocks()
|
|
|
- .Get(context.generics().Get(generic_id_).bindings_id)
|
|
|
+ context->inst_blocks()
|
|
|
+ .Get(context->generics().Get(generic_id_).bindings_id)
|
|
|
.size(),
|
|
|
SemIR::InstId::None);
|
|
|
|
|
|
if (enclosing_specific_id.has_value()) {
|
|
|
// Copy any outer generic arguments from the specified instance and prepare
|
|
|
// to substitute them into the function declaration.
|
|
|
- auto args = context.inst_blocks().Get(
|
|
|
- context.specifics().Get(enclosing_specific_id).args_id);
|
|
|
+ auto args = context->inst_blocks().Get(
|
|
|
+ context->specifics().Get(enclosing_specific_id).args_id);
|
|
|
llvm::copy(args, result_arg_ids_.begin());
|
|
|
|
|
|
// TODO: Subst is linear in the length of the substitutions list. Change
|
|
|
@@ -295,7 +296,7 @@ DeductionContext::DeductionContext(Context& context, SemIR::LocId loc_id,
|
|
|
for (auto [i, subst_inst_id] : llvm::enumerate(args)) {
|
|
|
substitutions_.push_back(
|
|
|
{.bind_id = SemIR::CompileTimeBindIndex(i),
|
|
|
- .replacement_id = context.constant_values().Get(subst_inst_id)});
|
|
|
+ .replacement_id = context->constant_values().Get(subst_inst_id)});
|
|
|
}
|
|
|
first_deduced_index_ = SemIR::CompileTimeBindIndex(args.size());
|
|
|
}
|
|
|
@@ -306,7 +307,7 @@ DeductionContext::DeductionContext(Context& context, SemIR::LocId loc_id,
|
|
|
result_arg_ids_[self_index.index] = self_type_id;
|
|
|
substitutions_.push_back(
|
|
|
{.bind_id = SemIR::CompileTimeBindIndex(self_index),
|
|
|
- .replacement_id = context.constant_values().Get(self_type_id)});
|
|
|
+ .replacement_id = context->constant_values().Get(self_type_id)});
|
|
|
first_deduced_index_ = SemIR::CompileTimeBindIndex(self_index.index + 1);
|
|
|
}
|
|
|
|
|
|
@@ -626,8 +627,9 @@ auto DeduceGenericCallArguments(
|
|
|
[[maybe_unused]] SemIR::InstBlockId implicit_params_id,
|
|
|
SemIR::InstBlockId params_id, [[maybe_unused]] SemIR::InstId self_id,
|
|
|
llvm::ArrayRef<SemIR::InstId> arg_ids) -> SemIR::SpecificId {
|
|
|
- DeductionContext deduction(context, loc_id, generic_id, enclosing_specific_id,
|
|
|
- self_type_id, /*diagnose=*/true);
|
|
|
+ DeductionContext deduction(&context, loc_id, generic_id,
|
|
|
+ enclosing_specific_id, self_type_id,
|
|
|
+ /*diagnose=*/true);
|
|
|
|
|
|
// Prepare to perform deduction of the explicit parameters against their
|
|
|
// arguments.
|
|
|
@@ -645,7 +647,7 @@ auto DeduceImplArguments(Context& context, SemIR::LocId loc_id, DeduceImpl impl,
|
|
|
SemIR::ConstantId self_id,
|
|
|
SemIR::SpecificId constraint_specific_id)
|
|
|
-> SemIR::SpecificId {
|
|
|
- DeductionContext deduction(context, loc_id, impl.generic_id,
|
|
|
+ DeductionContext deduction(&context, loc_id, impl.generic_id,
|
|
|
/*enclosing_specific_id=*/SemIR::SpecificId::None,
|
|
|
/*self_type_id=*/SemIR::InstId::None,
|
|
|
/*diagnose=*/false);
|