* 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

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

View file

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

View file

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