Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle runtime implicit parameters, and self outside of methods #4361

Merged
merged 5 commits into from
Oct 3, 2024

Conversation

josh11b
Copy link
Contributor

@josh11b josh11b commented Oct 1, 2024

Closes #4356, #4359

@josh11b josh11b requested review from zygoloid and removed request for chandlerc October 1, 2024 23:58
Comment on lines 437 to 483
auto RequireGenericParams(Context& context, SemIR::InstBlockId block_id)
-> void {
if (!block_id.is_valid() || block_id == SemIR::InstBlockId::Empty) {
return;
}

for (auto& inst_id : context.inst_blocks().Get(block_id)) {
if (!context.constant_values().Get(inst_id).is_constant()) {
// TODO: Change GetParamFromParamRefId to return the name instead of
// inspecting param.name_id.
auto [param_id, param] =
SemIR::Function::GetParamFromParamRefId(context.sem_ir(), inst_id);
if (param.name_id == SemIR::NameId::SelfValue) {
CARBON_DIAGNOSTIC(SelfParameterNotAllowed, Error,
"`self` parameter only allowed on functions");
context.emitter().Emit(inst_id, SelfParameterNotAllowed);

ReplaceInstructionWithError(context, inst_id);
} else if (!context.constant_values().Get(inst_id).is_constant()) {
CARBON_DIAGNOSTIC(GenericParamMustBeConstant, Error,
"parameters of generic types must be constant");
context.emitter().Emit(inst_id, GenericParamMustBeConstant);

// Replace the parameter with an invalid instruction so that we don't try
// constructing a generic based on it. Note this is updating the param
// refs block, not the actual params block, so will not be directly
// reflected in SemIR output.
inst_id = context.AddInstInNoBlock<SemIR::Param>(
context.insts().GetLocId(inst_id),
{.type_id = SemIR::TypeId::Error,
.name_id = SemIR::NameId::Base,
.runtime_index = SemIR::RuntimeParamIndex::Invalid});
ReplaceInstructionWithError(context, inst_id);
}
}
}

auto RequireGenericOrSelfImplicitParams(Context& context,
SemIR::InstBlockId block_id) -> void {
if (!block_id.is_valid() || block_id == SemIR::InstBlockId::Empty) {
return;
}
for (auto& inst_id : context.inst_blocks().Get(block_id)) {
// TODO: Change GetParamFromParamRefId to return the name instead of
// inspecting param.name_id.
auto [param_id, param] =
SemIR::Function::GetParamFromParamRefId(context.sem_ir(), inst_id);
if (param.name_id != SemIR::NameId::SelfValue &&
!context.constant_values().Get(inst_id).is_constant()) {
CARBON_DIAGNOSTIC(
ImplictParamMustBeConstant, Error,
"implicit parameters of functions must be constant or `self`");
context.emitter().Emit(inst_id, ImplictParamMustBeConstant);

ReplaceInstructionWithError(context, inst_id);
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look very similar; would it make sense to combine these into a single function? Eg:

auto RequireGenericParams(Context& context, SemIR::InstBlockId block_id, bool allow_self)
    -> void {
  if (!block_id.is_valid() || block_id == SemIR::InstBlockId::Empty) {
    return;
  }
  for (auto& inst_id : context.inst_blocks().Get(block_id)) {
    // TODO: Change GetParamFromParamRefId to return the name instead of
    // inspecting param.name_id.
    auto [param_id, param] =
        SemIR::Function::GetParamFromParamRefId(context.sem_ir(), inst_id);
    if (param.name_id == SemIR::NameId::SelfValue) {
      if (!allow_self) {
        CARBON_DIAGNOSTIC(SelfParameterNotAllowed, Error,
                          "`self` parameter only allowed on functions");
        context.emitter().Emit(inst_id, SelfParameterNotAllowed);

        ReplaceInstructionWithError(context, inst_id);
      }
    } else if (!context.constant_values().Get(inst_id).is_constant()) {
      CARBON_DIAGNOSTIC(
          ImplicitParamMustBeConstant, Error,
          "parameters of generic types must be constant");
      CARBON_DIAGNOSTIC(
          ImplictParamMustBeConstantOrSelf, Error,
          "implicit parameters of functions must be constant or `self`");
      context.emitter().Emit(
          inst_id,
          allow_self ? ImplicitParamMustBeConstantOrSelf : ImplicitParamMustBeConstant);

      ReplaceInstructionWithError(context, inst_id);
    }
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the function name, as discussed offline.

@josh11b josh11b enabled auto-merge October 2, 2024 23:44
@josh11b josh11b added this pull request to the merge queue Oct 3, 2024
Merged via the queue into carbon-language:trunk with commit d6d70bf Oct 3, 2024
8 checks passed
@josh11b josh11b deleted the fuzz branch October 3, 2024 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CHECK failure when using runtime implicit parameter
2 participants