* don't sem const objectConstr defaults * fixes * add `efSkipFieldVisibilityCheck`; fixes nkBracket types * fixes #20681 * fixes tests * suggestion from @metagn * fixes tests Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
This commit is contained in:
parent
779b1cc5be
commit
141abb7b75
7 changed files with 50 additions and 47 deletions
|
|
@ -69,7 +69,8 @@ type
|
||||||
efWantStmt, efAllowStmt, efDetermineType, efExplain,
|
efWantStmt, efAllowStmt, efDetermineType, efExplain,
|
||||||
efWantValue, efOperand, efNoSemCheck,
|
efWantValue, efOperand, efNoSemCheck,
|
||||||
efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
|
efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
|
||||||
efNoUndeclared, efIsDotCall, efCannotBeDotCall
|
efNoUndeclared, efIsDotCall, efCannotBeDotCall,
|
||||||
|
efSkipFieldVisibilityCheck
|
||||||
# Use this if undeclared identifiers should not raise an error during
|
# Use this if undeclared identifiers should not raise an error during
|
||||||
# overload resolution.
|
# overload resolution.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3075,7 +3075,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType
|
||||||
of paTupleFields: result = semTupleFieldsConstr(c, n, flags, expectedType)
|
of paTupleFields: result = semTupleFieldsConstr(c, n, flags, expectedType)
|
||||||
of paSingle: result = semExpr(c, n[0], flags, expectedType)
|
of paSingle: result = semExpr(c, n[0], flags, expectedType)
|
||||||
of nkCurly: result = semSetConstr(c, n, expectedType)
|
of nkCurly: result = semSetConstr(c, n, expectedType)
|
||||||
of nkBracket: result = semArrayConstr(c, n, flags, expectedType)
|
of nkBracket:
|
||||||
|
result = semArrayConstr(c, n, flags, expectedType)
|
||||||
of nkObjConstr: result = semObjConstr(c, n, flags, expectedType)
|
of nkObjConstr: result = semObjConstr(c, n, flags, expectedType)
|
||||||
of nkLambdaKinds: result = semProcAux(c, n, skProc, lambdaPragmas, flags)
|
of nkLambdaKinds: result = semProcAux(c, n, skProc, lambdaPragmas, flags)
|
||||||
of nkDerefExpr: result = semDeref(c, n)
|
of nkDerefExpr: result = semDeref(c, n)
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,8 @@ proc semConstrField(c: PContext, flags: TExprFlags,
|
||||||
let assignment = locateFieldInInitExpr(c, field, initExpr)
|
let assignment = locateFieldInInitExpr(c, field, initExpr)
|
||||||
if assignment != nil:
|
if assignment != nil:
|
||||||
if nfSem in assignment.flags: return assignment[1]
|
if nfSem in assignment.flags: return assignment[1]
|
||||||
if nfUseDefaultField in assignment[1].flags:
|
if nfUseDefaultField in assignment[1].flags or
|
||||||
|
efSkipFieldVisibilityCheck in flags:
|
||||||
discard
|
discard
|
||||||
elif not fieldVisible(c, field):
|
elif not fieldVisible(c, field):
|
||||||
localError(c.config, initExpr.info,
|
localError(c.config, initExpr.info,
|
||||||
|
|
@ -415,7 +416,10 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
|
||||||
# field (if this is a case object, initialized fields in two different
|
# field (if this is a case object, initialized fields in two different
|
||||||
# branches will be reported as an error):
|
# branches will be reported as an error):
|
||||||
var constrCtx = initConstrContext(t, result)
|
var constrCtx = initConstrContext(t, result)
|
||||||
let (initResult, defaults) = semConstructTypeAux(c, constrCtx, flags)
|
let (initResult, defaults) = if nfUseDefaultField in n.flags:
|
||||||
|
semConstructTypeAux(c, constrCtx, flags + {efSkipFieldVisibilityCheck})
|
||||||
|
else:
|
||||||
|
semConstructTypeAux(c, constrCtx, flags)
|
||||||
result[0].sons.add defaults
|
result[0].sons.add defaults
|
||||||
var hasError = false # needed to split error detect/report for better msgs
|
var hasError = false # needed to split error detect/report for better msgs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,16 @@ proc isRecursiveType(t: PType, cycleDetector: var IntSet): bool =
|
||||||
else:
|
else:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
proc fitDefaultNode(c: PContext, n: PNode): PType =
|
||||||
|
let expectedType = if n[^2].kind != nkEmpty: semTypeNode(c, n[^2], nil) else: nil
|
||||||
|
n[^1] = semConstExpr(c, n[^1], expectedType = expectedType)
|
||||||
|
if n[^2].kind != nkEmpty:
|
||||||
|
if expectedType != nil:
|
||||||
|
n[^1] = fitNodeConsiderViewType(c, expectedType, n[^1], n[^1].info)
|
||||||
|
result = n[^1].typ
|
||||||
|
else:
|
||||||
|
result = n[^1].typ
|
||||||
|
|
||||||
proc isRecursiveType*(t: PType): bool =
|
proc isRecursiveType*(t: PType): bool =
|
||||||
# handle simple recusive types before typeFinalPass
|
# handle simple recusive types before typeFinalPass
|
||||||
var cycleDetector = initIntSet()
|
var cycleDetector = initIntSet()
|
||||||
|
|
@ -484,13 +494,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||||
checkMinSonsLen(a, 3, c.config)
|
checkMinSonsLen(a, 3, c.config)
|
||||||
var hasDefaultField = a[^1].kind != nkEmpty
|
var hasDefaultField = a[^1].kind != nkEmpty
|
||||||
if hasDefaultField:
|
if hasDefaultField:
|
||||||
a[^1] = semConstExpr(c, a[^1])
|
typ = fitDefaultNode(c, a)
|
||||||
if a[^2].kind != nkEmpty:
|
|
||||||
typ = semTypeNode(c, a[^2], nil)
|
|
||||||
let def = semExprWithType(c, a[^1], {}, typ)
|
|
||||||
typ = fitNodeConsiderViewType(c, typ, def, def.info).typ
|
|
||||||
else:
|
|
||||||
typ = a[^1].typ
|
|
||||||
elif a[^2].kind != nkEmpty:
|
elif a[^2].kind != nkEmpty:
|
||||||
typ = semTypeNode(c, a[^2], nil)
|
typ = semTypeNode(c, a[^2], nil)
|
||||||
if c.graph.config.isDefined("nimPreviewRangeDefault") and typ.skipTypes(abstractInst).kind == tyRange:
|
if c.graph.config.isDefined("nimPreviewRangeDefault") and typ.skipTypes(abstractInst).kind == tyRange:
|
||||||
|
|
@ -824,13 +828,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
|
||||||
var typ: PType
|
var typ: PType
|
||||||
var hasDefaultField = n[^1].kind != nkEmpty
|
var hasDefaultField = n[^1].kind != nkEmpty
|
||||||
if hasDefaultField:
|
if hasDefaultField:
|
||||||
n[^1] = semConstExpr(c, n[^1])
|
typ = fitDefaultNode(c, n)
|
||||||
if n[^2].kind != nkEmpty:
|
|
||||||
typ = semTypeNode(c, n[^2], nil)
|
|
||||||
let def = semExprWithType(c, n[^1], {}, typ)
|
|
||||||
typ = fitNodeConsiderViewType(c, typ, def, def.info).typ
|
|
||||||
else:
|
|
||||||
typ = n[^1].typ
|
|
||||||
propagateToOwner(rectype, typ)
|
propagateToOwner(rectype, typ)
|
||||||
elif n[^2].kind == nkEmpty:
|
elif n[^2].kind == nkEmpty:
|
||||||
localError(c.config, n.info, errTypeExpected)
|
localError(c.config, n.info, errTypeExpected)
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,9 @@ discard """
|
||||||
errormsg: ""
|
errormsg: ""
|
||||||
nimout:
|
nimout:
|
||||||
'''
|
'''
|
||||||
tdefaultfieldscheck.nim(17, 17) Error: type mismatch: got <string> but expected 'int'
|
tdefaultfieldscheck.nim(14, 17) Error: type mismatch: got <string> but expected 'int'
|
||||||
tdefaultfieldscheck.nim(18, 20) Error: type mismatch: got <int literal(12)> but expected 'string'
|
tdefaultfieldscheck.nim(15, 20) Error: type mismatch: got <int literal(12)> but expected 'string'
|
||||||
tdefaultfieldscheck.nim(20, 16) Error: type mismatch: got <float64> but expected 'int'
|
tdefaultfieldscheck.nim(17, 16) Error: type mismatch: got <float64> but expected 'int'
|
||||||
tdefaultfieldscheck.nim(17, 5) Error: type mismatch: got <string> but expected 'int'
|
|
||||||
tdefaultfieldscheck.nim(18, 5) Error: type mismatch: got <int literal(12)> but expected 'string'
|
|
||||||
tdefaultfieldscheck.nim(20, 5) Error: type mismatch: got <float64> but expected 'int'
|
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "conversion from int literal(0) to range 1..5(int) is invalid"
|
errormsg: "cannot convert 0 to range 1..5(int)"
|
||||||
line: 9
|
line: 9
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ discard """
|
||||||
targets: "c cpp js"
|
targets: "c cpp js"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import times
|
import std/[times, tables]
|
||||||
|
|
||||||
type
|
type
|
||||||
Guess = object
|
Guess = object
|
||||||
|
|
@ -222,6 +222,18 @@ template main {.dirty.} =
|
||||||
doAssert y.time == 1.2
|
doAssert y.time == 1.2
|
||||||
doAssert y.scale == 1
|
doAssert y.scale == 1
|
||||||
|
|
||||||
|
block:
|
||||||
|
var my = @[1, 2, 3, 4, 5]
|
||||||
|
my.setLen(0)
|
||||||
|
my.setLen(5)
|
||||||
|
doAssert my == @[0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
block:
|
||||||
|
var my = "hello"
|
||||||
|
my.setLen(0)
|
||||||
|
my.setLen(5)
|
||||||
|
doAssert $(@my) == """@['\x00', '\x00', '\x00', '\x00', '\x00']"""
|
||||||
|
|
||||||
block: # array
|
block: # array
|
||||||
var x: array[10, Object] = arrayWith(default(Object), 10)
|
var x: array[10, Object] = arrayWith(default(Object), 10)
|
||||||
let y = x[0]
|
let y = x[0]
|
||||||
|
|
@ -387,12 +399,11 @@ template main {.dirty.} =
|
||||||
doAssert x.def.obj == default(ObjectBase)
|
doAssert x.def.obj == default(ObjectBase)
|
||||||
doAssert x.def.name == ""
|
doAssert x.def.name == ""
|
||||||
|
|
||||||
when not defined(cpp):
|
block:
|
||||||
block:
|
var x = default(Member)
|
||||||
var x = default(Member)
|
doAssert x.def.id == 777
|
||||||
doAssert x.def.id == 777
|
doAssert x.def.obj == default(ObjectBase)
|
||||||
doAssert x.def.obj == default(ObjectBase)
|
doAssert x.def.name == "fine"
|
||||||
doAssert x.def.name == "fine"
|
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var x {.noinit.} = 12
|
var x {.noinit.} = 12
|
||||||
|
|
@ -408,22 +419,13 @@ template main {.dirty.} =
|
||||||
var z {.noinit.}: Pure = Pure(id: 77)
|
var z {.noinit.}: Pure = Pure(id: 77)
|
||||||
doAssert z.id == 77
|
doAssert z.id == 77
|
||||||
|
|
||||||
|
block: # bug #20681
|
||||||
|
type A = object
|
||||||
|
d: DateTime = DateTime()
|
||||||
|
|
||||||
proc main1 =
|
let x = default(A)
|
||||||
var my = @[1, 2, 3, 4, 5]
|
doAssert $x == "(d: Uninitialized DateTime)"
|
||||||
my.setLen(0)
|
|
||||||
my.setLen(5)
|
|
||||||
doAssert my == @[0, 0, 0, 0, 0]
|
|
||||||
|
|
||||||
proc main2 =
|
|
||||||
var my = "hello"
|
|
||||||
my.setLen(0)
|
|
||||||
my.setLen(5)
|
|
||||||
doAssert $(@my) == """@['\x00', '\x00', '\x00', '\x00', '\x00']"""
|
|
||||||
|
|
||||||
when defined(gcArc) or defined(gcOrc):
|
|
||||||
main1()
|
|
||||||
main2()
|
|
||||||
|
|
||||||
static: main()
|
static: main()
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue