fixed dot operator recursive loop & macro suggest (#16922)

* basic stability improvements; refs nimsuggest
* fixed dot operator recursive loop & macro suggest
* hacky fix for run away dot operator sem check

Committing this mostly to make the issue more clear. Perhaps get better
feedback.

* semExprWithType seems like a better place to check
* fixed error messages const case expressions
* Clean-up test
* stopped the dot operator madness

No longer get infinite recursion when seming broken code with a dot
operator macro like in jsffi.

Co-authored-by: Araq <rumpf_a@web.de>
This commit is contained in:
Saem Ghani 2021-02-15 00:51:05 -08:00 • committed by GitHub
commit 260a5dacb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 51 additions and 24 deletions

View file

@ -66,10 +66,17 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
proc semExprCheck(c: PContext, n: PNode, flags: TExprFlags): PNode =
rejectEmptyNode(n)
result = semExpr(c, n, flags+{efWantValue})
if result.kind == nkEmpty:
let
isEmpty = result.kind == nkEmpty
isTypeError = result.typ != nil and result.typ.kind == tyError
if isEmpty or isTypeError:
# bug #12741, redundant error messages are the lesser evil here:
localError(c.config, n.info, errExprXHasNoType %
renderTree(result, {renderNoComments}))
if isEmpty:
# do not produce another redundant error message:
result = errorNode(c, n)
@ -79,6 +86,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
localError(c.config, n.info, errExprXHasNoType %
renderTree(result, {renderNoComments}))
result.typ = errorType(c)
elif result.typ.kind == tyError:
# associates the type error to the current owner
result.typ = errorType(c)
else:
if result.typ.kind in {tyVar, tyLent}: result = newDeref(result)
@ -887,6 +897,9 @@ proc setGenericParams(c: PContext, n: PNode) =
n[i].typ = semTypeNode(c, n[i], nil)
proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags): PNode =
if efNoSemCheck notin flags and n.typ != nil and n.typ.kind == tyError:
return errorNode(c, n)
result = n
let callee = result[0].sym
case callee.kind
@ -1368,6 +1381,9 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
return tryReadingTypeField(c, n, i, ty.base)
elif isTypeExpr(n.sons[0]):
return tryReadingTypeField(c, n, i, ty)
elif ty.kind == tyError:
# a type error doesn't have any builtin fields
return nil
if ty.kind in tyUserTypeClasses and ty.isResolvedUserTypeClass:
ty = ty.lastSon