Skip to content

Commit 7f94bf3

Browse files
bors[bot]Clyybber
andauthored
239: Turn more localReports into newError r=Clyybber a=Clyybber ## Summary Turn more localReports into newError and some cleanup and refactor to not loose nkError nodes. Co-authored-by: Clyybber <[email protected]>
2 parents b47c543 + 4bf54da commit 7f94bf3

File tree

17 files changed

+136
-99
lines changed

17 files changed

+136
-99
lines changed

compiler/front/cli_reporter.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,7 @@ proc reportBody*(conf: ConfigRef, r: SemReport): string =
23042304
result = "a pattern cannot be empty"
23052305

23062306
of rsemInvalidExpression:
2307-
result = "invalid expression"
2307+
result = "invalid expression: " & render(r.ast)
23082308

23092309
of rsemParameterRedefinition:
23102310
result = "attempt to redefine: '" & r.symstr & "'"

compiler/sem/sem.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool)
103103

104104
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType
105105
proc semStmt(c: PContext, n: PNode; flags: TExprFlags): PNode
106-
proc semOpAux(c: PContext, n: PNode)
106+
proc semOpAux(c: PContext, n: PNode): bool
107107
proc semParamList(c: PContext, n, genericParams: PNode, s: PSym)
108108
proc addParams(c: PContext, n: PNode, kind: TSymKind)
109109
proc maybeAddResult(c: PContext, s: PSym, n: PNode)

compiler/sem/semcall.nim

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,20 @@ proc resolveOverloads(c: PContext, n: PNode,
314314
var f = n[0]
315315
if f.kind == nkBracketExpr:
316316
# fill in the bindings:
317-
semOpAux(c, f)
317+
let hasError = semOpAux(c, f)
318318
initialBinding = f
319-
f = f[0]
319+
if hasError:
320+
f = c.config.wrapErrorInSubTree(f)
321+
else:
322+
f = f[0]
320323
else:
321324
initialBinding = nil
322325

326+
if f.isError:
327+
n[0] = f
328+
result.call = c.config.wrapErrorInSubTree(n)
329+
return
330+
323331
template pickBest(headSymbol) =
324332
pickBestCandidate(c, headSymbol, n, initialBinding,
325333
filter, result, alt, errors, flags)
@@ -576,7 +584,7 @@ proc semOverloadedCall(c: PContext, n: PNode,
576584

577585
result = semResolvedCall(c, r, n, flags)
578586

579-
elif r.call != nil and r.call.kind == nkError:
587+
elif r.call.isError:
580588
result = r.call
581589

582590
elif efNoUndeclared notin flags:
@@ -586,9 +594,7 @@ proc semOverloadedCall(c: PContext, n: PNode,
586594
result = r.call
587595

588596
proc explicitGenericInstError(c: PContext; n: PNode): PNode =
589-
localReport(c.config, getCallLineInfo(n), reportAst(rsemCannotInstantiate, n))
590-
591-
result = n
597+
c.config.newError(n, reportAst(rsemCannotInstantiate, n), posInfo = getCallLineInfo(n))
592598

593599
proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
594600
# binding has to stay 'nil' for this to work!
@@ -618,7 +624,11 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
618624
assert n.kind == nkBracketExpr
619625
for i in 1..<n.len:
620626
let e = semExpr(c, n[i])
621-
if e.typ == nil:
627+
if e.isError:
628+
n[i] = e
629+
result = c.config.wrapErrorInSubTree(n)
630+
return
631+
elif e.typ == nil:
622632
n[i].typ = errorType(c)
623633
else:
624634
n[i].typ = e.typ.skipTypes({tyTypeDesc})

compiler/sem/semexprs.nim

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,22 @@ template rejectEmptyNode(n: PNode) =
3838
semReportIllformedAst(c.config, n, "Unexpected empty node")
3939

4040
proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
41-
rejectEmptyNode(n)
4241
# same as 'semExprWithType' but doesn't check for proc vars
42+
rejectEmptyNode(n)
4343
result = semExpr(c, n, flags + {efOperand})
4444
if result.typ != nil:
4545
# XXX tyGenericInst here?
4646
if result.typ.kind == tyProc and hasUnresolvedParams(result, {efOperand}):
47-
localReport(c.config, n, reportAst(rsemProcHasNoConcreteType, n))
47+
result = c.config.newError(n, reportAst(rsemProcHasNoConcreteType, n))
4848

49-
if result.typ.kind in {tyVar, tyLent}:
49+
elif result.typ.kind in {tyVar, tyLent}:
5050
result = newDeref(result)
5151

5252
elif {efWantStmt, efAllowStmt} * flags != {}:
5353
result.typ = newTypeS(tyVoid, c)
5454

5555
else:
56-
localReport(c.config, n.info, reportAst(
57-
rsemExpressionHasNoType, result))
58-
59-
result.typ = errorType(c)
56+
result = c.config.newError(n, reportAst(rsemExpressionHasNoType, result))
6057

6158
proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode =
6259
rejectEmptyNode(n)
@@ -67,53 +64,44 @@ proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode =
6764
isError = result.kind == nkError
6865
isTypeError = result.typ != nil and result.typ.kind == tyError
6966

70-
if isEmpty or (isTypeError and not isError):
71-
# bug #12741, redundant error messages are the lesser evil here:
72-
localReport(c.config, n, reportSem rsemExpressionHasNoType)
73-
74-
if isError and isTypeError:
75-
# XXX: Error message should mention that it's an error node/type
76-
# newer code paths propagate nkError nodes
77-
result = c.config.newError(result, reportSem rsemExpressionHasNoType, args = @[n])
67+
if isError:
68+
discard # no need to do anything
7869

79-
if isEmpty:
80-
# do not produce another redundant error message:
81-
result = errorNode(c, n)
70+
elif isEmpty or isTypeError:
71+
# bug #12741, redundant error messages are the lesser evil here:
72+
result = c.config.newError(n, reportSem rsemExpressionHasNoType)
8273

8374
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
8475
result = semExprCheck(c, n, flags)
8576
if result.typ == nil and efInTypeof in flags:
8677
result.typ = c.voidType
78+
8779
elif result.typ == nil or result.typ == c.enforceVoidContext:
88-
localReport(c.config, n.info, reportAst(
80+
result = c.config.newError(n, reportAst(
8981
rsemExpressionHasNoType, result))
9082

91-
result.typ = errorType(c)
9283
elif result.typ.kind == tyError:
9384
# associates the type error to the current owner
9485
result.typ = errorType(c)
86+
9587
elif result.typ.kind in {tyVar, tyLent}:
9688
result = newDeref(result)
9789

9890
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
9991
result = semExprCheck(c, n, flags)
10092
if result.typ == nil:
101-
localReport(c.config, n.info, reportAst(
93+
result = c.config.newError(n, reportAst(
10294
rsemExpressionHasNoType, result))
10395

104-
result.typ = errorType(c)
105-
10696
proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
10797
result = symChoice(c, n, s, scClosed)
10898

10999
proc inlineConst(c: PContext, n: PNode, s: PSym): PNode {.inline.} =
110-
result = copyTree(s.ast)
111-
if result.isNil:
112-
localReport(c.config, n.info, reportSym(
100+
if s.ast.isNil:
101+
result = c.config.newError(n, reportSym(
113102
rsemConstantOfTypeHasNoValue, s))
114-
115-
result = newSymNode(s)
116103
else:
104+
result = copyTree(s.ast)
117105
result.typ = s.typ
118106
result.info = n.info
119107

@@ -280,10 +268,9 @@ proc isOwnedSym(c: PContext; n: PNode): bool =
280268

281269
proc semConv(c: PContext, n: PNode): PNode =
282270
if n.len != 2:
283-
localReport(c.config, n.info, semReportCountMismatch(
271+
result = c.config.newError(n, semReportCountMismatch(
284272
rsemTypeConversionArgumentMismatch, expected = 1, got = n.len - 1, n))
285-
286-
return n
273+
return
287274

288275
result = newNodeI(nkConv, n.info)
289276

@@ -325,7 +312,8 @@ proc semConv(c: PContext, n: PNode): PNode =
325312
# special case to make MyObject(x = 3) produce a nicer error message:
326313
if n[1].kind == nkExprEqExpr and
327314
targetType.skipTypes(abstractPtrs).kind == tyObject:
328-
localReport(c.config, n, reportSem rsemUnexpectedEqInObjectConstructor)
315+
result = c.config.newError(n, reportSem rsemUnexpectedEqInObjectConstructor, posInfo = n[1].info)
316+
return
329317

330318
var op = semExprWithType(c, n[1])
331319
if targetType.kind != tyGenericParam and targetType.isMetaType:
@@ -359,13 +347,13 @@ proc semConv(c: PContext, n: PNode): PNode =
359347
of convNotLegal:
360348
result = fitNode(c, result.typ, result[1], result.info)
361349
if result == nil:
362-
localReport(c.config, n.info, SemReport(
350+
result = c.config.newError(n, SemReport(
363351
kind: rsemIllegalConversion,
364352
typeMismatch: @[
365353
c.config.typeMismatch(formal = result.typ, actual = op.typ)]))
366354

367355
of convNotInRange:
368-
localReport(c.config, n.info, reportAst(
356+
result = c.config.newError(n, reportAst(
369357
rsemCannotBeConvertedTo, op, typ = result.typ))
370358

371359
else:
@@ -385,14 +373,16 @@ proc semCast(c: PContext, n: PNode): PNode =
385373
let targetType = semTypeNode(c, n[0], nil)
386374
let castedExpr = semExprWithType(c, n[1])
387375
if tfHasMeta in targetType.flags:
388-
localReport(c.config, n[0].info, reportTyp(
389-
rsemCannotCastToNonConcrete, targetType))
376+
result = c.config.newError(n, reportTyp(rsemCannotCastToNonConcrete, targetType),
377+
posInfo = n[0].info)
378+
return
390379

391380
if not isCastable(c, targetType, castedExpr.typ):
392-
localReport(c.config, n.info, SemReport(
381+
result = c.config.newError(n, SemReport(
393382
kind: rsemCannotCastTypes,
394383
typeMismatch: @[
395384
c.config.typeMismatch(formal = targetType, actual = castedExpr.typ)]))
385+
return
396386

397387
result = newNodeI(nkCast, n.info)
398388
result.typ = targetType
@@ -403,8 +393,9 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
403393
const
404394
opToStr: array[mLow..mHigh, string] = ["low", "high"]
405395
if n.len != 2:
406-
localReport(c.config, n.info, reportStr(
396+
result = c.config.newError(n, reportStr(
407397
rsemExpectedTypeOrValue, opToStr[m]))
398+
return
408399

409400
else:
410401
n[1] = semExprWithType(c, n[1], {efDetermineType})
@@ -424,10 +415,11 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode =
424415
# that could easily turn into an infinite recursion in semtypinst
425416
n.typ = makeTypeFromExpr(c, n.copyTree)
426417
else:
427-
localReport(c.config, n.info, reportTyp(
418+
result = c.config.newError(n, reportTyp(
428419
rsemInvalidArgumentFor, typ, str = opToStr[m]))
420+
return
429421

430-
result = n
422+
result = n
431423

432424
proc fixupStaticType(c: PContext, n: PNode) =
433425
# This proc can be applied to evaluated expressions to assign
@@ -503,8 +495,9 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
503495

504496
proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
505497
if n.len != 3:
506-
localReport(c.config, n.info, semReportCountMismatch(
498+
result = c.config.newError(n, semReportCountMismatch(
507499
rsemWrongNumberOfArguments, 1, 2, n))
500+
return
508501

509502
let boolType = getSysType(c.graph, n.info, tyBool)
510503
n.typ = boolType
@@ -545,17 +538,24 @@ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
545538
n[1] = makeTypeSymNode(c, lhsType, n[1].info)
546539
result = isOpImpl(c, n, flags)
547540

548-
proc semOpAux(c: PContext, n: PNode) =
541+
proc semOpAux(c: PContext, n: PNode): bool =
542+
## Returns whether n contains errors
543+
## This does not not wrap child errors in n
544+
## the caller has to handle that
549545
const flags = {efDetermineType}
550546
for i in 1..<n.len:
551547
var a = n[i]
552548
if a.kind == nkExprEqExpr and a.len == 2:
553549
let info = a[0].info
554550
a[0] = newIdentNode(considerQuotedIdent(c, a[0], a), info)
555551
a[1] = semExprWithType(c, a[1], flags)
552+
if a[1].isError:
553+
result = true
556554
a.typ = a[1].typ
557555
else:
558556
n[i] = semExprWithType(c, a, flags)
557+
if n[1].isError:
558+
result = true
559559

560560
proc overloadedCallOpr(c: PContext, n: PNode): PNode =
561561
# quick check if there is *any* () operator overloaded:
@@ -655,9 +655,11 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
655655
if x.kind == nkExprColonExpr and x.len == 2:
656656
var idx = semConstExpr(c, x[0])
657657
if not isOrdinalType(idx.typ):
658-
localReport(c.config, idx):
659-
reportTyp(rsemExpectedOrdinal, idx.typ, ast = result).withIt do:
660-
it.wrongNode = idx
658+
result = n
659+
result[0][0] = c.config.newError(x[0]):
660+
reportTyp(rsemExpectedOrdinal, idx.typ, ast = result).withIt: it.wrongNode = idx
661+
result = c.config.wrapErrorInSubTree(result)
662+
return
661663

662664
else:
663665
firstIndex = getOrdValue(idx)
@@ -676,25 +678,27 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
676678
c, toInt64(firstIndex),
677679
toInt64(lastValidIndex), n.info, indexType)
678680

679-
localReport(c.config, n.info, SemReport(
681+
result = c.config.newError(n, SemReport(
680682
kind: rsemIndexOutOfBounds,
681683
typ: validIndex,
682-
ast: n,
683684
countMismatch: (expected: toInt128(i), got: toInt128(n.len))
684685
))
686+
return
685687

686688
x = n[i]
687689
if x.kind == nkExprColonExpr and x.len == 2:
688690
var idx = semConstExpr(c, x[0])
689691
idx = fitNode(c, indexType, idx, x.info)
690692
if lastIndex + 1 != getOrdValue(idx):
691-
localReport(c.config, x.info, SemReport(
693+
result = n
694+
result[i] = c.config.newError(x, SemReport(
692695
kind: rsemInvalidOrderInArrayConstructor,
693-
ast: x,
694696
typ: idx.typ,
695697
countMismatch: (
696698
expected: lastIndex + 1,
697699
got: getOrdValue(idx))))
700+
result = c.config.wrapErrorInSubTree(result)
701+
return
698702

699703
x = x[1]
700704

@@ -1074,7 +1078,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
10741078
setGenericParams(c, n[0])
10751079
return semDirectOp(c, n, flags)
10761080

1077-
semOpAux(c, n)
1081+
discard semOpAux(c, n)
10781082
var t: PType = nil
10791083
if n[0].typ != nil:
10801084
t = skipTypes(n[0].typ, abstractInst+{tyOwned}-{tyTypeDesc, tyDistinct})
@@ -1637,7 +1641,9 @@ proc maybeInstantiateGeneric(c: PContext, n: PNode, s: PSym): PNode =
16371641
result = n
16381642
else:
16391643
result = explicitGenericInstantiation(c, n, s)
1640-
if result == n:
1644+
if result.isError:
1645+
discard
1646+
elif result == n:
16411647
n[0] = copyTree(result[0])
16421648
else:
16431649
n[0] = result
@@ -3259,7 +3265,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
32593265
localReport(c.config, n, reportSem rsemInvalidBindContext)
32603266
of nkError: discard "ignore errors for now"
32613267
else:
3262-
localReport(c.config, n, reportSem rsemInvalidExpression)
3268+
result = c.config.newError(n, reportSem rsemInvalidExpression)
32633269

32643270
if result != nil:
32653271
incl(result.flags, nfSem)

compiler/sem/semmagic.nim

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ proc semTypeOf(c: PContext; n: PNode): PNode =
3636
result = newNodeI(nkTypeOfExpr, n.info)
3737
let typExpr = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
3838
result.add typExpr
39-
result.typ = makeTypeDesc(c, typExpr.typ)
39+
if typExpr.isError:
40+
result = c.config.wrapErrorInSubTree(result)
41+
else:
42+
result.typ = makeTypeDesc(c, typExpr.typ)
4043

4144
type
4245
SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn

tests/array/tidx_lit_err2.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
discard """
22
errormsg: "expected ordinal value for array index, got '\"string\"'"
3-
line: 5
3+
line: 6
4+
column: 10
45
"""
56
let x = ["string": 0, "index": 1]

0 commit comments

Comments
 (0)