fixes existing tests

This commit is contained in:
ringabout
2023-03-23 21:08:35 +08:00
parent cae539996a
commit 0175be50a9
3 changed files with 78 additions and 16 deletions

View File

@@ -3072,7 +3072,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType
result = semConv(c, n, expectedType)
elif ambig and n.len == 1:
errorUseQualifier(c, n.info, s)
elif n.len == 1:
elif n.len == 1 or (n.kind == nkCall and useObjConstr(c, n, flags, expectedType)):
result = semObjConstr(c, n, flags, expectedType)
elif s.magic == mNone: result = semDirectOp(c, n, flags, expectedType)
else: result = semMagic(c, n, s, flags, expectedType)

View File

@@ -412,15 +412,83 @@ proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) =
else:
assert false, "Must not enter here."
proc replaceObjConstr(c: PContext; field: PNode, result: PNode, iterField: var int, flags: TExprFlags) =
if iterField >= result.len:
return
case field.kind
of nkRecCase:
# handle defaults if the ast of the field is known
var discriminatorVal =
case result[iterField].kind
of nkExprColonExpr:
semExprFlagDispatched(c, result[iterField][1], flags + {efPreferStatic})
else:
semExprFlagDispatched(c, result[iterField], flags + {efPreferStatic})
let oldIterField = iterField
replaceObjConstr(c, field[0], result, iterField, flags)
if iterField > oldIterField:
doAssert discriminatorVal != nil and discriminatorVal.kind == nkIntLit # todo error messages
let matchedBranch = field.pickCaseBranch discriminatorVal
if matchedBranch != nil:
replaceObjConstr(c, matchedBranch.lastSon, result, iterField, flags)
of nkSym:
if result[iterField].kind != nkExprColonExpr:
result[iterField] = newTree(nkExprColonExpr, field, result[iterField])
inc iterField
elif field.sym.name.id == considerQuotedIdent(c, result[iterField][0]).id:
inc iterField
else:
discard
of nkRecList:
for f in field:
replaceObjConstr(c, f, result, iterField, flags)
else:
assert false
proc expandObjConstr(c: PContext, n: PNode, t: PType, flags: TExprFlags): PNode =
result = n
var hasValue = false
for i in 1..<n.len:
if n[i].kind != nkExprColonExpr:
hasValue = true
break
if hasValue:
var iterField = 1
replaceObjConstr(c, t.n, result, iterField, flags)
proc useObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): bool =
var n = copyTree(n)
var t = semTypeNode(c, n[0], nil)
if t == nil:
return false
if t.skipTypes({tyGenericInst,
tyAlias, tySink, tyOwned, tyRef}).kind != tyObject and
expectedType != nil and expectedType.skipTypes({tyGenericInst,
tyAlias, tySink, tyOwned, tyRef}).kind == tyObject:
t = expectedType
t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned})
if t.kind == tyRef:
t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned})
if t.kind != tyObject:
return false
var iterField = 1
replaceObjConstr(c, t.n, n, iterField, flags)
if iterField < n.len:
return false
result = true
proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
var t = semTypeNode(c, n[0], nil)
result = newNodeIT(nkObjConstr, n.info, t)
for i in 0..<n.len:
result.add n[i]
if t == nil:
return localErrorNode(c, result, "object constructor needs an object type")
if t.skipTypes({tyGenericInst,
tyAlias, tySink, tyOwned, tyRef}).kind != tyObject and
expectedType != nil and expectedType.skipTypes({tyGenericInst,
@@ -443,6 +511,10 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
"'; the object's generic parameters cannot be inferred and must be explicitly given"
)
let expanded = expandObjConstr(c, n, t, flags)
for i in 0..<expanded.len:
result.add expanded[i]
# Check if the object is fully initialized by recursively testing each
# field (if this is a case object, initialized fields in two different
# branches will be reported as an error):

View File

@@ -1,15 +1,3 @@
discard """
cmd: "nim check $file"
errormsg: ""
nimout: '''
t17437.nim(20, 16) Error: undeclared identifier: 'x'
t17437.nim(20, 16) Error: expression 'x' has no type (or is ambiguous)
t17437.nim(20, 19) Error: incorrect object construction syntax
t17437.nim(20, 19) Error: incorrect object construction syntax
t17437.nim(20, 12) Error: expression '' has no type (or is ambiguous)
'''
"""
# bug #17437 invalid object construction should result in error
type
@@ -17,6 +5,8 @@ type
x, y: int
proc m =
var x = 12
var y = 1
var v = V(x: x, y)
m()