Interesting problem with `odin check . -vet` and generic method

I have the following code:

package midgard

import rand "core:math/rand"

shuffle :: proc(xs: []$T) {
	for i in 1 ..< len(xs) {
		j := rand.int_max(i + 1)
		xs[i], xs[j] = xs[j], xs[i]
	}
}

I can compile it and use it in tests without problems, but …

running odin check . -vet returns:
`/midgard/shuffle.odin(4:8) Error: ‘rand’ declared but not used

    import rand "core:math/rand"`

But if I add the following line before the definition of shuffle():

_ :: rand.int_max

The ‘vet’ warning disappear.

Is this because I am using rand from within a generic procedure which hasn’t been instanciated yet?.

If you have no code included within the project you are checking that calls shuffle, then no version of shuffle will be generated at compilation. This means that there will be no instances of shuffle and no usages of rand.int_max which might be causing the warning. Assuming there is no other usage of the rand package.

1 Like

What you are saying makes sense. I used to have a test of shuffle in the same file and didn’t get the warning. The warning appeared when I moved the test in a different package.

Sometimes a simple experiment can help.
It has nothing to do with odin check . -vet or your test.
The reason is parapoly.
Try changing the parameter type from $T to something like int ,
and see the difference for yourself.

Yes I think I do understand now that it has to do with the generic type. In my mental model, the compiler would see the call to rand.int_max and validate that the import is used. After all, the compiler has to parse the code to verify it’s correct. I experimented and commented the import out and the compiler showed an error ("unknown ‘rand.max_int’)

In practice, unless the procedure gets instantiated then the compiler marks the import as not used. You can fix it by adding a test right in the file (this will instantiate the procedure with a concrete type and fix the problem) or add the dummy constant. If the line had included the generic T parameter that would have made more sense to me but that line just deal with concrete types j := rand.int_max(i + 1).

I am still new to the language and trying to get my feel of the land :slight_smile: