Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #15836 proc arg return type auto unexpectly match proc with concr… #21065

Merged
merged 4 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion compiler/docgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion compiler/lookups.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
6 changes: 4 additions & 2 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 1 addition & 2 deletions compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 1 addition & 3 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 14 additions & 0 deletions tests/misc/t12869.nim
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions tests/misc/t16244.nim
Original file line number Diff line number Diff line change
@@ -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()
2 changes: 1 addition & 1 deletion tests/proc/tillegalreturntype.nim
Original file line number Diff line number Diff line change
@@ -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
Expand Down
11 changes: 11 additions & 0 deletions tests/types/t15836.nim
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions tests/types/t15836_2.nim
Original file line number Diff line number Diff line change
@@ -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())