diff --git a/toolchain/check/deduce.cpp b/toolchain/check/deduce.cpp index 12f89bf5e42e..fed35280477d 100644 --- a/toolchain/check/deduce.cpp +++ b/toolchain/check/deduce.cpp @@ -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 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 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 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);