ols icon indicating copy to clipboard operation
ols copied to clipboard

Unhandled specialization `&Pointer_Type`

Open DragosPopse opened this issue 1 year ago • 1 comments

The language server crashes on some generics it seems. Could a temporary fix be to make things that are not handled just ignored rather than a full panic crash?

Error message:

D:/a/ols/ols/src/server/generics.odin(287:3) panic: log.panicf
[Error - 1:04:40 PM] Unhandled specialization &Pointer_Type{node = Expr{expr_base = Node{pos = Pos{file = "C:\\dev\\cdc\\cdc\\mlw\\adt\\sparse_set\\sparse_set.odin", offset = 1017, line = 45, column = 21}, end = Pos{file = "C:\\dev\\cdc\\cdc\\mlw\\adt\\sparse_set\\sparse_set.odin", offset = 1036, line = 45, column = 40}, state_flags = Node_State_Flags{}, derived = 0x1F04609C970}, derived_expr = 0x1F04609C970}, tag = <nil>, pointer = Pos{file = "\a\xff\xb4H\xf0\x01\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00h\u05b9H\xf0\x01\x00\x00\x10\xf4\xb9H\xf0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", offset = 1017, line = 45, column = 21}, elem = 0x1F04609CA20}

Code that produces this error (self contained, so it might just work to add it in a project for testing

package mlw_sparse_set

import "base:runtime"

Handle :: bit_field u64 {
	index     : int | 48,
	generation: int | 16,
}

Sparse_Set :: struct($I: typeid, $T: typeid) {
	sparse     : []int,
	dense      : []T,
	generations: []int,
	free_queue : []int,
	queue_top  : int,
	size       : int,
	count      : int,
	allocator  : runtime.Allocator,
}

init :: proc(set: $S/^Sparse_Set($I, $T), #any_int capacity: int, allocator := context.allocator) {
	context.allocator = allocator
	set.allocator = allocator
	cap := capacity + 1
	set.size = cap
	set.sparse = make([]int, cap)
	set.dense = make([]T, cap)
	set.generations = make([]int, cap)
	set.free_queue = make([]int, cap)

	for i := set.size - 1; i >= 1; i -= 1 {
		set.free_queue[set.queue_top] = i
		set.queue_top += 1
	}
}

destroy :: proc(set: $S/^Sparse_Set($I, $T)) {
	context.allocator = set.allocator
}

slice :: proc(set: $S/Sparse_Set($I, $T)) -> (values: []T) {
	return set.dense[:set.count]
}

add :: proc(set: $S/^Sparse_Set($I, $T), val: T) -> (handle: I) {
	assert(set != nil)
	assert(set.free_queue != nil)

	if set.queue_top > 0 {
		set.queue_top -= 1
		handle.index = set.free_queue[set.queue_top]
		handle.generation = set.generations[handle.index]
		val_pos := set.count
		set.dense[val_pos] = val
		set.sparse[handle.index] = val_pos
		
		set.count += 1
	}

	return handle
}

remove :: proc(set: $S/^Sparse_Set($I, $T), handle: I) {
	assert(set != nil)
	assert(set.free_queue != nil)
	assert(handle.index > 0 && handle.index < set.size)
	assert(handle.generation == set.generations[handle.index], "Generation mismatch")
	assert(set.queue_top < set.size, "No more items to remove")
	set.free_queue[set.queue_top] = handle.index
	set.generations[handle.index] += 1
	set.queue_top += 1
	last_packed := set.count - 1
	set.dense[set.sparse[handle.index]] = set.dense[last_packed]
	set.count -= 1
	assert(set.queue_top <= set.size - 1)
}

get :: proc(set: $S/^Sparse_Set($I, $T), handle: I) -> (ptr: ^T) {
	if handle.generation != set.generations[handle.index] {
		return nil
	}
	if handle.index <= 0 || handle.index >= set.size {
		return nil
	}
	return &set.dense[set.sparse[handle.index]]
}

// TESTING

import "core:testing"
import "core:fmt"

print_details :: proc(set: ^Sparse_Set($I, $T)) {
	fmt.printf("Sparse: %v\n", set.sparse)
	fmt.printf("Dense: %v\n", set.dense)
	fmt.printf("Queue: %v top: %v\n", set.free_queue, set.queue_top)
	fmt.printf("Values: %v\n", slice(set^))
}

add_print :: proc(set: ^Sparse_Set($I, $T), val: T) -> I {
	handle := add(set, val)
	fmt.printf("Add value %v at %v\n", val, handle)
	print_details(set)
	fmt.println()
	return handle
}

remove_print :: proc(set: ^Sparse_Set($I, $T), i: I) {
	fmt.printf("Removing %v with value %v\n", i, get(set, i)^)
	remove(set, i)
	print_details(set)
}

@test
sparse_set_test :: proc(T: ^testing.T) {
	set: Sparse_Set(Handle, int)
	init(&set, 6)
	val1 := add_print(&set, 1)
	val2 := add_print(&set, 2)
	val3 := add_print(&set, 3)
	remove_print(&set, val2)
	val4 := add_print(&set, 100)
}

Not having the file open will not trigger the crash.

DragosPopse avatar Jun 11 '24 10:06 DragosPopse

Currently working on the rename branch, so it has been fixed there. Closing issue when merged.

DanielGavin avatar Jun 11 '24 17:06 DanielGavin

Merged with master.

DanielGavin avatar Jul 11 '24 19:07 DanielGavin