Merge some cases of resolveTypeOfNodeInternal
This commit is contained in:
parent
ea1ad532a2
commit
45c7f9671c
201
src/analysis.zig
201
src/analysis.zig
@ -474,25 +474,22 @@ pub fn resolveReturnType(
|
|||||||
|
|
||||||
if (fn_decl.ast.return_type == 0) return null;
|
if (fn_decl.ast.return_type == 0) return null;
|
||||||
const return_type = fn_decl.ast.return_type;
|
const return_type = fn_decl.ast.return_type;
|
||||||
|
const ret = .{ .node = return_type, .handle = handle };
|
||||||
|
const child_type = (try resolveTypeOfNodeInternal(store, arena, ret, bound_type_params)) orelse
|
||||||
|
return null;
|
||||||
|
|
||||||
const is_inferred_error = tree.tokens.items(.tag)[tree.firstToken(return_type) - 1] == .bang;
|
const is_inferred_error = tree.tokens.items(.tag)[tree.firstToken(return_type) - 1] == .bang;
|
||||||
return if (is_inferred_error) block: {
|
if (is_inferred_error) {
|
||||||
const child_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = return_type,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
const child_type_node = switch (child_type.type.data) {
|
const child_type_node = switch (child_type.type.data) {
|
||||||
.other => |n| n,
|
.other => |n| n,
|
||||||
else => return null,
|
else => return null,
|
||||||
};
|
};
|
||||||
break :block TypeWithHandle{
|
return TypeWithHandle{
|
||||||
.type = .{ .data = .{ .error_union = child_type_node }, .is_type_val = false },
|
.type = .{ .data = .{ .error_union = child_type_node }, .is_type_val = false },
|
||||||
.handle = child_type.handle,
|
.handle = child_type.handle,
|
||||||
};
|
};
|
||||||
} else ((try resolveTypeOfNodeInternal(store, arena, .{
|
} else
|
||||||
.node = return_type,
|
return child_type.instanceTypeVal();
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null).instanceTypeVal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves the child type of an optional type
|
/// Resolves the child type of an optional type
|
||||||
@ -591,7 +588,7 @@ fn resolveDerefType(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves bracket access type (both slicing and array access)
|
/// Resolves slicing and array access
|
||||||
fn resolveBracketAccessType(
|
fn resolveBracketAccessType(
|
||||||
store: *DocumentStore,
|
store: *DocumentStore,
|
||||||
arena: *std.heap.ArenaAllocator,
|
arena: *std.heap.ArenaAllocator,
|
||||||
@ -684,17 +681,13 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
node_handle: NodeWithHandle,
|
node_handle: NodeWithHandle,
|
||||||
bound_type_params: *BoundTypeParams,
|
bound_type_params: *BoundTypeParams,
|
||||||
) error{OutOfMemory}!?TypeWithHandle {
|
) error{OutOfMemory}!?TypeWithHandle {
|
||||||
const node = node_handle.node;
|
|
||||||
const handle = node_handle.handle;
|
|
||||||
const tree = handle.tree;
|
|
||||||
|
|
||||||
const state = struct {
|
const state = struct {
|
||||||
var resolve_trail = std.ArrayListUnmanaged(NodeWithHandle){};
|
var resolve_trail = std.ArrayListUnmanaged(NodeWithHandle){};
|
||||||
};
|
};
|
||||||
// If we were asked to resolve this node before,
|
// If we were asked to resolve this node before,
|
||||||
// it is self-referential and we cannot resolve it.
|
// it is self-referential and we cannot resolve it.
|
||||||
for (state.resolve_trail.items) |i| {
|
for (state.resolve_trail.items) |i| {
|
||||||
if (i.node == node and i.handle == handle)
|
if (std.meta.eql(i, node_handle))
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// We use the backing allocator here because the ArrayList expects its
|
// We use the backing allocator here because the ArrayList expects its
|
||||||
@ -702,6 +695,10 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
try state.resolve_trail.append(arena.child_allocator, node_handle);
|
try state.resolve_trail.append(arena.child_allocator, node_handle);
|
||||||
defer _ = state.resolve_trail.pop();
|
defer _ = state.resolve_trail.pop();
|
||||||
|
|
||||||
|
const node = node_handle.node;
|
||||||
|
const handle = node_handle.handle;
|
||||||
|
const tree = handle.tree;
|
||||||
|
|
||||||
const main_tokens = tree.nodes.items(.main_token);
|
const main_tokens = tree.nodes.items(.main_token);
|
||||||
const node_tags = tree.nodes.items(.tag);
|
const node_tags = tree.nodes.items(.tag);
|
||||||
const datas = tree.nodes.items(.data);
|
const datas = tree.nodes.items(.data);
|
||||||
@ -755,24 +752,6 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
.container_field,
|
|
||||||
.container_field_init,
|
|
||||||
.container_field_align,
|
|
||||||
=> |c| {
|
|
||||||
const field: ast.full.ContainerField = switch (c) {
|
|
||||||
.container_field => tree.containerField(node),
|
|
||||||
.container_field_align => tree.containerFieldAlign(node),
|
|
||||||
.container_field_init => tree.containerFieldInit(node),
|
|
||||||
else => unreachable,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (field.ast.type_expr == 0) return null;
|
|
||||||
const field_type = .{ .node = field.ast.type_expr, .handle = handle };
|
|
||||||
|
|
||||||
const typ = (try resolveTypeOfNodeInternal(store, arena, field_type, bound_type_params)) orelse
|
|
||||||
return null;
|
|
||||||
return typ.instanceTypeVal();
|
|
||||||
},
|
|
||||||
.call,
|
.call,
|
||||||
.call_comma,
|
.call_comma,
|
||||||
.async_call,
|
.async_call,
|
||||||
@ -839,53 +818,62 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
.@"comptime",
|
.@"comptime",
|
||||||
.@"nosuspend",
|
.@"nosuspend",
|
||||||
.grouped_expression,
|
.grouped_expression,
|
||||||
=> {
|
.container_field,
|
||||||
return try resolveTypeOfNodeInternal(store, arena, .{ .node = datas[node].lhs, .handle = handle }, bound_type_params);
|
.container_field_init,
|
||||||
},
|
.container_field_align,
|
||||||
.struct_init,
|
.struct_init,
|
||||||
.struct_init_comma,
|
.struct_init_comma,
|
||||||
.struct_init_one,
|
.struct_init_one,
|
||||||
.struct_init_one_comma,
|
.struct_init_one_comma,
|
||||||
=> {
|
|
||||||
return ((try resolveTypeOfNodeInternal(
|
|
||||||
store,
|
|
||||||
arena,
|
|
||||||
.{ .node = datas[node].lhs, .handle = handle },
|
|
||||||
bound_type_params,
|
|
||||||
)) orelse return null).instanceTypeVal();
|
|
||||||
},
|
|
||||||
.error_set_decl => {
|
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
|
||||||
},
|
|
||||||
.slice,
|
.slice,
|
||||||
.slice_sentinel,
|
.slice_sentinel,
|
||||||
.slice_open,
|
.slice_open,
|
||||||
=> {
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return try resolveBracketAccessType(store, arena, left_type, .Range, bound_type_params);
|
|
||||||
},
|
|
||||||
.deref,
|
.deref,
|
||||||
.unwrap_optional,
|
.unwrap_optional,
|
||||||
|
.array_access,
|
||||||
|
.@"orelse",
|
||||||
|
.@"catch",
|
||||||
|
.@"try",
|
||||||
|
.address_of,
|
||||||
=> {
|
=> {
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
const base = .{ .node = datas[node].lhs, .handle = handle };
|
||||||
.node = datas[node].lhs,
|
const base_type = (try resolveTypeOfNodeInternal(store, arena, base, bound_type_params)) orelse
|
||||||
.handle = handle,
|
return null;
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return switch (node_tags[node]) {
|
return switch (node_tags[node]) {
|
||||||
.unwrap_optional => try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params),
|
.@"comptime",
|
||||||
.deref => try resolveDerefType(store, arena, left_type, bound_type_params),
|
.@"nosuspend",
|
||||||
else => unreachable,
|
.grouped_expression,
|
||||||
|
=> base_type,
|
||||||
|
.container_field,
|
||||||
|
.container_field_init,
|
||||||
|
.container_field_align,
|
||||||
|
.struct_init,
|
||||||
|
.struct_init_comma,
|
||||||
|
.struct_init_one,
|
||||||
|
.struct_init_one_comma,
|
||||||
|
=> base_type.instanceTypeVal(),
|
||||||
|
.slice,
|
||||||
|
.slice_sentinel,
|
||||||
|
.slice_open,
|
||||||
|
=> try resolveBracketAccessType(store, arena, base_type, .Range, bound_type_params),
|
||||||
|
.deref => try resolveDerefType(store, arena, base_type, bound_type_params),
|
||||||
|
.unwrap_optional => try resolveUnwrapOptionalType(store, arena, base_type, bound_type_params),
|
||||||
|
.array_access => try resolveBracketAccessType(store, arena, base_type, .Single, bound_type_params),
|
||||||
|
.@"orelse" => try resolveUnwrapOptionalType(store, arena, base_type, bound_type_params),
|
||||||
|
.@"catch" => try resolveUnwrapErrorType(store, arena, base_type, bound_type_params),
|
||||||
|
.@"try" => try resolveUnwrapErrorType(store, arena, base_type, bound_type_params),
|
||||||
|
.address_of => {
|
||||||
|
const lhs_node = switch (base_type.type.data) {
|
||||||
|
.other => |n| n,
|
||||||
|
else => return null,
|
||||||
|
};
|
||||||
|
return TypeWithHandle{
|
||||||
|
.type = .{ .data = .{ .pointer = lhs_node }, .is_type_val = base_type.type.is_type_val },
|
||||||
|
.handle = base_type.handle,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
.array_access => {
|
else => unreachable,
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
};
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return try resolveBracketAccessType(store, arena, left_type, .Single, bound_type_params);
|
|
||||||
},
|
},
|
||||||
.field_access => {
|
.field_access => {
|
||||||
const field_access = datas[node];
|
const field_access = datas[node];
|
||||||
@ -897,7 +885,7 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
store,
|
store,
|
||||||
arena,
|
arena,
|
||||||
(try resolveTypeOfNodeInternal(store, arena, .{
|
(try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
.node = field_access.lhs,
|
.node = datas[node].lhs,
|
||||||
.handle = handle,
|
.handle = handle,
|
||||||
}, bound_type_params)) orelse return null,
|
}, bound_type_params)) orelse return null,
|
||||||
bound_type_params,
|
bound_type_params,
|
||||||
@ -917,20 +905,6 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
return try child.resolveType(store, arena, bound_type_params);
|
return try child.resolveType(store, arena, bound_type_params);
|
||||||
} else return null;
|
} else return null;
|
||||||
},
|
},
|
||||||
.@"orelse" => {
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return try resolveUnwrapOptionalType(store, arena, left_type, bound_type_params);
|
|
||||||
},
|
|
||||||
.@"catch" => {
|
|
||||||
const left_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return try resolveUnwrapErrorType(store, arena, left_type, bound_type_params);
|
|
||||||
},
|
|
||||||
.array_type,
|
.array_type,
|
||||||
.array_type_sentinel,
|
.array_type_sentinel,
|
||||||
.optional_type,
|
.optional_type,
|
||||||
@ -938,30 +912,20 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
.ptr_type,
|
.ptr_type,
|
||||||
.ptr_type_bit_range,
|
.ptr_type_bit_range,
|
||||||
.error_union,
|
.error_union,
|
||||||
|
.error_set_decl,
|
||||||
|
.container_decl,
|
||||||
|
.container_decl_arg,
|
||||||
|
.container_decl_arg_trailing,
|
||||||
|
.container_decl_trailing,
|
||||||
|
.container_decl_two,
|
||||||
|
.container_decl_two_trailing,
|
||||||
|
.tagged_union,
|
||||||
|
.tagged_union_trailing,
|
||||||
|
.tagged_union_two,
|
||||||
|
.tagged_union_two_trailing,
|
||||||
|
.tagged_union_enum_tag,
|
||||||
|
.tagged_union_enum_tag_trailing,
|
||||||
=> return TypeWithHandle.typeVal(node_handle),
|
=> return TypeWithHandle.typeVal(node_handle),
|
||||||
.@"try" => {
|
|
||||||
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
return try resolveUnwrapErrorType(store, arena, rhs_type, bound_type_params);
|
|
||||||
},
|
|
||||||
.address_of => {
|
|
||||||
const rhs_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
|
||||||
.node = datas[node].lhs,
|
|
||||||
.handle = handle,
|
|
||||||
}, bound_type_params)) orelse return null;
|
|
||||||
|
|
||||||
const rhs_node = switch (rhs_type.type.data) {
|
|
||||||
.other => |n| n,
|
|
||||||
else => return null,
|
|
||||||
};
|
|
||||||
|
|
||||||
return TypeWithHandle{
|
|
||||||
.type = .{ .data = .{ .pointer = rhs_node }, .is_type_val = rhs_type.type.is_type_val },
|
|
||||||
.handle = rhs_type.handle,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
.builtin_call,
|
.builtin_call,
|
||||||
.builtin_call_comma,
|
.builtin_call_comma,
|
||||||
.builtin_call_two,
|
.builtin_call_two,
|
||||||
@ -1035,21 +999,6 @@ pub fn resolveTypeOfNodeInternal(
|
|||||||
// reference to node '0' which is root
|
// reference to node '0' which is root
|
||||||
return TypeWithHandle.typeVal(.{ .node = 0, .handle = new_handle });
|
return TypeWithHandle.typeVal(.{ .node = 0, .handle = new_handle });
|
||||||
},
|
},
|
||||||
.container_decl,
|
|
||||||
.container_decl_arg,
|
|
||||||
.container_decl_arg_trailing,
|
|
||||||
.container_decl_trailing,
|
|
||||||
.container_decl_two,
|
|
||||||
.container_decl_two_trailing,
|
|
||||||
.tagged_union,
|
|
||||||
.tagged_union_trailing,
|
|
||||||
.tagged_union_two,
|
|
||||||
.tagged_union_two_trailing,
|
|
||||||
.tagged_union_enum_tag,
|
|
||||||
.tagged_union_enum_tag_trailing,
|
|
||||||
=> {
|
|
||||||
return TypeWithHandle.typeVal(node_handle);
|
|
||||||
},
|
|
||||||
.fn_proto,
|
.fn_proto,
|
||||||
.fn_proto_multi,
|
.fn_proto_multi,
|
||||||
.fn_proto_one,
|
.fn_proto_one,
|
||||||
@ -2726,7 +2675,8 @@ fn makeScopeInternal(
|
|||||||
}
|
}
|
||||||
// Visit parameter types to pick up any error sets and enum
|
// Visit parameter types to pick up any error sets and enum
|
||||||
// completions
|
// completions
|
||||||
if (param.type_expr != 0) try makeScopeInternal(
|
if (param.type_expr != 0)
|
||||||
|
try makeScopeInternal(
|
||||||
allocator,
|
allocator,
|
||||||
scopes,
|
scopes,
|
||||||
error_completions,
|
error_completions,
|
||||||
@ -2964,12 +2914,15 @@ fn makeScopeInternal(
|
|||||||
std.debug.assert(token_tags[name_token] == .identifier);
|
std.debug.assert(token_tags[name_token] == .identifier);
|
||||||
|
|
||||||
const name = tree.tokenSlice(name_token);
|
const name = tree.tokenSlice(name_token);
|
||||||
try scope.decls.putNoClobber(name, if (is_for) .{
|
try scope.decls.putNoClobber(name, if (is_for)
|
||||||
|
.{
|
||||||
.array_payload = .{
|
.array_payload = .{
|
||||||
.identifier = name_token,
|
.identifier = name_token,
|
||||||
.array_expr = while_node.ast.cond_expr,
|
.array_expr = while_node.ast.cond_expr,
|
||||||
},
|
},
|
||||||
} else .{
|
}
|
||||||
|
else
|
||||||
|
.{
|
||||||
.pointer_payload = .{
|
.pointer_payload = .{
|
||||||
.name = name_token,
|
.name = name_token,
|
||||||
.condition = while_node.ast.cond_expr,
|
.condition = while_node.ast.cond_expr,
|
||||||
|
Loading…
Reference in New Issue
Block a user