mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-15 08:03:46 +00:00
adds modifierMode parameter to typeof (#25815)
This PR adds 3 modes to `typeof` to specify how to handle type modifiers
`var`, `sink` and `lent`.
- typeOfModCompatible
Remove or keep type modifiers in the same way as old typeof. That means
keep `sink` but remove `var` and `lent`.
- typeOfModRemoveModifier
Remove type modifiers.
- typeOfModKeepModifier
Keep type modifiers.
Related to https://github.com/nim-lang/Nim/pull/25779
https://github.com/nim-lang/Nim/issues/25786
(cherry picked from commit 48621c217f)
This commit is contained in:
@@ -106,7 +106,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType
|
||||
|
||||
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
result = semExprCheck(c, n, flags)
|
||||
if result.typ == nil:
|
||||
if result.typ == nil and efInTypeof in flags:
|
||||
result.typ = c.voidType
|
||||
elif result.typ == nil:
|
||||
localError(c.config, n.info, errExprXHasNoType %
|
||||
renderTree(result, {renderNoComments}))
|
||||
result.typ() = errorType(c)
|
||||
|
||||
@@ -43,17 +43,8 @@ proc semAddr(c: PContext; n: PNode): PNode =
|
||||
result.typ() = makePtrType(c, x.typ.skipTypes({tySink}))
|
||||
|
||||
proc semTypeOf(c: PContext; n: PNode): PNode =
|
||||
var m = BiggestInt 1 # typeOfIter
|
||||
if n.len == 3:
|
||||
let mode = semConstExpr(c, n[2])
|
||||
if mode.kind != nkIntLit:
|
||||
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
|
||||
else:
|
||||
m = mode.intVal
|
||||
let typExpr = semTypeOfImpl(c, n)
|
||||
result = newNodeI(nkTypeOfExpr, n.info)
|
||||
inc c.inTypeofContext
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
result.add typExpr
|
||||
if typExpr.typ.kind == tyFromExpr:
|
||||
typExpr.typ.flags.incl tfNonConstExpr
|
||||
|
||||
@@ -1949,6 +1949,57 @@ proc semStaticType(c: PContext, childNode: PNode, prev: PType): PType =
|
||||
result.rawAddSon(base)
|
||||
result.flags.incl tfHasStatic
|
||||
|
||||
proc semTypeOfImpl(c: PContext; n: PNode): PNode =
|
||||
var m = BiggestInt 1 # typeOfIter
|
||||
var modifierMode = BiggestInt 0 # CompatibleTypeModifiers
|
||||
type
|
||||
TypeOfParams = enum
|
||||
topMode
|
||||
topModifier
|
||||
if n.len in 3 .. 4:
|
||||
for i in 2 ..< n.len:
|
||||
var argKind = topMode
|
||||
var arg: PNode = nil
|
||||
if n[i].kind == nkExprEqExpr and n[i][0].kind == nkIdent:
|
||||
# named param
|
||||
case n[i][0].ident.s
|
||||
of "mode": argKind = topMode
|
||||
of "modifierMode": argKind = topModifier
|
||||
else:
|
||||
localError(c.config, n.info, "typeof: got unknown parameter name")
|
||||
arg = n[i][1]
|
||||
else:
|
||||
if i == 2:
|
||||
argKind = topMode
|
||||
else:
|
||||
argKind = topModifier
|
||||
arg = n[i]
|
||||
case argKind
|
||||
of topMode:
|
||||
let mode = semConstExpr(c, arg)
|
||||
if mode.kind != nkIntLit:
|
||||
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
|
||||
else:
|
||||
m = mode.intVal
|
||||
of topModifier:
|
||||
let modMode = semConstExpr(c, arg)
|
||||
if modMode.kind != nkIntLit:
|
||||
localError(c.config, n.info, "typeof: cannot evaluate 'modifierMode' parameter at compile-time")
|
||||
else:
|
||||
modifierMode = modMode.intVal
|
||||
|
||||
inc c.inTypeofContext
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
var typExpr = semExprNoDeref(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
if modifierMode == 0:
|
||||
# CompatibleTypeModifiers
|
||||
typExpr.typ = typExpr.typ.skipTypes({tyVar, tyLent})
|
||||
elif modifierMode == 1:
|
||||
# RemoveTypeModifiers
|
||||
typExpr.typ = typExpr.typ.skipTypes({tyVar, tyLent, tySink})
|
||||
|
||||
result = typExpr
|
||||
|
||||
proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
|
||||
openScope(c)
|
||||
inc c.inTypeofContext
|
||||
@@ -1969,16 +2020,7 @@ proc semTypeOf(c: PContext; n: PNode; prev: PType): PType =
|
||||
|
||||
proc semTypeOf2(c: PContext; n: PNode; prev: PType): PType =
|
||||
openScope(c)
|
||||
var m = BiggestInt 1 # typeOfIter
|
||||
if n.len == 3:
|
||||
let mode = semConstExpr(c, n[2])
|
||||
if mode.kind != nkIntLit:
|
||||
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
|
||||
else:
|
||||
m = mode.intVal
|
||||
inc c.inTypeofContext
|
||||
defer: dec c.inTypeofContext # compiles can raise an exception
|
||||
let ex = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||
let ex = semTypeOfImpl(c, n)
|
||||
closeScope(c)
|
||||
result = ex.typ
|
||||
if result.kind == tyFromExpr:
|
||||
|
||||
Reference in New Issue
Block a user