mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-21 06:45:27 +00:00
Let inferGenericTypes continue if a param is already bound (#22384)
* Play with typeRel * Temp solution: Fixup call's param types * Test result type with two generic params * Asserts * Tiny cleanup * Skip sink * Ignore proc * Use changeType * Remove conversion * Remove last bits of conversion * Flag --------- Co-authored-by: SirOlaf <>
This commit is contained in:
@@ -564,7 +564,7 @@ proc getCallLineInfo(n: PNode): TLineInfo =
|
||||
|
||||
proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) =
|
||||
## Helper proc to inherit bound generic parameters from expectedType into x.
|
||||
## Does nothing if 'inferGenericTypes' isn't in c.features
|
||||
## Does nothing if 'inferGenericTypes' isn't in c.features.
|
||||
if inferGenericTypes notin c.features: return
|
||||
if expectedType == nil or x.callee[0] == nil: return # required for inference
|
||||
|
||||
@@ -578,7 +578,7 @@ proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) =
|
||||
## skips types and puts the skipped version on stack
|
||||
# It might make sense to skip here one by one. It's not part of the main
|
||||
# type reduction because the right side normally won't be skipped
|
||||
const toSkip = { tyVar, tyLent, tyStatic, tyCompositeTypeClass }
|
||||
const toSkip = { tyVar, tyLent, tyStatic, tyCompositeTypeClass, tySink }
|
||||
let
|
||||
x = a.skipTypes(toSkip)
|
||||
y = if a.kind notin toSkip: b
|
||||
@@ -603,7 +603,9 @@ proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) =
|
||||
if t[i] == nil or u[i] == nil: return
|
||||
stackPut(t[i], u[i])
|
||||
of tyGenericParam:
|
||||
if x.bindings.idTableGet(t) != nil: return
|
||||
let prebound = x.bindings.idTableGet(t).PType
|
||||
if prebound != nil:
|
||||
continue # Skip param, already bound
|
||||
|
||||
# fully reduced generic param, bind it
|
||||
if t notin flatUnbound:
|
||||
@@ -611,6 +613,7 @@ proc inheritBindings(c: PContext, x: var TCandidate, expectedType: PType) =
|
||||
flatBound.add(u)
|
||||
else:
|
||||
discard
|
||||
# update bindings
|
||||
for i in 0 ..< flatUnbound.len():
|
||||
x.bindings.idTablePut(flatUnbound[i], flatBound[i])
|
||||
|
||||
|
||||
@@ -136,4 +136,27 @@ block:
|
||||
x: Table[int, float]
|
||||
|
||||
let a = Foo(x: initTable())
|
||||
doAssert a.x is Table[int, float]
|
||||
doAssert a.x is Table[int, float]
|
||||
|
||||
# partial binding
|
||||
block:
|
||||
type
|
||||
ResultKind = enum
|
||||
Ok, Error
|
||||
|
||||
Result[T, E] = object
|
||||
case kind: ResultKind
|
||||
of Ok:
|
||||
okVal: T
|
||||
of Error:
|
||||
errVal: E
|
||||
|
||||
proc err[T, E](myParam: E): Result[T, E] =
|
||||
Result[T, E](kind : Error, errVal : myParam)
|
||||
|
||||
proc doStuff(): Result[int, string] =
|
||||
err("Error")
|
||||
|
||||
let res = doStuff()
|
||||
doAssert res.kind == Error
|
||||
doAssert res.errVal == "Error"
|
||||
Reference in New Issue
Block a user