parent
87568830ab
commit
c50a04adc5
3 changed files with 82 additions and 12 deletions
|
|
@ -1835,7 +1835,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
if destIsGeneric:
|
if destIsGeneric:
|
||||||
dest = generateTypeInstance(c, m.bindings, arg, dest)
|
dest = generateTypeInstance(c, m.bindings, arg, dest)
|
||||||
let fdest = typeRel(m, f, dest)
|
let fdest = typeRel(m, f, dest)
|
||||||
if fdest in {isEqual, isGeneric}:
|
if fdest in {isEqual, isGeneric} and not (dest.kind == tyLent and f.kind == tyVar):
|
||||||
markUsed(c.config, arg.info, c.converters[i], c.graph.usageSym)
|
markUsed(c.config, arg.info, c.converters[i], c.graph.usageSym)
|
||||||
var s = newSymNode(c.converters[i])
|
var s = newSymNode(c.converters[i])
|
||||||
s.typ = c.converters[i].typ
|
s.typ = c.converters[i].typ
|
||||||
|
|
@ -2231,8 +2231,15 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
else:
|
else:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
return
|
return
|
||||||
|
|
||||||
if formal.typ.kind == tyVar:
|
if formal.typ.kind == tyVar:
|
||||||
if not n.isLValue:
|
let arg_converter = if arg.kind == nkHiddenDeref: arg[0] else: arg
|
||||||
|
if arg_converter.kind == nkHiddenCallConv:
|
||||||
|
if arg_converter.typ.kind != tyVar:
|
||||||
|
m.state = csNoMatch
|
||||||
|
m.mutabilityProblem = uint8(f-1)
|
||||||
|
return
|
||||||
|
elif not n.isLValue:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
m.mutabilityProblem = uint8(f-1)
|
m.mutabilityProblem = uint8(f-1)
|
||||||
return
|
return
|
||||||
|
|
@ -2243,6 +2250,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
else: 0
|
else: 0
|
||||||
# iterates over the actual given arguments
|
# iterates over the actual given arguments
|
||||||
a = 1
|
a = 1
|
||||||
|
arg: PNode # current prepared argument
|
||||||
|
|
||||||
m.state = csMatch # until proven otherwise
|
m.state = csMatch # until proven otherwise
|
||||||
m.call = newNodeI(n.kind, n.info)
|
m.call = newNodeI(n.kind, n.info)
|
||||||
|
|
@ -2297,7 +2305,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
m.typedescMatched = false
|
m.typedescMatched = false
|
||||||
n.sons[a].sons[1] = prepareOperand(c, formal.typ, n.sons[a].sons[1])
|
n.sons[a].sons[1] = prepareOperand(c, formal.typ, n.sons[a].sons[1])
|
||||||
n.sons[a].typ = n.sons[a].sons[1].typ
|
n.sons[a].typ = n.sons[a].sons[1].typ
|
||||||
var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
||||||
n.sons[a].sons[1], n.sons[a].sons[1])
|
n.sons[a].sons[1], n.sons[a].sons[1])
|
||||||
if arg == nil:
|
if arg == nil:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
|
@ -2334,7 +2342,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
m.typedescMatched = false
|
m.typedescMatched = false
|
||||||
incl(marker, formal.position)
|
incl(marker, formal.position)
|
||||||
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
||||||
var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
||||||
n.sons[a], nOrig.sons[a])
|
n.sons[a], nOrig.sons[a])
|
||||||
if arg != nil and m.baseTypeMatch and container != nil:
|
if arg != nil and m.baseTypeMatch and container != nil:
|
||||||
addSon(container, arg)
|
addSon(container, arg)
|
||||||
|
|
@ -2368,7 +2376,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
m.baseTypeMatch = false
|
m.baseTypeMatch = false
|
||||||
m.typedescMatched = false
|
m.typedescMatched = false
|
||||||
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
||||||
var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
||||||
n.sons[a], nOrig.sons[a])
|
n.sons[a], nOrig.sons[a])
|
||||||
if arg == nil:
|
if arg == nil:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
|
|
||||||
|
|
@ -26,3 +26,19 @@ block:
|
||||||
var x = "101"
|
var x = "101"
|
||||||
var y: int = x # instantiate withVar
|
var y: int = x # instantiate withVar
|
||||||
doAssert(y == ord('0'))
|
doAssert(y == ord('0'))
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# bug #3503
|
||||||
|
type Foo = object
|
||||||
|
r: float
|
||||||
|
|
||||||
|
converter toFoo(r: float): Foo =
|
||||||
|
result.r = r
|
||||||
|
|
||||||
|
proc `+=`*(x: var Foo, r: float) =
|
||||||
|
x.r += r
|
||||||
|
|
||||||
|
var a: Foo
|
||||||
|
a.r += 3.0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,7 @@
|
||||||
discard """
|
discard """
|
||||||
file: "tconverter_unique_ptr.nim"
|
file: "tconverter_unique_ptr.nim"
|
||||||
targets: "c cpp"
|
targets: "c cpp"
|
||||||
output: '''5
|
output: ""
|
||||||
2.0 5
|
|
||||||
'''
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
## Bugs 9698 and 9699
|
## Bugs 9698 and 9699
|
||||||
|
|
@ -22,6 +20,8 @@ type
|
||||||
data: ptr UncheckedArray[float]
|
data: ptr UncheckedArray[float]
|
||||||
|
|
||||||
proc `$`(x: MyLen): string {.borrow.}
|
proc `$`(x: MyLen): string {.borrow.}
|
||||||
|
proc `==`(x1, x2: MyLen): bool {.borrow.}
|
||||||
|
|
||||||
|
|
||||||
proc `=destroy`*(m: var MySeq) {.inline.} =
|
proc `=destroy`*(m: var MySeq) {.inline.} =
|
||||||
if m.data != nil:
|
if m.data != nil:
|
||||||
|
|
@ -50,10 +50,12 @@ proc len*(m: MySeq): MyLen {.inline.} = m.len
|
||||||
|
|
||||||
proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
|
proc lenx*(m: var MySeq): MyLen {.inline.} = m.len
|
||||||
|
|
||||||
|
|
||||||
proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
|
proc `[]`*(m: MySeq; i: MyLen): float {.inline.} =
|
||||||
m.data[i.int]
|
m.data[i.int]
|
||||||
|
|
||||||
|
proc `[]`*(m: var MySeq; i: MyLen): var float {.inline.} =
|
||||||
|
m.data[i.int]
|
||||||
|
|
||||||
proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
|
proc `[]=`*(m: var MySeq; i: MyLen, val: float) {.inline.} =
|
||||||
m.data[i.int] = val
|
m.data[i.int] = val
|
||||||
|
|
||||||
|
|
@ -97,11 +99,55 @@ proc newUniquePtr*[T](val: sink T): UniquePtr[T] =
|
||||||
converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
|
converter convertPtrToObj*[T](p: UniquePtr[T]): var T =
|
||||||
result = p.val[]
|
result = p.val[]
|
||||||
|
|
||||||
|
|
||||||
var pu = newUniquePtr(newMySeq(5, 1.0))
|
var pu = newUniquePtr(newMySeq(5, 1.0))
|
||||||
echo pu.len
|
let pu2 = newUniquePtr(newMySeq(5, 1.0))
|
||||||
|
doAssert: pu.len == 5
|
||||||
|
doAssert: pu2.len == 5
|
||||||
|
doAssert: pu.lenx == 5
|
||||||
|
doAssert: pu2.lenx == 5
|
||||||
|
|
||||||
pu[0] = 2.0
|
pu[0] = 2.0
|
||||||
echo pu[0], " ", pu.lenx
|
pu2[0] = 2.0
|
||||||
|
doAssert pu[0] == 2.0
|
||||||
|
doAssert: pu2[0] == 2.0
|
||||||
|
|
||||||
|
##-----------------------------------------------------------------------------------------
|
||||||
|
## Bugs #9735 and #9736
|
||||||
|
type
|
||||||
|
ConstPtr*[T] = object
|
||||||
|
## This pointer makes it impossible to change underlying value
|
||||||
|
## as it returns only `lent T`
|
||||||
|
val: ptr T
|
||||||
|
|
||||||
|
proc `=destroy`*[T](p: var ConstPtr[T]) =
|
||||||
|
if p.val != nil:
|
||||||
|
`=destroy`(p.val[])
|
||||||
|
dealloc(p.val)
|
||||||
|
p.val = nil
|
||||||
|
|
||||||
|
proc `=`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.error.}
|
||||||
|
|
||||||
|
proc `=sink`*[T](dest: var ConstPtr[T], src: ConstPtr[T]) {.inline.} =
|
||||||
|
if dest.val != nil and dest.val != src.val:
|
||||||
|
`=destroy`(dest)
|
||||||
|
dest.val = src.val
|
||||||
|
|
||||||
|
proc newConstPtr*[T](val: sink T): ConstPtr[T] =
|
||||||
|
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
|
||||||
|
reset(result.val[])
|
||||||
|
result.val[] = val
|
||||||
|
|
||||||
|
converter convertConstPtrToObj*[T](p: ConstPtr[T]): lent T =
|
||||||
|
result = p.val[]
|
||||||
|
|
||||||
|
var pc = newConstPtr(newMySeq(3, 1.0))
|
||||||
|
let pc2 = newConstPtr(newMySeq(3, 1.0))
|
||||||
|
doAssert: pc.len == 3
|
||||||
|
doAssert: pc.len == 3
|
||||||
|
doAssert: compiles(pc.lenx == 2) == false
|
||||||
|
doAssert: compiles(pc2.lenx == 2) == false
|
||||||
|
doAssert: compiles(pc[0] = 2.0) == false
|
||||||
|
doAssert: compiles(pc2[0] = 2.0) == false
|
||||||
|
|
||||||
|
doAssert: pc[0] == 1.0
|
||||||
|
doAssert: pc2[0] == 1.0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue