* fixes #20645

* better bugfix
This commit is contained in:
Andreas Rumpf 2022-10-24 21:41:29 +02:00 • committed by GitHub
commit 48d41ab375
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 7 deletions

View file

@ -1363,7 +1363,7 @@ proc tryReadingTypeField(c: PContext, n: PNode, i: PIdent, ty: PType): PNode =
else:
result = tryReadingGenericParam(c, n, i, ty)
proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
proc builtinFieldAccess(c: PContext; n: PNode; flags: var TExprFlags): PNode =
## returns nil if it's not a built-in field access
checkSonsLen(n, 2, c.config)
# tests/bind/tbindoverload.nim wants an early exit here, but seems to
@ -1401,12 +1401,15 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# field access and we leave the compiler to compile a normal call:
if getCurrOwner(c).kind != skMacro:
n.typ = makeTypeFromExpr(c, n.copyTree)
flags.incl efCannotBeDotCall
return n
else:
return nil
else:
flags.incl efCannotBeDotCall
return tryReadingTypeField(c, n, i, ty.base)
elif isTypeExpr(n.sons[0]):
flags.incl efCannotBeDotCall
return tryReadingTypeField(c, n, i, ty)
elif ty.kind == tyError:
# a type error doesn't have any builtin fields
@ -1458,6 +1461,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
if result == nil:
let t = n[0].typ.skipTypes(tyDotOpTransparent)
result = tryReadingGenericParam(c, n, i, t)
flags.incl efCannotBeDotCall
proc dotTransformation(c: PContext, n: PNode): PNode =
if isSymChoice(n[1]):
@ -1474,9 +1478,11 @@ proc dotTransformation(c: PContext, n: PNode): PNode =
proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# this is difficult, because the '.' is used in many different contexts
# in Nim. We first allow types in the semantic checking.
result = builtinFieldAccess(c, n, flags - {efIsDotCall})
if result == nil or ((result.typ == nil or result.typ.skipTypes(abstractInst).kind != tyProc) and
efIsDotCall in flags and callOperator notin c.features):
var f = flags - {efIsDotCall}
result = builtinFieldAccess(c, n, f)
if result == nil or ((result.typ == nil or result.typ.skipTypes(abstractInst).kind != tyProc) and
efIsDotCall in flags and callOperator notin c.features and
efCannotBeDotCall notin f):
result = dotTransformation(c, n)
proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode =
@ -1744,7 +1750,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
# r.f = x
# --> `f=` (r, x)
let nOrig = n.copyTree
a = builtinFieldAccess(c, a, {efLValue})
var flags = {efLValue}
a = builtinFieldAccess(c, a, flags)
if a == nil:
a = propertyWriteAccess(c, n, nOrig, n[0])
if a != nil: return a