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

Generic code can cause attempts to use constructors for unrelated types to fail #1051

Closed
barcharcraz opened this issue Mar 29, 2014 · 1 comment

Comments

@barcharcraz
Copy link
Contributor

the code

type TMatrix[N,M: static[int], T] = object
  data: array[0..M*N-1, T]
type TMat4f = TMatrix[4,4,float32]
type TVec3f = TMatrix[1,3,float32]
type TVec4f = TMatrix[1,4,float32]
type TVec[N: static[int]; T] = TMatrix[N,1,T]
proc dot*(a, b: TVec): TVec.T =
  #assert(a.data.len == b.data.len)
  for i in 1..a.data.len:
    result += a.data[i-1] * b.data[i-1]
proc row*(a: TMatrix; i: int): auto =
  result = TVec[TMatrix.M, TMatrix.T]()
  for idx in 1..TMatrix.M:
    result.data[idx-1] = a.data[(TMatrix.N * (idx-1)) + (i-1)]
proc col*(a: TMatrix; j: int): auto =
  result = TVec[TMatrix.N, TMatrix.T]()
  for idx in 1..TMatrix.N:
    result.data[idx] = a.data[(TMatrix.N * (j-1)) + (idx-1)]
proc mul*(a: TMat4f; b: TMat4f): TMat4f =
  for i in 1..4:
    for j in 1..4:
      result.data[(4 * (j-1)) + (i-1)] = dot(row(a,i), col(b,j))

var test = TVec4f(data: [1.0'f32, 1.0'f32, 1.0'f32, 1.0'f32])

fails with the error

tconstruct.nim(24, 17) Error: internal error: genObjConstr
No stack traceback available

if test is changed to be a TVec3f then the code works, but it fails again if a mul proc is defined for TMat3f

@gmpreussner
Copy link
Contributor

Workaround:

type TMatrix[N,M: static[int], T] = object
  data: array[0..M*N-1, T]
type TMat4f = TMatrix[4,4,float32]
type TVec3f = TMatrix[1,3,float32]
type TVec4f = TMatrix[1,4,float32]
type TVec[N: static[int]; T] = TMatrix[N,1,T]
proc dot*(a, b: TVec): TVec.T =
  #assert(a.data.len == b.data.len)
  for i in 1..a.data.len:
    result += a.data[i-1] * b.data[i-1]
proc row*[N, M, T](a: TMatrix[N, M, T]; i: int): TVec[M, T] =
  for idx in 1..M:
    result.data[idx-1] = a.data[(N * (idx-1)) + (i-1)]
proc col*[N, M, T](a: TMatrix[N, M, T]; j: int): TVec[N, T] =
  for idx in 1..N:
    result.data[idx] = a.data[(N * (j-1)) + (idx-1)]
proc mul*(a: TMat4f; b: TMat4f): TMat4f =
  for i in 1..4:
    for j in 1..4:
      result.data[(4 * (j-1)) + (i-1)] = dot(row(a,i), col(b,j))

var test = TVec4f(data: [1.0'f32, 1.0'f32, 1.0'f32, 1.0'f32])

zah added a commit that referenced this issue Jun 10, 2017
zah added a commit that referenced this issue Jun 19, 2017
@Araq Araq closed this as completed in 36c4f0a Jun 20, 2017
Clyybber pushed a commit to Clyybber/Nim that referenced this issue Feb 24, 2024
## Summary

Remove an optimization/semantic-change from `cgen` that's not used
anymore.

## Details

The `isInactiveDestructorCall`/`notYetAlive` procedures was responsible
for detecting whether a destructor call or reset operation could be
safely omitted for a local.

This is a workaround for destructor injection being limited to wrapping
whole scopes in `try`/`finally` statements, but it finally stopped
working with the introduction of the MIR (~11 months ago), as the 'def'
statements for all locals requiring destruction are placed before the
`try` statement responsible for their destruction.

Since the proper fix will be implemented in the destructor injection
pass rather than in the code generators, `isInactiveDestructorCall`,
`notYetAlive` are removed and their usage sites are updated. The now-
unused `compat.getRoot` procedure is removed too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants