mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
generate tyFromExpr for typeof static param with generic base type (#24745)
fixes #24743, refs #24718 We cannot do this in general for any expression with generic type because the `typeof` logic is called for things like `type Foo` in: ```nim type Foo[T] = object proc init(_: type Foo) = discard ``` We also cannot use `containsUnresolvedType` to work around this specific case because the base type of `static[auto]` is not unresolved, it is a typeclass that isn't lifted to a parameter. The behavior of generating `tyFromExpr` is also consistent with pre-2.0, so we do this in this special case of `static`.
This commit is contained in:
@@ -55,7 +55,15 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
|
||||
result.add typExpr
|
||||
if typExpr.typ.kind == tyFromExpr:
|
||||
typExpr.typ.flags.incl tfNonConstExpr
|
||||
result.typ() = makeTypeDesc(c, typExpr.typ.skipTypes({tyStatic}))
|
||||
var t = typExpr.typ
|
||||
if t.kind == tyStatic:
|
||||
let base = t.skipTypes({tyStatic})
|
||||
if c.inGenericContext > 0 and base.containsGenericType:
|
||||
t = makeTypeFromExpr(c, copyTree(typExpr))
|
||||
t.flags.incl tfNonConstExpr
|
||||
else:
|
||||
t = base
|
||||
result.typ() = makeTypeDesc(c, t)
|
||||
|
||||
type
|
||||
SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn
|
||||
|
||||
@@ -1933,11 +1933,17 @@ proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let ex = semExprWithType(c, n, {efInTypeof})
|
||||
closeScope(c)
|
||||
let t = ex.typ.skipTypes({tyStatic})
|
||||
fixupTypeOf(c, prev, t)
|
||||
result = t
|
||||
result = ex.typ
|
||||
if result.kind == tyFromExpr:
|
||||
result.flags.incl tfNonConstExpr
|
||||
elif result.kind == tyStatic:
|
||||
let base = result.skipTypes({tyStatic})
|
||||
if c.inGenericContext > 0 and base.containsGenericType:
|
||||
result = makeTypeFromExpr(c, copyTree(ex))
|
||||
result.flags.incl tfNonConstExpr
|
||||
else:
|
||||
result = base
|
||||
fixupTypeOf(c, prev, result)
|
||||
|
||||
proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
|
||||
openScope(c)
|
||||
@@ -1952,11 +1958,17 @@ proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let ex = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
closeScope(c)
|
||||
let t = ex.typ.skipTypes({tyStatic})
|
||||
fixupTypeOf(c, prev, t)
|
||||
result = t
|
||||
result = ex.typ
|
||||
if result.kind == tyFromExpr:
|
||||
result.flags.incl tfNonConstExpr
|
||||
elif result.kind == tyStatic:
|
||||
let base = result.skipTypes({tyStatic})
|
||||
if c.inGenericContext > 0 and base.containsGenericType:
|
||||
result = makeTypeFromExpr(c, copyTree(ex))
|
||||
result.flags.incl tfNonConstExpr
|
||||
else:
|
||||
result = base
|
||||
fixupTypeOf(c, prev, result)
|
||||
|
||||
proc semTypeIdent(c: PContext, n: PNode): PSym =
|
||||
if n.kind == nkSym:
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
# issue #24715
|
||||
block: # issue #24715
|
||||
type H[c: static[float64]] = object
|
||||
value: typeof(c)
|
||||
|
||||
type H[c: static[float64]] = object
|
||||
value: typeof(c)
|
||||
proc u[T: H](_: typedesc[T]) =
|
||||
discard default(T)
|
||||
|
||||
proc u[T: H](_: typedesc[T]) =
|
||||
discard default(T)
|
||||
u(H[1'f64])
|
||||
|
||||
u(H[1'f64])
|
||||
block: # issue #24743
|
||||
type
|
||||
K[w: static[auto]] = typeof(w)
|
||||
V = object
|
||||
a: K[0]
|
||||
GenericV[w: static[auto]] = object
|
||||
a: typeof(w)
|
||||
|
||||
var x: GenericV[0]
|
||||
doAssert x.a is int
|
||||
var y: GenericV["abc"]
|
||||
doAssert y.a is string
|
||||
|
||||
Reference in New Issue
Block a user