mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
* fix #15836 proc arg return type auto unexpectly match proc with concrete type * fix #16244 * add test case for #12869
This commit is contained in:
@@ -2047,6 +2047,9 @@ template detailedInfo*(sym: PSym): string =
|
||||
proc isInlineIterator*(typ: PType): bool {.inline.} =
|
||||
typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure
|
||||
|
||||
proc isIterator*(typ: PType): bool {.inline.} =
|
||||
typ.kind == tyProc and tfIterator in typ.flags
|
||||
|
||||
proc isClosureIterator*(typ: PType): bool {.inline.} =
|
||||
typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@ proc runAllExamples(d: PDoc) =
|
||||
|
||||
proc quoted(a: string): string = result.addQuoted(a)
|
||||
|
||||
proc toInstantiationInfo(conf: ConfigRef, info: TLineInfo): auto =
|
||||
proc toInstantiationInfo(conf: ConfigRef, info: TLineInfo): (string, int, int) =
|
||||
# xxx expose in compiler/lineinfos.nim
|
||||
(conf.toMsgFilename(info), info.line.int, info.col.int + ColOffset)
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ type SpellCandidate = object
|
||||
msg: string
|
||||
sym: PSym
|
||||
|
||||
template toOrderTup(a: SpellCandidate): auto =
|
||||
template toOrderTup(a: SpellCandidate): (int, int, string) =
|
||||
# `dist` is first, to favor nearby matches
|
||||
# `depth` is next, to favor nearby enclosing scopes among ties
|
||||
# `sym.name.s` is last, to make the list ordered and deterministic among ties
|
||||
|
||||
@@ -81,7 +81,7 @@ template semIdeForTemplateOrGeneric(c: PContext; n: PNode;
|
||||
proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
|
||||
let x = arg.skipConv
|
||||
if (x.kind == nkCurly and formal.kind == tySet and formal.base.kind != tyGenericParam) or
|
||||
(x.kind in {nkPar, nkTupleConstr}) and formal.kind notin {tyUntyped, tyBuiltInTypeClass}:
|
||||
(x.kind in {nkPar, nkTupleConstr}) and formal.kind notin {tyUntyped, tyBuiltInTypeClass, tyAnything}:
|
||||
changeType(c, x, formal, check=true)
|
||||
result = arg
|
||||
result = skipHiddenSubConv(result, c.graph, c.idgen)
|
||||
@@ -439,7 +439,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
||||
# does not mean we expect a tyTypeDesc.
|
||||
retType = retType[0]
|
||||
case retType.kind
|
||||
of tyUntyped:
|
||||
of tyUntyped, tyAnything:
|
||||
# Not expecting a type here allows templates like in ``tmodulealias.in``.
|
||||
result = semExpr(c, result, flags, expectedType)
|
||||
of tyTyped:
|
||||
|
||||
@@ -1843,6 +1843,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||
var rhsTyp = rhs.typ
|
||||
if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass:
|
||||
rhsTyp = rhsTyp.lastSon
|
||||
if lhs.sym.typ.kind == tyAnything:
|
||||
rhsTyp = rhsTyp.skipIntLit(c.idgen)
|
||||
if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
|
||||
internalAssert c.config, c.p.resultSym != nil
|
||||
# Make sure the type is valid for the result variable
|
||||
@@ -1916,8 +1918,8 @@ proc semProcBody(c: PContext, n: PNode; expectedType: PType = nil): PNode =
|
||||
else:
|
||||
localError(c.config, c.p.resultSym.info, errCannotInferReturnType %
|
||||
c.p.owner.name.s)
|
||||
if isInlineIterator(c.p.owner.typ) and c.p.owner.typ[0] != nil and
|
||||
c.p.owner.typ[0].kind == tyUntyped:
|
||||
if isIterator(c.p.owner.typ) and c.p.owner.typ[0] != nil and
|
||||
c.p.owner.typ[0].kind == tyAnything:
|
||||
localError(c.config, c.p.owner.info, errCannotInferReturnType %
|
||||
c.p.owner.name.s)
|
||||
closeScope(c)
|
||||
|
||||
@@ -2179,8 +2179,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
if hasProto: localError(c.config, n.info, errImplOfXexpected % proto.name.s)
|
||||
if {sfImportc, sfBorrow, sfError} * s.flags == {} and s.magic == mNone:
|
||||
# this is a forward declaration and we're building the prototype
|
||||
if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyUntyped:
|
||||
# `auto` is represented as `tyUntyped` at this point in compilation.
|
||||
if s.kind in {skProc, skFunc} and s.typ[0] != nil and s.typ[0].kind == tyAnything:
|
||||
localError(c.config, n[paramsPos][0].info, "return type 'auto' cannot be used in forward declarations")
|
||||
|
||||
incl(s.flags, sfForward)
|
||||
|
||||
@@ -1405,9 +1405,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
||||
"' is only valid for macros and templates")
|
||||
# 'auto' as a return type does not imply a generic:
|
||||
elif r.kind == tyAnything:
|
||||
# 'p(): auto' and 'p(): untyped' are equivalent, but the rest of the
|
||||
# compiler is hardly aware of 'auto':
|
||||
r = newTypeS(tyUntyped, c)
|
||||
discard
|
||||
elif r.kind == tyStatic:
|
||||
# type allowed should forbid this type
|
||||
discard
|
||||
|
||||
14
tests/misc/t12869.nim
Normal file
14
tests/misc/t12869.nim
Normal file
@@ -0,0 +1,14 @@
|
||||
discard """
|
||||
errormsg: "type mismatch: got <bool> but expected 'int'"
|
||||
line: 12
|
||||
"""
|
||||
|
||||
import sugar
|
||||
from algorithm import sorted, SortOrder
|
||||
|
||||
let a = 5
|
||||
|
||||
proc sorted*[T](a: openArray[T], key: proc(v: T): int, order = SortOrder.Ascending): seq[T] =
|
||||
sorted(a, (x, y) => key(x) < key(y), order)
|
||||
|
||||
echo sorted(@[9, 1, 8, 2, 6, 4, 5, 0], (x) => (a - x).abs)
|
||||
9
tests/misc/t16244.nim
Normal file
9
tests/misc/t16244.nim
Normal file
@@ -0,0 +1,9 @@
|
||||
discard """
|
||||
errormsg: "type mismatch: got <int, float64>"
|
||||
line: 9
|
||||
"""
|
||||
|
||||
proc g(): auto = 1
|
||||
proc h(): auto = 1.0
|
||||
|
||||
var a = g() + h()
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
cmd: "nim check $file"
|
||||
cmd: "nim check --hints:off $file"
|
||||
errormsg: ""
|
||||
nimout: '''
|
||||
tillegalreturntype.nim(11, 11) Error: return type 'typed' is only valid for macros and templates
|
||||
|
||||
11
tests/types/t15836.nim
Normal file
11
tests/types/t15836.nim
Normal file
@@ -0,0 +1,11 @@
|
||||
discard """
|
||||
errormsg: "type mismatch: got <string> but expected 'int'"
|
||||
line: 11
|
||||
"""
|
||||
|
||||
proc takesProc[T](x: T, f: proc(x: T): int) =
|
||||
echo f(x) + 2
|
||||
|
||||
takesProc(1, proc (a: int): int = 2) # ok, prints 4
|
||||
takesProc(1, proc (a: auto): auto = 2) # ok, prints 4
|
||||
takesProc(1, proc (a: auto): auto = "uh uh") # prints garbage
|
||||
26
tests/types/t15836_2.nim
Normal file
26
tests/types/t15836_2.nim
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
discard """
|
||||
action: "compile"
|
||||
disabled: true
|
||||
"""
|
||||
import std/sugar
|
||||
|
||||
type Tensor[T] = object
|
||||
x: T
|
||||
|
||||
proc numerical_gradient*[T](input: T, f: (proc(x: T): T), h = T(1e-5)): T {.inline.} =
|
||||
result = default(T)
|
||||
|
||||
proc numerical_gradient*[T](input: Tensor[T], f: (proc(x: Tensor[T]): T), h = T(1e-5)): Tensor[T] {.noinit.} =
|
||||
result = default(Tensor[T])
|
||||
|
||||
proc conv2d*[T](input: Tensor[T]): Tensor[T] {.inline.} =
|
||||
result = default(Tensor[T])
|
||||
|
||||
proc sum*[T](arg: Tensor[T]): T = default(T)
|
||||
|
||||
proc sum*[T](arg: Tensor[T], axis: int): Tensor[T] {.noinit.} = default(Tensor[T])
|
||||
|
||||
let dinput = Tensor[int](x: 1)
|
||||
let target_grad_input = dinput.numerical_gradient(
|
||||
x => conv2d(x).sum())
|
||||
Reference in New Issue
Block a user