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

T(a) not an L-value when a is an L-value and typeEqualsOrDistinct(T, typeof(a)) holds #22523

Closed
tersec opened this issue Aug 20, 2023 · 1 comment · Fixed by #24197
Closed

Comments

@tersec
Copy link
Contributor

tersec commented Aug 20, 2023

Description

from std/typetraits import distinctBase

type
  V[p: static int] = distinct int
  D[p: static int] = distinct int
  T = V[1]

proc f(y: var T) = discard

var a: D[0]

static:
  doAssert distinctBase(T) is distinctBase(D[0])
  doAssert distinctBase(T) is int
  doAssert distinctBase(D[0]) is int
  doAssert T(a) is T

f(cast[ptr T](addr a)[])
f(T(a))

fails to build not for

f(cast[ptr T](addr a)[])

but rather for

f(T(a))

https://nim-lang.org/docs/manual.html#type-relations-convertible-relation states that

The type conversion T(a) is an L-value if a is an L-value and typeEqualsOrDistinct(T, typeof(a)) holds.
which is the case here.

Because a is an L-value here, and they're all ints per that static block, T(a) should therefore also be an L-value, but it appears not to be.

Nim Version

Nim Compiler Version 1.6.14 [Linux: amd64]
Compiled at 2023-06-29
Copyright (c) 2006-2023 by Andreas Rumpf

active boot switches: -d:release
Nim Compiler Version 2.0.1 [Linux: amd64]
Compiled at 2023-08-20
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 037f536e7ee25c4baf23dff8a4525825c506442c
active boot switches: -d:release
Nim Compiler Version 2.1.1 [Linux: amd64]
Compiled at 2023-08-20
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: a4781dc4bcdf6e76076af80d0b21cb09865b3d44
active boot switches: -d:release

Current Output

r.nim(19, 2) Error: type mismatch
Expression: f(T(a))
  [1] T(a): T

Expected one of (first mismatch at [position]):
[1] proc f(y: var T)

Expected Output

No response

Possible Solution

No response

Additional Information

No response

@Araq
Copy link
Member

Araq commented Aug 20, 2023

+1 for quoting the spec.

metagn added a commit to metagn/Nim that referenced this issue Sep 28, 2024
@Araq Araq closed this as completed in b0e6d28 Sep 29, 2024
narimiran pushed a commit that referenced this issue Dec 20, 2024
fixes #22523

There were 2 problems with the code in `sameType` for
`dcEqIgnoreDistinct`:

1. The code that skipped `{tyDistinct, tyGenericInst}` only ran if the
given types had different kinds. This is fixed by always performing this
skip.
2. The code block below that checks if `tyGenericInst`s have different
values still ran for `dcEqIgnoreDistinct` since it checks if the given
types are generic insts, not the skipped types (and also only the 1st
given type). This is fixed by only invoking this block for `dcEq`;
`dcEqOrDistinctOf` (which is unused) also skips the first given type.
Arguably there is another issue here that `skipGenericAlias` only ever
skips 1 type.

These combined fix the issue (`T` is `GenericInst(V, 1, distinct int)`
and `D[0]` is `GenericInst(D, 0, distinct int)`).

(cherry picked from commit b0e6d28)
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

Successfully merging a pull request may close this issue.

2 participants