I have a table member of an object declared as such
entries: Table[string, string]
And I was returning it with this
proc getAll*(this: JotzCollection): Table[string, string] =
return this.entries
When I try to get its length
assert(collection.getAll().len == 2)
I get a spew of errors
Error: type mismatch: got <Table[system.string, system.string]>
but expected one of:
func len(x: (type array) | array): int
first type mismatch at position: 1
required type for x: typedesc[array] or array
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
func len(x: string): int
first type mismatch at position: 1
required type for x: string
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
func len[TOpenArray: openArray | varargs](x: TOpenArray): int
first type mismatch at position: 1
required type for x: TOpenArray: openArray or varargs
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
func len[T](x: seq[T]): int
first type mismatch at position: 1
required type for x: seq[T]
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
func len[T](x: set[T]): int
first type mismatch at position: 1
required type for x: set[T]
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
proc len(w: WideCString): int
first type mismatch at position: 1
required type for w: WideCString
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
proc len(x: cstring): int
first type mismatch at position: 1
required type for x: cstring
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
proc len[U: Ordinal; V: Ordinal](x: HSlice[U, V]): int
first type mismatch at position: 1
required type for x: HSlice[len.U, len.V]
but expression 'getAll(collection)' is of type: Table[system.string, system.string]
expression: len(getAll(collection))
This seems to be telling me there is no len function for tables? I can call len just fine on the table from within the proc. What am I missing? Thanks!There has to be a way to make the error message better in this common situation…
If the module where the type was declared also contains the appropriate procedure, show a “perhaps you forgot to import this module” message?
Error: `len(Table[string, string])' is not defined in this scope.
Do you mean `proc len[A, B](t: Table[A, B]): int' defined in std/tables?
If yes, please add the following code to the top of your source file:
import std/tables
Error: no overloads for len(Table[system.string, system.string]) found in scope
expected one of:
func len(x: (type array) | array): int
...
That particular error has always been confusing. The primary helpful information is precisely what @sls1005 and @Hlaaftana suggested. You need to know the proc, the type, and ideally, the context you used it in. All the other overloads are useless unless you meant to use a different type, which is probably not very often (at least for me). I also think it might be a bit unreasonable for the compiler to reason about where the import might come from, given that it probably doesn't have this information. I think the better thing would be for the compiler to be more intelligent and include procs/methods/funcs attached to the type, even if you've imported it "second hand" from another module like @Zekereth did.
So given that, the most helpful error message might be something like what you guys suggested, but with some context, like so (similar to Rust):
Error: 'len(Table[string, string])' is not defined in this scope.
4 |
5 | assert(collection.getAll().len == 2)
6 | ^^^
But not sure how feasible that is given the current structure of the error message reporting.