* fixes #20645

* better bugfix
This commit is contained in:
Andreas Rumpf
2022-10-24 21:41:29 +02:00
committed by GitHub
parent ea0e45e62f
commit 48d41ab375
3 changed files with 24 additions and 7 deletions

View File

@@ -69,7 +69,7 @@ type
efWantStmt, efAllowStmt, efDetermineType, efExplain,
efWantValue, efOperand, efNoSemCheck,
efNoEvaluateGeneric, efInCall, efFromHlo, efNoSem2Check,
efNoUndeclared, efIsDotCall
efNoUndeclared, efIsDotCall, efCannotBeDotCall
# Use this if undeclared identifiers should not raise an error during
# overload resolution.

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

View File

@@ -1,5 +1,6 @@
discard """
output: '''true'''
output: '''true
5.0'''
"""
#bug #592
@@ -89,3 +90,12 @@ proc does_fail(): Foo =
result.bar(5, a)
doAssert does_fail().bar == 0
# bug #20645
type Zzz[Gen] = object
proc testZ(z: Zzz) =
echo z.Gen(5)
testZ(Zzz[float]())