Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression from 2.0.8/version-2-0 to version-2-2/devel with Error: type mismatch with templates and generics #24125

Closed
tersec opened this issue Sep 17, 2024 · 9 comments

Comments

@tersec
Copy link
Contributor

tersec commented Sep 17, 2024

Description

template v[T, S](c: S): T = T(c)
discard v[int](0)

Nim Version

Builds:

Nim Compiler Version 2.0.8 [Linux: amd64]
Compiled at 2024-09-16
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 5935c3bfa9fec6505394867b23510eb5cbab3dbf
active boot switches: -d:release
Nim Compiler Version 2.0.9 [Linux: amd64]
Compiled at 2024-09-16
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 3214174f06930d240b0e35cb35c22014b89d1272
active boot switches: -d:release

Doesn't build:

Nim Compiler Version 2.1.99 [Linux: amd64]
Compiled at 2024-09-17
Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 61e04ba0ed4b8c6567f4cfd5c48c2c2439c62371
active boot switches: -d:release
Nim Compiler Version 2.1.99 [Linux: amd64]
Compiled at 2024-09-17
Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 1fbb67ffe9d3ec71fb1424609831eaca648c96d3
active boot switches: -d:release

Current Output

/tmp/k.nim(2, 15) Error: type mismatch
Expression: v[int](0)
  [1] 0: int literal(0)

Expected Output

No response

Known Workarounds

No response

Additional Information

No response

@Araq
Copy link
Member

Araq commented Sep 17, 2024

Partial explicit generic instantations are not in the language spec.

@tersec
Copy link
Contributor Author

tersec commented Sep 17, 2024

Ok

@diegomrsantos
Copy link

template v[T](c: SomeOrdinal): T = T(c)
discard v[int, char]('A')

outputs

.SIGSEGV: Illegal storage access. (Attempt to read from nil?)

@metagn
Copy link
Collaborator

metagn commented Sep 18, 2024

.SIGSEGV: Illegal storage access. (Attempt to read from nil?)

This happens in error reporting as a mistake from #24077 #24010 originally, it's supposed to give this error:

Error: type mismatch
Expression: v[int, char]('A')
  [1] 'A': char

Expected one of (first mismatch at [position]):
[2] template v[T](c: SomeOrdinal): T
  generic parameter mismatch, expected SomeOrdinal but got 'char' of type: typedesc[char]

char doesn't seem to be part of SomeOrdinal.

Also the second generic parameter isn't needed in this case.

@tersec
Copy link
Contributor Author

tersec commented Sep 18, 2024

.SIGSEGV: Illegal storage access. (Attempt to read from nil?)

This happens in error reporting as a mistake from #24077, it's supposed to give this error:

Error: type mismatch
Expression: v[int, char]('A')
  [1] 'A': char

Expected one of (first mismatch at [position]):
[2] template v[T](c: SomeOrdinal): T
  generic parameter mismatch, expected SomeOrdinal but got 'char' of type: typedesc[char]

Also the second generic parameter isn't needed in this case.

The compiler shouldn't crash though, regardless

Araq pushed a commit that referenced this issue Sep 19, 2024
refs #24010, refs
#24125 (comment)

The generic mismatch errors added in #24010 made it possible for `nArg`
to be `nil` in the error reporting since it checked the call argument
list, not the generic parameter list for the mismatching argument node,
which causes a segfault. This is fixed by checking the generic parameter
list immediately on any generic mismatch error.

Also the `typedesc` type is skipped for the value of the generic params
since it's redundant and the generic parameter constraints don't have
it.
@diegomrsantos
Copy link

diegomrsantos commented Sep 19, 2024

@metagn

This works fine

template v[T](c: SomeOrdinal): T = T(c)
discard v[int](1)

but

template v[T](c: SomeOrdinal): T = T(c)
discard v[int, char](1)

causes

Error: type mismatch
Expression: v[int, char](1)
  [1] 1: int literal(1)

Expected one of (first mismatch at [position]):
[2] template v[T](c: SomeOrdinal): T
  generic parameter mismatch, expected SomeOrdinal but got 'char' of type: char

I think it should be sth like "invalid type parameter char". This error logic could be causing more hidden bugs. What do you think?

@metagn
Copy link
Collaborator

metagn commented Sep 19, 2024

The extra generic parameter is allowed there because SomeOrdinal creates an implicit generic parameter, i.e. the compiler transforms it to:

template v[T; #[hidden]# cType: SomeOrdinal](c: cType): T = T(c)

Some libraries depended on being able to assign to this hidden generic parameter so it was kept allowed, which is why the compiler gives the error "expected SomeOrdinal", because it's trying to overwrite it. Maybe this could be mentioned in the error message, that an implicit generic parameter is being assigned.

The reason we can't support only partially giving the generic parameters is because it makes overloading ambiguous with differing generic parameter numbers and can cause instantiation issues for parameters that aren't properly constrained (i.e. foo[I, T](x: array[I, T]) vs foo[T](x: seq[T]), what if you do foo[string]?). The compiler could still infer the parameters from the call as it did before but the parameter counts need to match just so overloading works as expected.

@diegomrsantos
Copy link

diegomrsantos commented Sep 19, 2024

Thanks a lot for explaining. What do you think about the following?

template v[T](c: SomeOrdinal): T =
  echo "v1"
  T(c)

discard v[int, int](1)

prints v1

template v[T](c: SomeOrdinal): T =
  echo "v1"
  T(c)
template v[T, U](c: SomeOrdinal): T =
  echo "v2"
  T(c)

discard v[int, int](1)

prints v2

nim -v
Nim Compiler Version 2.1.99 [MacOSX: arm64]
Compiled at 2024-09-19
Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 755307be61e4ee7b32c8354b2c303d04bdfc3a3e
active boot switches: -d:release

The same happens with 2.0.8 and 1.6.20.

@metagn
Copy link
Collaborator

metagn commented Sep 19, 2024

What do you think about the following?

It's not good, if you change the order of the templates it prints v1 instead.

metagn added a commit to metagn/Nim that referenced this issue Sep 21, 2024
…#24140)

refs nim-lang#24010, refs
nim-lang#24125 (comment)

The generic mismatch errors added in nim-lang#24010 made it possible for `nArg`
to be `nil` in the error reporting since it checked the call argument
list, not the generic parameter list for the mismatching argument node,
which causes a segfault. This is fixed by checking the generic parameter
list immediately on any generic mismatch error.

Also the `typedesc` type is skipped for the value of the generic params
since it's redundant and the generic parameter constraints don't have
it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants