mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:51:12 +01:00
Ensure a location for monomorphization diagnostics in call argument deduction (#7401)
If the deduction fails while forming the parameter type, ensure that we print an actual diagnostic saying what went wrong. And always ensure that an invalid array bounds error points at a location. The `inst_id` given to `EvalConstantInst` always has a location, but the `bounds_id` instruction inside it may be canonical when it's coming from inside a larger type. So when it is, fall back to using the location of the whole array inst.
This commit is contained in:
@@ -66,6 +66,13 @@ auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
|
||||
"Unexpected inst {0} for template constant int", bound_inst);
|
||||
return ConstantEvalResult::NewSamePhase(inst);
|
||||
}
|
||||
|
||||
auto orig_inst = context.insts().GetAs<SemIR::ArrayType>(inst_id);
|
||||
auto error_loc =
|
||||
context.insts().GetCanonicalLocId(orig_inst.bound_id).has_value()
|
||||
? orig_inst.bound_id
|
||||
: inst_id;
|
||||
|
||||
// TODO: We should check that the size of the resulting array type
|
||||
// fits in 64 bits, not just that the bound does. Should we use a
|
||||
// 32-bit limit for 32-bit targets?
|
||||
@@ -74,17 +81,15 @@ auto EvalConstantInst(Context& context, SemIR::InstId inst_id,
|
||||
bound_val.isNegative()) {
|
||||
CARBON_DIAGNOSTIC(ArrayBoundNegative, Error,
|
||||
"array bound of {0} is negative", TypedInt);
|
||||
context.emitter().Emit(
|
||||
context.insts().GetAs<SemIR::ArrayType>(inst_id).bound_id,
|
||||
ArrayBoundNegative, {.type = int_bound->type_id, .value = bound_val});
|
||||
context.emitter().Emit(error_loc, ArrayBoundNegative,
|
||||
{.type = int_bound->type_id, .value = bound_val});
|
||||
return ConstantEvalResult::Error;
|
||||
}
|
||||
if (bound_val.getActiveBits() > 64) {
|
||||
CARBON_DIAGNOSTIC(ArrayBoundTooLarge, Error,
|
||||
"array bound of {0} is too large", TypedInt);
|
||||
context.emitter().Emit(
|
||||
context.insts().GetAs<SemIR::ArrayType>(inst_id).bound_id,
|
||||
ArrayBoundTooLarge, {.type = int_bound->type_id, .value = bound_val});
|
||||
context.emitter().Emit(error_loc, ArrayBoundTooLarge,
|
||||
{.type = int_bound->type_id, .value = bound_val});
|
||||
return ConstantEvalResult::Error;
|
||||
}
|
||||
return ConstantEvalResult::NewSamePhase(inst);
|
||||
|
||||
Reference in New Issue
Block a user