fix #18823 Passing Natural to bitops.BitsRange[T] parameter in generi… (#20683)

* fix #18823 Passing Natural to bitops.BitsRange[T] parameter in generic proc is compile error

(cherry picked from commit 37d8f32ae9)
This commit is contained in:
Bung
2023-08-08 16:06:47 +08:00
committed by narimiran
parent a7394440b9
commit c1745b5924
4 changed files with 23 additions and 10 deletions

View File

@@ -2023,10 +2023,12 @@ proc skipColon*(n: PNode): PNode =
result = n[1]
proc findUnresolvedStatic*(n: PNode): PNode =
# n.typ == nil: see issue #14802
if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
return n
if n.typ != nil and n.typ.kind == tyTypeDesc:
let t = skipTypes(n.typ, {tyTypeDesc})
if t.kind == tyGenericParam and t.len == 0:
return n
for son in n:
let n = son.findUnresolvedStatic
if n != nil: return n

View File

@@ -89,7 +89,7 @@ type
proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
proc replaceTypeVarsN*(cl: var TReplTypeVars, n: PNode; start=0): PNode
proc replaceTypeVarsN*(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode
proc initLayeredTypeMap*(pt: TIdTable): LayeredIdTable =
result = LayeredIdTable()
@@ -213,7 +213,7 @@ proc hasValuelessStatics(n: PNode): bool =
return true
false
proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode =
if n == nil: return
result = copyNode(n)
if n.typ != nil:
@@ -255,8 +255,8 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
when false:
n = reResolveCallsWithTypedescParams(cl, n)
result = if cl.allowMetaTypes: n
else: cl.c.semExpr(cl.c, n)
if not cl.allowMetaTypes:
else: cl.c.semExpr(cl.c, n, {}, expectedType)
if not cl.allowMetaTypes and expectedType != nil:
assert result.kind notin nkCallKinds
else:
if n.len > 0:
@@ -692,12 +692,13 @@ proc initTypeVars*(p: PContext, typeMap: LayeredIdTable, info: TLineInfo;
result.owner = owner
proc replaceTypesInBody*(p: PContext, pt: TIdTable, n: PNode;
owner: PSym, allowMetaTypes = false): PNode =
owner: PSym, allowMetaTypes = false,
fromStaticExpr = false, expectedType: PType = nil): PNode =
var typeMap = initLayeredTypeMap(pt)
var cl = initTypeVars(p, typeMap, n.info, owner)
cl.allowMetaTypes = allowMetaTypes
pushInfoContext(p.config, n.info)
result = replaceTypeVarsN(cl, n)
result = replaceTypeVarsN(cl, n, expectedType = expectedType)
popInfoContext(p.config)
when false:

View File

@@ -810,7 +810,8 @@ proc maybeSkipDistinct(m: TCandidate; t: PType, callee: PSym): PType =
result = t
proc tryResolvingStaticExpr(c: var TCandidate, n: PNode,
allowUnresolved = false): PNode =
allowUnresolved = false,
expectedType: PType = nil): PNode =
# Consider this example:
# type Value[N: static[int]] = object
# proc foo[N](a: Value[N], r: range[0..(N-1)])
@@ -1167,9 +1168,12 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
if result notin {isNone, isGeneric}:
# resolve any late-bound static expressions
# that may appear in the range:
let expectedType = base(f)
for i in 0..1:
if f.n[i].kind == nkStaticExpr:
f.n[i] = tryResolvingStaticExpr(c, f.n[i])
let r = tryResolvingStaticExpr(c, f.n[i], expectedType = expectedType)
if r != nil:
f.n[i] = r
result = typeRangeRel(f, a)
else:
let f = skipTypes(f, {tyRange})

View File

@@ -0,0 +1,6 @@
type BitsRange[T] = range[0..sizeof(T)*8-1]
proc bar[T](a: T; b: BitsRange[T]) =
discard
bar(1, 2.Natural)