mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
fixes #1783
This commit is contained in:
@@ -1039,8 +1039,8 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
addToResult(elem)
|
||||
return
|
||||
elif t.kind != tyGenericBody:
|
||||
#we likely got code of the form TypeA[TypeB] where TypeA is
|
||||
#not generic.
|
||||
# we likely got code of the form TypeA[TypeB] where TypeA is
|
||||
# not generic.
|
||||
localError(n.info, errNoGenericParamsAllowedForX, s.name.s)
|
||||
return newOrPrevType(tyError, prev, c)
|
||||
else:
|
||||
@@ -1057,9 +1057,14 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
var isConcrete = true
|
||||
|
||||
for i in 1 .. <m.call.len:
|
||||
let typ = m.call[i].typ.skipTypes({tyTypeDesc})
|
||||
if containsGenericType(typ): isConcrete = false
|
||||
addToResult(typ)
|
||||
var typ = m.call[i].typ
|
||||
if typ.kind == tyTypeDesc and typ.sons[0].kind == tyNone:
|
||||
isConcrete = false
|
||||
addToResult(typ)
|
||||
else:
|
||||
typ = typ.skipTypes({tyTypeDesc})
|
||||
if containsGenericType(typ): isConcrete = false
|
||||
addToResult(typ)
|
||||
|
||||
if isConcrete:
|
||||
if s.ast == nil and s.typ.kind != tyCompositeTypeClass:
|
||||
|
||||
@@ -89,6 +89,7 @@ type
|
||||
info*: TLineInfo
|
||||
allowMetaTypes*: bool # allow types such as seq[Number]
|
||||
# i.e. the result contains unresolved generics
|
||||
skipTypedesc*: bool # wether we should skip typeDescs
|
||||
|
||||
proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType
|
||||
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
|
||||
@@ -276,6 +277,8 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
else:
|
||||
idTablePut(cl.localCache, t, result)
|
||||
|
||||
let oldSkipTypedesc = cl.skipTypedesc
|
||||
cl.skipTypedesc = true
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
var x = replaceTypeVarsT(cl, t.sons[i])
|
||||
assert x.kind != tyGenericInvocation
|
||||
@@ -289,6 +292,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||
rawAddSon(result, header.sons[i])
|
||||
|
||||
var newbody = replaceTypeVarsT(cl, lastSon(body))
|
||||
cl.skipTypedesc = oldSkipTypedesc
|
||||
newbody.flags = newbody.flags + (t.flags + body.flags - tfInstClearedFlags)
|
||||
result.flags = result.flags + newbody.flags - tfInstClearedFlags
|
||||
# This is actually wrong: tgeneric_closure fails with this line:
|
||||
@@ -400,7 +404,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||
let lookup = PType(idTableGet(cl.typeMap, t)) # lookupTypeVar(cl, t)
|
||||
if lookup != nil:
|
||||
result = lookup
|
||||
if tfUnresolved in t.flags: result = result.base
|
||||
if tfUnresolved in t.flags or cl.skipTypedesc: result = result.base
|
||||
elif t.sons[0].kind != tyNone:
|
||||
result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0]))
|
||||
|
||||
|
||||
37
tests/metatype/ttypedesc2.nim
Normal file
37
tests/metatype/ttypedesc2.nim
Normal file
@@ -0,0 +1,37 @@
|
||||
discard """
|
||||
output: "(x: a)"
|
||||
"""
|
||||
|
||||
type
|
||||
Bar[T] = object
|
||||
x: T
|
||||
|
||||
proc infer(T: typeDesc): Bar[T] = Bar[T](x: 'a')
|
||||
|
||||
let foo = infer(char)
|
||||
echo foo
|
||||
|
||||
when true:
|
||||
# bug #1783
|
||||
|
||||
type
|
||||
uoffset_t* = uint32
|
||||
FlatBufferBuilder* = object
|
||||
|
||||
uarray* {.unchecked.} [T] = array [0..0, T]
|
||||
Array* [T] = object
|
||||
o*: uoffset_t
|
||||
len*: int
|
||||
data*: ptr uarray[T]
|
||||
|
||||
proc ca* (fbb: ptr FlatBufferBuilder, T: typedesc, len: int): Array[T] {.noinit.} =
|
||||
result.len = len
|
||||
|
||||
var fbb: ptr FlatBufferBuilder
|
||||
let boolarray = ca(fbb, bool, 2)
|
||||
let boolarray2 = fbb.ca(bool, 2)
|
||||
|
||||
# bug #1664
|
||||
type Point[T] = tuple[x, y: T]
|
||||
proc origin(T: typedesc): Point[T] = discard
|
||||
discard origin(int)
|
||||
Reference in New Issue
Block a user