Skip to content

Commit 1d2df42

Browse files
committed
Fix issues with the local evaluation of generic function in value decl, since we can't lazily evaluate it.
1 parent f06cf17 commit 1d2df42

File tree

3 files changed

+129
-4
lines changed

3 files changed

+129
-4
lines changed

src/server/analysis.odin

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,15 +1308,17 @@ internal_resolve_type_identifier :: proc(
13081308
signature = node.name,
13091309
pkg = ast_context.current_package,
13101310
value = SymbolUntypedValue{type = .Bool},
1311-
}, true
1311+
},
1312+
true
13121313
case:
13131314
return {
13141315
type = .Keyword,
13151316
signature = node.name,
13161317
name = ident.name,
13171318
pkg = ast_context.current_package,
13181319
value = SymbolBasicValue{ident = ident},
1319-
}, true
1320+
},
1321+
true
13201322
}
13211323
}
13221324

@@ -3029,6 +3031,7 @@ get_generic_assignment :: proc(
30293031
ast_context.call = old_call
30303032
}
30313033

3034+
//We have to resolve early and can't rely on lazy evalutation because it can have multiple returns.
30323035
if symbol, ok := resolve_type_expression(ast_context, v.expr); ok {
30333036
if procedure, ok := symbol.value.(SymbolProcedureValue); ok {
30343037
for ret in procedure.return_types {

src/server/generics.odin

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,31 +351,47 @@ find_and_replace_poly_type :: proc(
351351
case ^ast.Matrix_Type:
352352
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
353353
v.elem = expr
354+
v.pos.file = expr.pos.file
355+
v.end.file = expr.end.file
354356
}
355357
if expr, ok := is_in_poly_map(v.column_count, poly_map); ok {
356358
v.column_count = expr
359+
v.pos.file = expr.pos.file
360+
v.end.file = expr.end.file
357361
}
358362
if expr, ok := is_in_poly_map(v.row_count, poly_map); ok {
359363
v.row_count = expr
364+
v.pos.file = expr.pos.file
365+
v.end.file = expr.end.file
360366
}
361367
case ^ast.Dynamic_Array_Type:
362368
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
363369
v.elem = expr
370+
v.pos.file = expr.pos.file
371+
v.end.file = expr.end.file
364372
}
365373
case ^ast.Array_Type:
366374
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
367375
v.elem = expr
376+
v.pos.file = expr.pos.file
377+
v.end.file = expr.end.file
368378
}
369379
if expr, ok := is_in_poly_map(v.len, poly_map); ok {
370380
v.len = expr
381+
v.pos.file = expr.pos.file
382+
v.end.file = expr.end.file
371383
}
372384
case ^ast.Multi_Pointer_Type:
373385
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
374386
v.elem = expr
387+
v.pos.file = expr.pos.file
388+
v.end.file = expr.end.file
375389
}
376390
case ^ast.Pointer_Type:
377391
if expr, ok := is_in_poly_map(v.elem, poly_map); ok {
378392
v.elem = expr
393+
v.pos.file = expr.pos.file
394+
v.end.file = expr.end.file
379395
}
380396
}
381397

tests/completions_test.odin

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ ast_swizzle_completion :: proc(t: ^testing.T) {
481481
t,
482482
&source,
483483
".",
484-
{
484+
{
485485
"x: f32",
486486
"y: f32",
487487
"z: f32",
@@ -2657,6 +2657,112 @@ ast_simple_bit_field_completion :: proc(t: ^testing.T) {
26572657
t,
26582658
&source,
26592659
".",
2660-
{"My_Bit_Field.one: int", "My_Bit_Field.two: int", "My_Bit_Field.three: int"},
2660+
{
2661+
"My_Bit_Field.one: int",
2662+
"My_Bit_Field.two: int",
2663+
"My_Bit_Field.three: int",
2664+
},
2665+
)
2666+
}
2667+
2668+
2669+
@(test)
2670+
ast_generics_function_with_struct_same_pkg :: proc(t: ^testing.T) {
2671+
packages := make([dynamic]test.Package)
2672+
2673+
append(
2674+
&packages,
2675+
test.Package {
2676+
pkg = "my_package",
2677+
source = `package my_package
2678+
DummyFunction :: proc(value: $T/[dynamic]$E, index: int) -> ^E
2679+
{
2680+
return &value[index]
2681+
}
2682+
`,
2683+
},
2684+
)
2685+
2686+
source := test.Source {
2687+
main = `package main
2688+
import "my_package"
2689+
2690+
CoolStruct :: struct
2691+
{
2692+
val1, val2, val3: int,
2693+
}
2694+
2695+
main :: proc()
2696+
{
2697+
testArray : [dynamic]CoolStruct
2698+
2699+
//no completion on function or new value
2700+
newValue := my_package.DummyFunction(testArray, 10)
2701+
newValue.{*}
2702+
}
2703+
`,
2704+
packages = packages[:],
2705+
}
2706+
2707+
test.expect_completion_details(
2708+
t,
2709+
&source,
2710+
".",
2711+
{
2712+
"CoolStruct.val1: int",
2713+
"CoolStruct.val2: int",
2714+
"CoolStruct.val3: int",
2715+
},
2716+
)
2717+
}
2718+
2719+
2720+
@(test)
2721+
ast_generics_function_with_struct_diff_pkg :: proc(t: ^testing.T) {
2722+
packages := make([dynamic]test.Package)
2723+
2724+
append(
2725+
&packages,
2726+
test.Package {
2727+
pkg = "my_package",
2728+
source = `package my_package
2729+
DummyFunction :: proc(value: $T/[dynamic]$E, index: int) -> ^E
2730+
{
2731+
return &value[index]
2732+
}
2733+
2734+
CoolStruct :: struct
2735+
{
2736+
val1, val2, val3: int,
2737+
}
2738+
`,
2739+
},
2740+
)
2741+
2742+
source := test.Source {
2743+
main = `package main
2744+
import "my_package"
2745+
2746+
main :: proc()
2747+
{
2748+
testArray : [dynamic]my_package.CoolStruct
2749+
2750+
//no completion on function or new value
2751+
newValue := my_package.DummyFunction(testArray, 10)
2752+
newValue.{*}
2753+
}
2754+
`,
2755+
packages = packages[:],
2756+
}
2757+
2758+
test.expect_completion_details(
2759+
t,
2760+
&source,
2761+
".",
2762+
{
2763+
"CoolStruct.val1: int",
2764+
"CoolStruct.val2: int",
2765+
"CoolStruct.val3: int",
2766+
},
26612767
)
26622768
}

0 commit comments

Comments
 (0)