diff options
author | Neelesh Chandola <neelesh.chandola@outlook.com> | 2020-05-29 15:18:15 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-29 11:48:15 +0200 |
commit | 4c08e64e9868dabca4a1a82979b74bda5c7d0329 (patch) | |
tree | eb666279521d0934bd35ff5609ee2e5be6f452df | |
parent | 579456d52073229bfe362d3794fae22a479dda38 (diff) | |
download | Nim-4c08e64e9868dabca4a1a82979b74bda5c7d0329.tar.gz |
disallow typedesc in arrays & move existing checks to `types.typeAllowedAux` (#13261)
* disallow typedesc in arrays and move previous checks to types.typeAllowedAux
-rw-r--r-- | compiler/sem.nim | 12 | ||||
-rw-r--r-- | compiler/semstmts.nim | 45 | ||||
-rw-r--r-- | compiler/types.nim | 32 | ||||
-rw-r--r-- | tests/array/t9932.nim | 11 | ||||
-rw-r--r-- | tests/errmsgs/t10489_a.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/t10489_b.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/t12844.nim | 6 | ||||
-rw-r--r-- | tests/errmsgs/t5870.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/t8610.nim | 2 | ||||
-rw-r--r-- | tests/errmsgs/ttypeAllowed.nim | 2 | ||||
-rw-r--r-- | tests/metatype/typedesc_as_value.nim | 2 | ||||
-rw-r--r-- | tests/typerel/typedescs2.nim | 2 |
12 files changed, 70 insertions, 50 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index 62e3ca8db..683c67254 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -233,13 +233,15 @@ proc typeAllowedCheck(conf: ConfigRef; info: TLineInfo; typ: PType; kind: TSymKi flags: TTypeAllowedFlags = {}) = let t = typeAllowed(typ, kind, flags) if t != nil: + var err: string if t == typ: - localError(conf, info, "invalid type: '" & typeToString(typ) & - "' for " & substr($kind, 2).toLowerAscii) + err = "invalid type: '$1' for $2" % [typeToString(typ), toHumanStr(kind)] + if kind in {skVar, skLet, skConst} and taIsTemplateOrMacro in flags: + err &= ". Did you mean to call the $1 with '()'?" % [toHumanStr(typ.owner.kind)] else: - localError(conf, info, "invalid type: '" & typeToString(t) & - "' in this context: '" & typeToString(typ) & - "' for " & substr($kind, 2).toLowerAscii) + err = "invalid type: '$1' in this context: '$2' for $3" % [typeToString(t), + typeToString(typ), toHumanStr(kind)] + localError(conf, info, err) proc paramsTypeCheck(c: PContext, typ: PType) {.inline.} = typeAllowedCheck(c.config, typ.n.info, typ, skProc) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3faa32808..a4b4c9362 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -36,8 +36,6 @@ const errRecursiveDependencyX = "recursive dependency: '$1'" errRecursiveDependencyIteratorX = "recursion is not supported in iterators: '$1'" errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1" - errCannotAssignMacroSymbol = "cannot assign $1 '$2' to '$3'. Did you mean to call the $1 with '()'?" - errInvalidTypeDescAssign = "'typedesc' metatype is not valid here; typed '=' instead of ':'?" proc semDiscard(c: PContext, n: PNode): PNode = result = n @@ -491,19 +489,16 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if a[^2].kind != nkEmpty: typ = semTypeNode(c, a[^2], nil) + var typFlags: TTypeAllowedFlags + var def: PNode = c.graph.emptyNode if a[^1].kind != nkEmpty: def = semExprWithType(c, a[^1], {efAllowDestructor}) - if def.typ.kind == tyProc and def.kind == nkSym: - if def.sym.kind in {skMacro, skTemplate}: - localError(c.config, def.info, errCannotAssignMacroSymbol % [ - if def.sym.kind == skMacro: "macro" else: "template", - def.sym.name.s, a[0].ident.s]) - def.typ = errorType(c) + + if def.kind == nkSym and def.sym.kind in {skTemplate, skMacro}: + typFlags.incl taIsTemplateOrMacro elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: - # prevent the all too common 'var x = int' bug: - localError(c.config, def.info, errInvalidTypeDescAssign) - def.typ = errorType(c) + typFlags.incl taProcContextIsNotMacro if typ != nil: if typ.isMetaType: @@ -534,7 +529,11 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = # this can only happen for errornous var statements: if typ == nil: continue - typeAllowedCheck(c.config, a.info, typ, symkind, if c.matchedConcept != nil: {taConcept} else: {}) + + if c.matchedConcept != nil: + typFlags.incl taConcept + typeAllowedCheck(c.config, a.info, typ, symkind, typFlags) + when false: liftTypeBoundOps(c, typ, a.info) instAllTypeBoundOp(c, a.info) var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink}) @@ -642,18 +641,15 @@ proc semConst(c: PContext, n: PNode): PNode = if a[^2].kind != nkEmpty: typ = semTypeNode(c, a[^2], nil) + var typFlags: TTypeAllowedFlags + # don't evaluate here since the type compatibility check below may add a converter var def = semExprWithType(c, a[^1]) - if def.typ.kind == tyProc and def.kind == nkSym: - if def.sym.kind in {skMacro, skTemplate}: - localError(c.config, def.info, errCannotAssignMacroSymbol % [ - if def.sym.kind == skMacro: "macro" else: "template", - def.sym.name.s, a[0].ident.s]) - def.typ = errorType(c) + + if def.kind == nkSym and def.sym.kind in {skTemplate, skMacro}: + typFlags.incl taIsTemplateOrMacro elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: - # prevent the all too common 'const x = int' bug: - localError(c.config, def.info, errInvalidTypeDescAssign) - def.typ = errorType(c) + typFlags.incl taProcContextIsNotMacro # check type compatibility between def.typ and typ: if typ != nil: @@ -670,9 +666,10 @@ proc semConst(c: PContext, n: PNode): PNode = if def == nil: localError(c.config, a[^1].info, errConstExprExpected) continue - if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit: - localError(c.config, a.info, "invalid type for const: " & typeToString(typ)) - continue + if def.kind != nkNilLit: + if c.matchedConcept != nil: + typFlags.incl taConcept + typeAllowedCheck(c.config, a.info, typ, skConst, typFlags) var b: PNode if a.kind == nkVarTuple: diff --git a/compiler/types.nim b/compiler/types.nim index 709e5bb2e..e1b283f87 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1246,6 +1246,8 @@ type taConcept, taIsOpenArray, taNoUntyped + taIsTemplateOrMacro + taProcContextIsNotMacro TTypeAllowedFlags* = set[TTypeAllowedFlag] @@ -1307,18 +1309,24 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, if kind notin {skParam, skResult}: result = t else: result = typeAllowedAux(marker, t2, kind, flags) of tyProc: - if isInlineIterator(typ) and kind in {skVar, skLet, skConst, skParam, skResult}: - # only closure iterators my be assigned to anything. + if kind in {skVar, skLet, skConst} and taIsTemplateOrMacro in flags: result = t - let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags - for i in 1..<t.len: - if result != nil: break - result = typeAllowedAux(marker, t[i], skParam, f-{taIsOpenArray}) - if result.isNil and t[0] != nil: - result = typeAllowedAux(marker, t[0], skResult, flags) + else: + if isInlineIterator(typ) and kind in {skVar, skLet, skConst, skParam, skResult}: + # only closure iterators may be assigned to anything. + result = t + let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags + for i in 1..<t.len: + if result != nil: break + result = typeAllowedAux(marker, t[i], skParam, f-{taIsOpenArray}) + if result.isNil and t[0] != nil: + result = typeAllowedAux(marker, t[0], skResult, flags) of tyTypeDesc: - # XXX: This is still a horrible idea... - result = nil + if kind in {skVar, skLet, skConst} and taProcContextIsNotMacro in flags: + result = t + else: + # XXX: This is still a horrible idea... + result = nil of tyUntyped, tyTyped: if kind notin {skParam, skResult} or taNoUntyped in flags: result = t of tyStatic: @@ -1363,7 +1371,9 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, elif kind in {skVar, skLet}: result = t[0] of tyArray: - if t[1].kind != tyEmpty: + if t[1].kind == tyTypeDesc: + result = t[1] + elif t[1].kind != tyEmpty: result = typeAllowedAux(marker, t[1], kind, flags) elif kind in {skVar, skLet}: result = t[1] diff --git a/tests/array/t9932.nim b/tests/array/t9932.nim new file mode 100644 index 000000000..1e09c487b --- /dev/null +++ b/tests/array/t9932.nim @@ -0,0 +1,11 @@ +discard """ +cmd: "nim check $file" +errormsg: "invalid type: 'type int' in this context: 'array[0..0, type int]' for var" +nimout: ''' +t9932.nim(10, 5) Error: invalid type: 'type' in this context: 'array[0..0, type]' for var +t9932.nim(11, 5) Error: invalid type: 'type int' in this context: 'array[0..0, type int]' for var +''' +""" + +var y: array[1,type] +var x = [int] diff --git a/tests/errmsgs/t10489_a.nim b/tests/errmsgs/t10489_a.nim index 86659f7ac..71a6cc3c4 100644 --- a/tests/errmsgs/t10489_a.nim +++ b/tests/errmsgs/t10489_a.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "cannot assign macro 'm' to 'x1'. Did you mean to call the macro with '()'?" +errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe, locks: 0.}' for let. Did you mean to call the macro with '()'?" line: 9 """ diff --git a/tests/errmsgs/t10489_b.nim b/tests/errmsgs/t10489_b.nim index 1182b4512..4b0b876e5 100644 --- a/tests/errmsgs/t10489_b.nim +++ b/tests/errmsgs/t10489_b.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "cannot assign macro 'm' to 'x2'. Did you mean to call the macro with '()'?" +errormsg: "invalid type: 'macro (body: untyped): untyped{.noSideEffect, gcsafe, locks: 0.}' for const. Did you mean to call the macro with '()'?" line: 9 """ diff --git a/tests/errmsgs/t12844.nim b/tests/errmsgs/t12844.nim index 999d26255..a274b72b4 100644 --- a/tests/errmsgs/t12844.nim +++ b/tests/errmsgs/t12844.nim @@ -1,9 +1,9 @@ discard """ cmd: "nim check $file" -errormsg: "cannot assign template 'z' to 'y'. Did you mean to call the template with '()'?" +errormsg: "invalid type: 'template (args: varargs[string])' for var. Did you mean to call the template with '()'?" nimout: ''' -t12844.nim(11, 11) Error: cannot assign template 'z' to 'x'. Did you mean to call the template with '()'? -t12844.nim(12, 9) Error: cannot assign template 'z' to 'y'. Did you mean to call the template with '()'?''' +t12844.nim(11, 7) Error: invalid type: 'template (args: varargs[string])' for const. Did you mean to call the template with '()'? +t12844.nim(12, 5) Error: invalid type: 'template (args: varargs[string])' for var. Did you mean to call the template with '()'?''' """ template z*(args: varargs[string, `$`]) = diff --git a/tests/errmsgs/t5870.nim b/tests/errmsgs/t5870.nim index bcbc9cca9..96966bcd7 100644 --- a/tests/errmsgs/t5870.nim +++ b/tests/errmsgs/t5870.nim @@ -1,5 +1,5 @@ discard """ -errormsg: "invalid type for const: seq[SomeRefObj]" +errormsg: "invalid type: 'SomeRefObj' in this context: 'seq[SomeRefObj]' for const" line: 14 """ diff --git a/tests/errmsgs/t8610.nim b/tests/errmsgs/t8610.nim index dd1a3ed29..6a253f7ab 100644 --- a/tests/errmsgs/t8610.nim +++ b/tests/errmsgs/t8610.nim @@ -1,5 +1,5 @@ discard """ - errmsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?" + errmsg: "invalid type: 'type int' for const" """ ## issue #8610 const Foo = int diff --git a/tests/errmsgs/ttypeAllowed.nim b/tests/errmsgs/ttypeAllowed.nim index a5b335faa..9efbc6ead 100644 --- a/tests/errmsgs/ttypeAllowed.nim +++ b/tests/errmsgs/ttypeAllowed.nim @@ -3,7 +3,7 @@ cmd: "nim check $file" errmsg: "" nimout: ''' ttypeAllowed.nim(13, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for let -ttypeAllowed.nim(17, 7) Error: invalid type for const: iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.} +ttypeAllowed.nim(17, 7) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for const ttypeAllowed.nim(21, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for var ttypeAllowed.nim(26, 10) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for result ''' diff --git a/tests/metatype/typedesc_as_value.nim b/tests/metatype/typedesc_as_value.nim index f6e526987..69eaf8a5c 100644 --- a/tests/metatype/typedesc_as_value.nim +++ b/tests/metatype/typedesc_as_value.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?" + errormsg: "invalid type: 'type int' for var" """ diff --git a/tests/typerel/typedescs2.nim b/tests/typerel/typedescs2.nim index 43cd48ca6..0b0b12986 100644 --- a/tests/typerel/typedescs2.nim +++ b/tests/typerel/typedescs2.nim @@ -1,5 +1,5 @@ discard """ - errormsg: "'typedesc' metatype is not valid here; typed '=' instead of ':'?" + errormsg: "invalid type: 'type Table' for const" file: "typedescs2.nim" line: 16 """ |