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

Dereferencing a ref type buggy #11773

Closed
timotheecour opened this issue Jul 17, 2019 · 5 comments
Closed

Dereferencing a ref type buggy #11773

timotheecour opened this issue Jul 17, 2019 · 5 comments

Comments

@timotheecour
Copy link
Member

after #11751 was merged, the behavior of type dereferencing seems buggy

  • the compiler SIGSEGV for when compiles(Foo2[])
  • dereferencing a ref type (ref to a generic) doesn't work (see below: type Goo1d = Goo1c[])
  • some dereferencing behavior seem suspicious; in general we shouldn't conflate dereferencing (only for ref / ptr would make sense IMO) vs accessing generic arguments (for which other apis should be used eg typetraits.genericHead, and extractGeneric ([superseded] new macro for generic reflection: extractGeneric(Foo2[float, string], 0) is float #8554) otherwise it gives ambiguities
  • inconsistent, eg:
doAssert (Bar[]) is string # passes
type Bar2 = Bar[] # Error: illformed AST

Example

type
  MyType = object
    a: int32
    b: int32
    c: int32

  MyRefType = ref MyType

echo sizeof(MyRefType[])
echo MyRefType[]

type Foo2 = object
  x: int

doAssert MyRefType[] is MyType
# echo sizeof(Foo2[]) # SIGSEGV: Illegal storage access
# when compiles(Foo2[]):discard # even checking that gives: SIGSEGV: Illegal storage access

type
  MyType2 = ref object
    a: int32
    b: int32
    c: int32
  MyRefType2 = ref MyType2

type Bar = seq[string]
doAssert (Bar[]) is string # is that ok? there's other ways to access generic parameters
# type Bar2 = Bar[] # Error: illformed AST: Bar[]
# doAssert string is (Bar[]) # Error: illformed AST: Bar[]

doAssert (ref ref string)[][] is string

# these pass, i guess they're ok?
doAssert (static string)[] is string
doAssert string[] is char
# doAssert char is string[] # Error: illformed AST: string[]
doAssert string isnot (ref char)

type Goo1[T] = object
  # x: T
type Goo1b = Goo1[float]
echo Goo1b[] # BUG: prints as 
echo Goo1b[].default
doAssert Goo1b[] is Goo1 # bug: runtime error if you uncomment x: T
# doAssert Goo1 is Goo1b[] # Error: illformed AST: Goo1b[] (same as above cases)

type Goo1c = ref Goo1b
doAssert Goo1c[] is Goo1b
# type Goo1d = Goo1c[] # Error: illformed AST: Goo1c[]; this should definitely work: Goo1c was a `ref X`

Current Output

inline in the example

Possible Solution

make [] only compile for ref T or ptr T
other use cases (eg generic access, including for special seq) should use extractGeneric

@mratsim
Copy link
Collaborator

mratsim commented Jul 18, 2019

I already mentioned my skepticism on IRC but I think we should have a deref for typedesc[ref or ptr] in typetraits rather than overloading this already overloaded [] operator nim-lang/RFCs#154

@zah
Copy link
Member

zah commented Jul 18, 2019

Here is the solution I would use:

template `[]`*(T: typedesc): typedesc =
  typeof(default(T)[])

This would also work for user-defined smart pointer types that have a deref operation.

@mratsim
Copy link
Collaborator

mratsim commented Jul 18, 2019

But that requires an instantiation.

@zah
Copy link
Member

zah commented Jul 18, 2019

@mratsim, I've seen this misconception being mentioned before. It's wrong. The expression given to typeof() is not evaluated, it's just analyzed by the compiler front-end in order to determine its type.

@Araq
Copy link
Member

Araq commented Jul 19, 2019

I reverted this PR.

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

4 participants