Skip to content

Commit

Permalink
Convert array bounds to IntLiteral.
Browse files Browse the repository at this point in the history
  • Loading branch information
zygoloid committed Nov 14, 2024
1 parent 4967122 commit 3a61b81
Show file tree
Hide file tree
Showing 109 changed files with 42,531 additions and 2,576 deletions.
18 changes: 12 additions & 6 deletions toolchain/check/handle_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "toolchain/check/convert.h"
#include "toolchain/check/handle.h"
#include "toolchain/parse/node_kind.h"
#include "toolchain/sem_ir/builtin_inst_kind.h"

namespace Carbon::Check {

Expand Down Expand Up @@ -33,24 +34,29 @@ auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool {
auto [element_type_node_id, element_type_inst_id] =
context.node_stack().PopExprWithNodeId();

// The array bound must be a constant.
auto element_type_id =
ExprAsType(context, element_type_node_id, element_type_inst_id).type_id;

// The array bound must be a constant. Diagnose this prior to conversion
// because conversion to `IntLiteral` will produce a generic "non-constant
// call to compile-time-only function" error.
//
// TODO: Should we support runtime-phase bounds in cases such as:
// comptime fn F(n: i32) -> type { return [i32; n]; }
auto bound_inst = context.constant_values().Get(bound_inst_id);
if (!bound_inst.is_constant()) {
if (!context.constant_values().Get(bound_inst_id).is_constant()) {
CARBON_DIAGNOSTIC(InvalidArrayExpr, Error, "array bound is not a constant");
context.emitter().Emit(bound_inst_id, InvalidArrayExpr);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}

bound_inst_id = ConvertToValueOfType(
context, context.insts().GetLocId(bound_inst_id), bound_inst_id,
context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType));
context.AddInstAndPush<SemIR::ArrayType>(
node_id, {.type_id = SemIR::TypeId::TypeType,
.bound_id = bound_inst_id,
.element_type_id = ExprAsType(context, element_type_node_id,
element_type_inst_id)
.type_id});
.element_type_id = element_type_id});
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions toolchain/check/handle_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ auto HandleParseNode(Context& context,
auto& function = context.functions().Get(function_id);
if (IsValidBuiltinDeclaration(context, function, builtin_kind)) {
function.builtin_function_kind = builtin_kind;
// Build an empty generic definition if this is a generic builtin.
StartGenericDefinition(context);
FinishGenericDefinition(context, function.generic_id);
} else {
CARBON_DIAGNOSTIC(InvalidBuiltinSignature, Error,
"invalid signature for builtin function \"{0}\"",
Expand Down
723 changes: 708 additions & 15 deletions toolchain/check/testdata/array/array_in_place.carbon

Large diffs are not rendered by default.

747 changes: 720 additions & 27 deletions toolchain/check/testdata/array/array_vs_tuple.carbon

Large diffs are not rendered by default.

713 changes: 703 additions & 10 deletions toolchain/check/testdata/array/assign_return_value.carbon

Large diffs are not rendered by default.

717 changes: 705 additions & 12 deletions toolchain/check/testdata/array/assign_var.carbon

Large diffs are not rendered by default.

803 changes: 755 additions & 48 deletions toolchain/check/testdata/array/base.carbon

Large diffs are not rendered by default.

866 changes: 825 additions & 41 deletions toolchain/check/testdata/array/canonicalize_index.carbon

Large diffs are not rendered by default.

701 changes: 698 additions & 3 deletions toolchain/check/testdata/array/fail_bound_negative.carbon

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions toolchain/check/testdata/array/fail_bound_overflow.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -402,27 +402,35 @@ var b: [1; 39999999999999999993];
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.9)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: Core.IntLiteral]() -> @Convert.2.%.1 (%.9) = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.3(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type unsigned, %N [symbolic = %.1 (constants.%.11)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: Core.IntLiteral]() -> @Convert.3.%.1 (%.11) = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.4(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.9)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @Convert.4.%.1 (%.9)]() -> Core.IntLiteral = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.5(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type unsigned, %N [symbolic = %.1 (constants.%.11)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @Convert.5.%.1 (%.11)]() -> Core.IntLiteral = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand All @@ -438,27 +446,35 @@ var b: [1; 39999999999999999993];
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.9)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: Core.IntLiteral]() -> @Convert.7.%.1 (%.9) = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.8(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type unsigned, %N [symbolic = %.1 (constants.%.11)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: Core.IntLiteral]() -> @Convert.8.%.1 (%.11) = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.9(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type signed, %N [symbolic = %.1 (constants.%.9)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @Convert.9.%.1 (%.9)]() -> Core.IntLiteral = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Convert.10(constants.%N: Core.IntLiteral) {
// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N)]
// CHECK:STDOUT: %.1: type = int_type unsigned, %N [symbolic = %.1 (constants.%.11)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
// CHECK:STDOUT: fn[%self.param_patt: @Convert.10.%.1 (%.11)]() -> Core.IntLiteral = "int.convert_checked";
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand Down
Loading

0 comments on commit 3a61b81

Please sign in to comment.