diff options
-rw-r--r-- | compiler/ast.nim | 6 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 13 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 8 | ||||
-rw-r--r-- | tests/generics/t18823.nim | 6 |
4 files changed, 23 insertions, 10 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index aba877187..55ee0e20d 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -2040,10 +2040,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 diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 19aa8be29..dfa1d2902 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -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() @@ -214,7 +214,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: @@ -256,8 +256,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: @@ -694,12 +694,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: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9bf47df70..462f5d0d1 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -821,7 +821,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)]) @@ -1179,9 +1180,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}) diff --git a/tests/generics/t18823.nim b/tests/generics/t18823.nim new file mode 100644 index 000000000..94c79aebe --- /dev/null +++ b/tests/generics/t18823.nim @@ -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) |