mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Add a helpful note when using ** on number types. (#13871)
This commit is contained in:
parent
cd9af0f286
commit
15a6336bb4
@ -2215,6 +2215,12 @@ pub const SrcLoc = struct {
|
||||
assert(src_loc.file_scope.tree_loaded);
|
||||
return nodeToSpan(tree, node);
|
||||
},
|
||||
.node_offset_main_token => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(gpa);
|
||||
const node = src_loc.declRelativeToNodeIndex(node_off);
|
||||
const main_token = tree.nodes.items(.main_token)[node];
|
||||
return tokensToSpan(tree, main_token, main_token, main_token);
|
||||
},
|
||||
.node_offset_bin_op => |node_off| {
|
||||
const tree = try src_loc.file_scope.getTree(gpa);
|
||||
const node = src_loc.declRelativeToNodeIndex(node_off);
|
||||
@ -3009,6 +3015,10 @@ pub const LazySrcLoc = union(enum) {
|
||||
/// from its containing Decl node AST index.
|
||||
/// The Decl is determined contextually.
|
||||
node_offset: TracedOffset,
|
||||
/// The source location points to the main token of an AST node, found
|
||||
/// by taking this AST node index offset from the containing Decl AST node.
|
||||
/// The Decl is determined contextually.
|
||||
node_offset_main_token: i32,
|
||||
/// The source location points to the beginning of a struct initializer.
|
||||
/// The Decl is determined contextually.
|
||||
node_offset_initializer: i32,
|
||||
@ -3275,6 +3285,7 @@ pub const LazySrcLoc = union(enum) {
|
||||
.byte_offset,
|
||||
.token_offset,
|
||||
.node_offset,
|
||||
.node_offset_main_token,
|
||||
.node_offset_initializer,
|
||||
.node_offset_var_decl_ty,
|
||||
.node_offset_var_decl_align,
|
||||
|
||||
37
src/Sema.zig
37
src/Sema.zig
@ -12059,8 +12059,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
|
||||
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs);
|
||||
const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs);
|
||||
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs) orelse {
|
||||
return sema.fail(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});
|
||||
};
|
||||
const rhs_info = try sema.getArrayCatInfo(block, rhs_src, rhs) orelse {
|
||||
return sema.fail(block, rhs_src, "expected indexable; found '{}'", .{rhs_ty.fmt(sema.mod)});
|
||||
};
|
||||
|
||||
const resolved_elem_ty = t: {
|
||||
var trash_block = block.makeSubBlock();
|
||||
@ -12220,7 +12224,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
return block.addAggregateInit(result_ty, element_refs);
|
||||
}
|
||||
|
||||
fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) !Type.ArrayInfo {
|
||||
fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) !?Type.ArrayInfo {
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.Array => return operand_ty.arrayInfo(),
|
||||
@ -12248,7 +12252,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return sema.fail(block, src, "expected indexable; found '{}'", .{operand_ty.fmt(sema.mod)});
|
||||
return null;
|
||||
}
|
||||
|
||||
fn analyzeTupleMul(
|
||||
@ -12330,16 +12334,33 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
const lhs_ty = sema.typeOf(lhs);
|
||||
const src: LazySrcLoc = inst_data.src();
|
||||
const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node };
|
||||
const operator_src: LazySrcLoc = .{ .node_offset_main_token = inst_data.src_node };
|
||||
const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node };
|
||||
|
||||
// In `**` rhs must be comptime-known, but lhs can be runtime-known
|
||||
const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known");
|
||||
|
||||
if (lhs_ty.isTuple()) {
|
||||
// In `**` rhs must be comptime-known, but lhs can be runtime-known
|
||||
const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known");
|
||||
return sema.analyzeTupleMul(block, inst_data.src_node, lhs, factor);
|
||||
}
|
||||
|
||||
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs);
|
||||
// Analyze the lhs first, to catch the case that someone tried to do exponentiation
|
||||
const lhs_info = try sema.getArrayCatInfo(block, lhs_src, lhs) orelse {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, lhs_src, "expected indexable; found '{}'", .{lhs_ty.fmt(sema.mod)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
switch (lhs_ty.zigTypeTag()) {
|
||||
.Int, .Float, .ComptimeFloat, .ComptimeInt, .Vector => {
|
||||
try sema.errNote(block, operator_src, msg, "this operator multiplies arrays; use std.math.pow for exponentiation", .{});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
};
|
||||
|
||||
// In `**` rhs must be comptime-known, but lhs can be runtime-known
|
||||
const factor = try sema.resolveInt(block, rhs_src, extra.rhs, Type.usize, "array multiplication factor must be comptime-known");
|
||||
|
||||
const result_len_u64 = std.math.mul(u64, lhs_info.len, factor) catch
|
||||
return sema.fail(block, rhs_src, "operation results in overflow", .{});
|
||||
|
||||
10
test/cases/compile_errors/array_mult_with_number_type.zig
Normal file
10
test/cases/compile_errors/array_mult_with_number_type.zig
Normal file
@ -0,0 +1,10 @@
|
||||
export fn entry(base: f32, exponent: f32) f32 {
|
||||
return base ** exponent;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:12: error: expected indexable; found 'f32'
|
||||
// :2:17: note: this operator multiplies arrays; use std.math.pow for exponentiation
|
||||
Loading…
x
Reference in New Issue
Block a user