diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 0fce7b417..b34dc36e3 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -10,7 +10,7 @@ # this module does the semantic checking of type declarations # included from sem.nim -import math +import std/math const errStringOrIdentNodeExpected = "string or ident node expected" @@ -1171,6 +1171,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, else: discard proc semParamType(c: PContext, n: PNode, constraint: var PNode): PType = + ## Semchecks the type of parameters. if n.kind == nkCurlyExpr: result = semTypeNode(c, n[0], nil) constraint = semNodeKindConstraints(n, c.config, 1) @@ -1226,10 +1227,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if hasType: typ = semParamType(c, a[^2], constraint) # TODO: Disallow typed/untyped in procs in the compiler/stdlib - if kind == skProc and (typ.kind == tyTyped or typ.kind == tyUntyped): + if kind in {skProc, skFunc} and (typ.kind == tyTyped or typ.kind == tyUntyped): if not isMagic(getCurrOwner(c)): localError(c.config, a[^2].info, "'" & typ.sym.name.s & "' is only allowed in templates and macros or magic procs") + if hasDefault: def = a[^1] block determineType: diff --git a/compiler/typeallowed.nim b/compiler/typeallowed.nim index db3735359..9075d9e38 100644 --- a/compiler/typeallowed.nim +++ b/compiler/typeallowed.nim @@ -57,7 +57,8 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, of tyVar, tyLent: if kind in {skProc, skFunc, skConst} and (views notin c.features): result = t - elif t.kind == tyLent and kind != skResult and (views notin c.features): + elif t.kind == tyLent and ((kind != skResult and views notin c.features) or + kind == skParam): # lent can't be used as parameters. result = t else: var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc, tySink}) diff --git a/tests/lent/t16898.nim b/tests/lent/t16898.nim new file mode 100644 index 000000000..ea7c934ef --- /dev/null +++ b/tests/lent/t16898.nim @@ -0,0 +1,31 @@ +discard """ + errormsg: "invalid type: 'lent QuadraticExt' in this context: 'proc (r: var QuadraticExt, a: lent QuadraticExt, b: lent QuadraticExt){.noSideEffect, gcsafe, locks: 0.}' for proc" +""" + +# bug #16898 +type + Fp[N: static int, T] = object + big: array[N, T] + +type + QuadraticExt* = concept x + ## Quadratic Extension concept (like complex) + type BaseField = auto + x.c0 is BaseField + x.c1 is BaseField + +{.experimental:"views".} + +func prod(r: var QuadraticExt, a, b: lent QuadraticExt) = + discard + +type + Fp2[N: static int, T] = object + c0, c1: Fp[N, T] + +# This should be passed by reference, +# but concepts do not respect the 24 bytes rule +# or `byref` pragma. +var r, a, b: Fp2[6, uint64] + +prod(r, a, b) diff --git a/tests/lent/t17621.nim b/tests/lent/t17621.nim new file mode 100644 index 000000000..e324a963e --- /dev/null +++ b/tests/lent/t17621.nim @@ -0,0 +1,15 @@ +discard """ + errormsg: "invalid type: 'lent Test' in this context: 'proc (self: lent Test)' for proc" +""" + +# bug #17621 +{.experimental: "views".} + +type Test = ref object + foo: int + +proc modify(self: lent Test) = + self.foo += 1 + +let test = Test(foo: 12) +modify(test)