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 to devel with dirty template #23611

Open
tersec opened this issue May 15, 2024 · 3 comments · May be fixed by #23614
Open

Regression from 2.0 to devel with dirty template #23611

tersec opened this issue May 15, 2024 · 3 comments · May be fixed by #23614

Comments

@tersec
Copy link
Contributor

tersec commented May 15, 2024

Description

a.nim

import "."/b

type
  B = object
  L = object

template F(T: type B): type = F(Json, B)
var j = F(B).init()
var f: L
s(j, f)

b.nim

type P = object

template d(Name: untyped) {.dirty.} =
  type Name* = object

import "."/c

d(Json)

type K[Flavor = P] = object
  lex: V

template F*(T: type Json, F: distinct type = P): type = K[F]

proc init*(T: type K): T = discard

proc s*[T](r: var K, value: var T) =
  x(r.lex)

c.nim

type
  U* = enum
    errNone
  V* = object
    err: U

template x*(lex: V) {.dirty.} =
  lex.err = errNone

Nim Version

Compiles:

Nim Compiler Version 2.0.5 [Linux: amd64]
Compiled at 2024-05-15
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: 2f399807cb45ea073e1c1bb640d16956e58fcae0
active boot switches: -d:release

Does not compile:

Nim Compiler Version 2.1.1 [Linux: amd64]
Compiled at 2024-05-15
Copyright (c) 2006-2024 by Andreas Rumpf

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

Current Output

a.nim(10, 2) template/generic instantiation of `s` from here
b.nim(18, 4) template/generic instantiation of `x` from here
c.nim(8, 13) Error: undeclared identifier: 'errNone'
candidates (edit distance, scope distance); see '--spellSuggest': 
 (4, 5): 'NimNode'
 (4, 5): 'range'

Expected Output

No response

Possible Solution

No response

Additional Information

No response

@metagn
Copy link
Collaborator

metagn commented May 15, 2024

Simplified:

# a.nim
import "."/b

s[int]()
# b.nim
import "."/c

type K = object
  lex: V

proc s*[T]() =
  var r: K
  x(r.lex)
# c.nim
type
  U* = enum
    errNone
  V* = object
    err: U

template x*(lex: V) {.dirty.} =
  lex.err = errNone

Removing the lex: V parameter from x gives no error, but changing lex.err = to let y = or errNone to a const instead of an enum symbol gives the same error on 2.0. dirty doesn't bind anything by default, so errNone was never accessible as a symbol through lookup.

So this very likely fails now because of #23588, which again, means this only worked since errNone is specifically an enum member in a context where its type can be inferred. I don't know if it's worth making this specific case work by adding back awkward behavior to the compiler. Is it too much of a problem to either bind errNone or not use dirty here?

@jangko
Copy link
Contributor

jangko commented May 20, 2024

We need the dirty template because sometimes we pass in statement such as return. But using bind also works.

@tersec
Copy link
Contributor Author

tersec commented May 27, 2024

To the extent status-im/nim-json-serialization#90 solves this, I'm fine with that. I reported this as a regression fairly mechanically, not so much prescriptively as descriptively. But I tend to agree it accidentally hit a weird edge case.

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.

3 participants