better error messages

This commit is contained in:
ringabout
2023-03-24 23:24:37 +08:00
parent a56697b513
commit 6f8b9b7cc4
2 changed files with 22 additions and 22 deletions

View File

@@ -414,6 +414,7 @@ proc defaultConstructionError(c: PContext, t: PType, info: TLineInfo) =
proc replaceObjConstr(c: PContext; field: PNode, result: PNode, iterField: var int, flags: TExprFlags) =
if iterField >= result.len:
inc iterField
return
case field.kind
of nkRecCase:
@@ -438,7 +439,7 @@ proc replaceObjConstr(c: PContext; field: PNode, result: PNode, iterField: var i
elif field.sym.name.id == considerQuotedIdent(c, result[iterField][0]).id:
inc iterField
else:
discard
localError(c.config, result.info, "When mixing named fields and unnamed fields, every field needs to be initialized in order")
of nkRecList:
for f in field:
replaceObjConstr(c, f, result, iterField, flags)
@@ -455,6 +456,10 @@ proc expandObjConstr(c: PContext, n: PNode, t: PType, flags: TExprFlags): PNode
if hasValue:
var iterField = 1
replaceObjConstr(c, t.n, result, iterField, flags)
if iterField > result.len:
localError(c.config, result.info, "When mixing named fields and unnamed fields, every field needs to be initialized in order")
elif iterField < result.len:
localError(c.config, result.info, "The object construction is given more fields than required")
proc filterObjConstr(c: PContext; field: PNode, n: PNode, iterField: var int, flags: TExprFlags): bool =
result = true
@@ -469,19 +474,19 @@ proc filterObjConstr(c: PContext; field: PNode, n: PNode, iterField: var int, fl
semExprFlagDispatched(c, n[iterField][1], flags + {efPreferStatic})
else:
semExprFlagDispatched(c, n[iterField], flags + {efPreferStatic})
let oldIterField = iterField
if not filterObjConstr(c, field[0], n, iterField, flags):
return false
if iterField > oldIterField:
doAssert discriminatorVal != nil and discriminatorVal.kind == nkIntLit # todo error messages
let matchedBranch = field.pickCaseBranch discriminatorVal
if matchedBranch != nil:
result = filterObjConstr(c, matchedBranch.lastSon, n, iterField, flags)
else:
result = false
if discriminatorVal == nil or discriminatorVal.kind != nkIntLit:
return false
let matchedBranch = field.pickCaseBranch discriminatorVal
if matchedBranch != nil:
result = filterObjConstr(c, matchedBranch.lastSon, n, iterField, flags)
else:
result = false
of nkSym:
if n[iterField].kind != nkExprColonExpr:
inc iterField
@@ -516,6 +521,11 @@ proc useObjConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType
if t.kind != tyObject:
return false
for i in 1..<n.len:
if n[i].kind == nkExprColonExpr:
return true
var iterField = 1
result = filterObjConstr(c, t.n, n, iterField, flags)
if iterField != n.len:

View File

@@ -4,12 +4,12 @@ type
b, c: int
block: # positional construction
## It specifies all the unnamed parameters
## It specifies all the unnamed fields
var x = Vector(1, 2, 3)
doAssert x.b == 2
block:
## unnamed parameters can be mixed with named parameters
## unnamed fields can be mixed with named fields
block:
var x = Vector(a: 1, 2, 3)
doAssert x.c == 3
@@ -22,14 +22,8 @@ block:
var x = Vector(1, 2, c: 3)
doAssert x.c == 3
block:
## Parameters can be omitted before a named parameter
var x = Vector(b: 2, 3)
doAssert x.c == 3
block:
## Object variants support unnamed parameters for tags, which should be known at the compile time.
## Object variants support unnamed fields for tags, which should be known at the compile time.
type
Color = enum
Red, Blue, Yellow
@@ -72,7 +66,3 @@ block:
block:
var x = Ciao(12, flag: true, 1, "123")
doAssert x.num == 1
block:
var x = Ciao(flag: true, 1, "123")
doAssert x.num == 1