remove {.this.} pragma, deprecated since 0.19 (#20201)
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
3dbf2ac946
commit
f6eb1d4d7d
13 changed files with 28 additions and 158 deletions
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
- `nimPreviewDotLikeOps` is going to be removed or deprecated.
|
- `nimPreviewDotLikeOps` is going to be removed or deprecated.
|
||||||
|
|
||||||
|
- The `{.this.}` pragma, deprecated since 0.19, has been removed.
|
||||||
- `nil` is no longer a valid value for distinct pointer types.
|
- `nil` is no longer a valid value for distinct pointer types.
|
||||||
|
|
||||||
## Standard library additions and changes
|
## Standard library additions and changes
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,6 @@ const
|
||||||
sfWrittenTo* = sfBorrow # param is assigned to
|
sfWrittenTo* = sfBorrow # param is assigned to
|
||||||
sfEscapes* = sfProcvar # param escapes
|
sfEscapes* = sfProcvar # param escapes
|
||||||
sfBase* = sfDiscriminant
|
sfBase* = sfDiscriminant
|
||||||
sfIsSelf* = sfOverriden # param is 'self'
|
|
||||||
sfCustomPragma* = sfRegister # symbol is custom pragma template
|
sfCustomPragma* = sfRegister # symbol is custom pragma template
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -1216,15 +1216,6 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
if not isTopLevel(c):
|
if not isTopLevel(c):
|
||||||
localError(c.config, n.info, "'experimental' pragma only valid as toplevel statement or in a 'push' environment")
|
localError(c.config, n.info, "'experimental' pragma only valid as toplevel statement or in a 'push' environment")
|
||||||
processExperimental(c, it)
|
processExperimental(c, it)
|
||||||
of wThis:
|
|
||||||
if it.kind in nkPragmaCallKinds and it.len == 2:
|
|
||||||
c.selfName = considerQuotedIdent(c, it[1])
|
|
||||||
message(c.config, n.info, warnDeprecated, "'.this' pragma is deprecated")
|
|
||||||
elif it.kind == nkIdent or it.len == 1:
|
|
||||||
c.selfName = getIdent(c.cache, "self")
|
|
||||||
message(c.config, n.info, warnDeprecated, "'.this' pragma is deprecated")
|
|
||||||
else:
|
|
||||||
localError(c.config, it.info, "'this' pragma is allowed to have zero or one arguments")
|
|
||||||
of wNoRewrite:
|
of wNoRewrite:
|
||||||
noVal(c, it)
|
noVal(c, it)
|
||||||
of wBase:
|
of wBase:
|
||||||
|
|
|
||||||
|
|
@ -374,22 +374,6 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
|
||||||
|
|
||||||
let overloadsState = result.state
|
let overloadsState = result.state
|
||||||
if overloadsState != csMatch:
|
if overloadsState != csMatch:
|
||||||
if c.p != nil and c.p.selfSym != nil:
|
|
||||||
# we need to enforce semchecking of selfSym again because it
|
|
||||||
# might need auto-deref:
|
|
||||||
var hiddenArg = newSymNode(c.p.selfSym)
|
|
||||||
hiddenArg.typ = nil
|
|
||||||
n.sons.insert(hiddenArg, 1)
|
|
||||||
orig.sons.insert(hiddenArg, 1)
|
|
||||||
|
|
||||||
pickBest(f)
|
|
||||||
|
|
||||||
if result.state != csMatch:
|
|
||||||
n.sons.delete(1)
|
|
||||||
orig.sons.delete(1)
|
|
||||||
excl n.flags, nfExprCall
|
|
||||||
else: return
|
|
||||||
|
|
||||||
if nfDotField in n.flags:
|
if nfDotField in n.flags:
|
||||||
internalAssert c.config, f.kind == nkIdent and n.len >= 2
|
internalAssert c.config, f.kind == nkIdent and n.len >= 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ type
|
||||||
# statements
|
# statements
|
||||||
owner*: PSym # the symbol this context belongs to
|
owner*: PSym # the symbol this context belongs to
|
||||||
resultSym*: PSym # the result symbol (if we are in a proc)
|
resultSym*: PSym # the result symbol (if we are in a proc)
|
||||||
selfSym*: PSym # the 'self' symbol (if available)
|
|
||||||
nestedLoopCounter*: int # whether we are in a loop or not
|
nestedLoopCounter*: int # whether we are in a loop or not
|
||||||
nestedBlockCounter*: int # whether we are in a block or not
|
nestedBlockCounter*: int # whether we are in a block or not
|
||||||
next*: PProcCon # used for stacking procedure contexts
|
next*: PProcCon # used for stacking procedure contexts
|
||||||
|
|
@ -149,7 +148,6 @@ type
|
||||||
inParallelStmt*: int
|
inParallelStmt*: int
|
||||||
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
instTypeBoundOp*: proc (c: PContext; dc: PSym; t: PType; info: TLineInfo;
|
||||||
op: TTypeAttachedOp; col: int): PSym {.nimcall.}
|
op: TTypeAttachedOp; col: int): PSym {.nimcall.}
|
||||||
selfName*: PIdent
|
|
||||||
cache*: IdentCache
|
cache*: IdentCache
|
||||||
graph*: ModuleGraph
|
graph*: ModuleGraph
|
||||||
signatures*: TStrTable
|
signatures*: TStrTable
|
||||||
|
|
|
||||||
|
|
@ -1283,33 +1283,6 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
result.typ = makeTypeDesc(c, s.typ)
|
result.typ = makeTypeDesc(c, s.typ)
|
||||||
of skField:
|
of skField:
|
||||||
var p = c.p
|
|
||||||
while p != nil and p.selfSym == nil:
|
|
||||||
p = p.next
|
|
||||||
if p != nil and p.selfSym != nil:
|
|
||||||
var ty = skipTypes(p.selfSym.typ, {tyGenericInst, tyVar, tyLent, tyPtr, tyRef,
|
|
||||||
tyAlias, tySink, tyOwned})
|
|
||||||
while tfBorrowDot in ty.flags: ty = ty.skipTypes({tyDistinct, tyGenericInst, tyAlias})
|
|
||||||
var check: PNode = nil
|
|
||||||
if ty.kind == tyObject:
|
|
||||||
while true:
|
|
||||||
check = nil
|
|
||||||
let f = lookupInRecordAndBuildCheck(c, n, ty.n, s.name, check)
|
|
||||||
if f != nil and fieldVisible(c, f):
|
|
||||||
# is the access to a public field or in the same module or in a friend?
|
|
||||||
doAssert f == s
|
|
||||||
markUsed(c, n.info, f)
|
|
||||||
onUse(n.info, f)
|
|
||||||
result = newNodeIT(nkDotExpr, n.info, f.typ)
|
|
||||||
result.add makeDeref(newSymNode(p.selfSym))
|
|
||||||
result.add newSymNode(f) # we now have the correct field
|
|
||||||
if check != nil:
|
|
||||||
check[0] = result
|
|
||||||
check.typ = result.typ
|
|
||||||
result = check
|
|
||||||
return result
|
|
||||||
if ty[0] == nil: break
|
|
||||||
ty = skipTypes(ty[0], skipPtrs)
|
|
||||||
# old code, not sure if it's live code:
|
# old code, not sure if it's live code:
|
||||||
markUsed(c, n.info, s)
|
markUsed(c, n.info, s)
|
||||||
onUse(n.info, s)
|
onUse(n.info, s)
|
||||||
|
|
|
||||||
|
|
@ -28,32 +28,13 @@ proc addObjFieldsToLocalScope(c: PContext; n: PNode) =
|
||||||
# it is not an error to shadow fields via parameters
|
# it is not an error to shadow fields via parameters
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc rawPushProcCon(c: PContext, owner: PSym) =
|
proc pushProcCon*(c: PContext; owner: PSym) =
|
||||||
var x: PProcCon
|
var x: PProcCon
|
||||||
new(x)
|
new(x)
|
||||||
x.owner = owner
|
x.owner = owner
|
||||||
x.next = c.p
|
x.next = c.p
|
||||||
c.p = x
|
c.p = x
|
||||||
|
|
||||||
proc rawHandleSelf(c: PContext; owner: PSym) =
|
|
||||||
const callableSymbols = {skProc, skFunc, skMethod, skConverter, skIterator, skMacro}
|
|
||||||
if c.selfName != nil and owner.kind in callableSymbols and owner.typ != nil:
|
|
||||||
let params = owner.typ.n
|
|
||||||
if params.len > 1:
|
|
||||||
let arg = params[1].sym
|
|
||||||
if arg.name.id == c.selfName.id:
|
|
||||||
c.p.selfSym = arg
|
|
||||||
arg.flags.incl sfIsSelf
|
|
||||||
var t = c.p.selfSym.typ.skipTypes(abstractPtrs)
|
|
||||||
while t.kind == tyObject:
|
|
||||||
addObjFieldsToLocalScope(c, t.n)
|
|
||||||
if t[0] == nil: break
|
|
||||||
t = t[0].skipTypes(skipPtrs)
|
|
||||||
|
|
||||||
proc pushProcCon*(c: PContext; owner: PSym) =
|
|
||||||
rawPushProcCon(c, owner)
|
|
||||||
rawHandleSelf(c, owner)
|
|
||||||
|
|
||||||
const
|
const
|
||||||
errCannotInstantiateX = "cannot instantiate: '$1'"
|
errCannotInstantiateX = "cannot instantiate: '$1'"
|
||||||
|
|
||||||
|
|
@ -377,7 +358,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
addDecl(c, s)
|
addDecl(c, s)
|
||||||
entry.concreteTypes[i] = s.typ
|
entry.concreteTypes[i] = s.typ
|
||||||
inc i
|
inc i
|
||||||
rawPushProcCon(c, result)
|
pushProcCon(c, result)
|
||||||
instantiateProcType(c, pt, result, info)
|
instantiateProcType(c, pt, result, info)
|
||||||
for j in 1..<result.typ.len:
|
for j in 1..<result.typ.len:
|
||||||
entry.concreteTypes[i] = result.typ[j]
|
entry.concreteTypes[i] = result.typ[j]
|
||||||
|
|
@ -392,7 +373,6 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
# a ``compiles`` context but this is the lesser evil. See
|
# a ``compiles`` context but this is the lesser evil. See
|
||||||
# bug #1055 (tevilcompiles).
|
# bug #1055 (tevilcompiles).
|
||||||
#if c.compilesContextId == 0:
|
#if c.compilesContextId == 0:
|
||||||
rawHandleSelf(c, result)
|
|
||||||
entry.compilesId = c.compilesContextId
|
entry.compilesId = c.compilesContextId
|
||||||
addToGenericProcCache(c, fn, entry)
|
addToGenericProcCache(c, fn, entry)
|
||||||
c.generics.add(makeInstPair(fn, entry))
|
c.generics.add(makeInstPair(fn, entry))
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ after 20 20'''
|
||||||
joinable: false
|
joinable: false
|
||||||
"""
|
"""
|
||||||
|
|
||||||
{.this: self.}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
mystring = object
|
mystring = object
|
||||||
len, cap: int
|
len, cap: int
|
||||||
|
|
@ -51,7 +49,7 @@ proc resize(self: var mystring) =
|
||||||
if self.cap == 0: self.cap = 8
|
if self.cap == 0: self.cap = 8
|
||||||
else: self.cap = (self.cap * 3) shr 1
|
else: self.cap = (self.cap * 3) shr 1
|
||||||
if self.data == nil: inc allocCount
|
if self.data == nil: inc allocCount
|
||||||
self.data = cast[type(data)](realloc(self.data, self.cap + 1))
|
self.data = cast[type(self.data)](realloc(self.data, self.cap + 1))
|
||||||
|
|
||||||
proc add*(self: var mystring; c: char) =
|
proc add*(self: var mystring; c: char) =
|
||||||
if self.len >= self.cap: resize(self)
|
if self.len >= self.cap: resize(self)
|
||||||
|
|
@ -60,17 +58,17 @@ proc add*(self: var mystring; c: char) =
|
||||||
inc self.len
|
inc self.len
|
||||||
|
|
||||||
proc ensure(self: var mystring; newLen: int) =
|
proc ensure(self: var mystring; newLen: int) =
|
||||||
if newLen >= cap:
|
if newLen >= self.cap:
|
||||||
cap = max((cap * 3) shr 1, newLen)
|
self.cap = max((self.cap * 3) shr 1, newLen)
|
||||||
if cap > 0:
|
if self.cap > 0:
|
||||||
if data == nil: inc allocCount
|
if self.data == nil: inc allocCount
|
||||||
data = cast[type(data)](realloc(data, cap + 1))
|
self.data = cast[type(self.data)](realloc(self.data, self.cap + 1))
|
||||||
|
|
||||||
proc add*(self: var mystring; y: mystring) =
|
proc add*(self: var mystring; y: mystring) =
|
||||||
let newLen = len + y.len
|
let newLen = self.len + y.len
|
||||||
ensure(self, newLen)
|
ensure(self, newLen)
|
||||||
copyMem(addr data[len], y.data, y.data.len + 1)
|
copyMem(addr self.data[self.len], y.data, y.data.len + 1)
|
||||||
len = newLen
|
self.len = newLen
|
||||||
|
|
||||||
proc create*(lit: string): mystring =
|
proc create*(lit: string): mystring =
|
||||||
let newLen = lit.len
|
let newLen = lit.len
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
discard """
|
|
||||||
output: '''0 -2 0
|
|
||||||
0 -2'''
|
|
||||||
"""
|
|
||||||
|
|
||||||
{.this: self.}
|
|
||||||
|
|
||||||
type
|
|
||||||
Foo = object
|
|
||||||
a, b, x: int
|
|
||||||
|
|
||||||
proc yay(self: Foo) =
|
|
||||||
echo a, " ", b, " ", x
|
|
||||||
|
|
||||||
proc footest[T](self: var Foo, a: T) =
|
|
||||||
b = 1+a
|
|
||||||
yay()
|
|
||||||
|
|
||||||
proc nongeneric(self: Foo) =
|
|
||||||
echo a, " ", b
|
|
||||||
|
|
||||||
var ff: Foo
|
|
||||||
footest(ff, -3)
|
|
||||||
ff.nongeneric
|
|
||||||
|
|
||||||
{.experimental.}
|
|
||||||
using
|
|
||||||
c: Foo
|
|
||||||
x, y: int
|
|
||||||
|
|
||||||
proc usesSig(c) =
|
|
||||||
echo "yummy"
|
|
||||||
|
|
||||||
proc foobar(c, y) =
|
|
||||||
echo "yay"
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
discard """
|
|
||||||
action: compile
|
|
||||||
"""
|
|
||||||
|
|
||||||
# bug #4671
|
|
||||||
{.experimental.}
|
|
||||||
{.this: self.}
|
|
||||||
type
|
|
||||||
SomeObj = object
|
|
||||||
f: int
|
|
||||||
|
|
||||||
proc f(num: int) =
|
|
||||||
discard
|
|
||||||
|
|
||||||
var intptr: ptr int
|
|
||||||
intptr.f() # compiles fine
|
|
||||||
|
|
||||||
proc doSomething(self: var SomeObj) =
|
|
||||||
var pint: ptr int
|
|
||||||
pint.f() # Error: expression '.(pint, "f")' cannot be called
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
# bug #4177
|
|
||||||
|
|
||||||
type
|
|
||||||
Parent = object of RootObj
|
|
||||||
parentField: int
|
|
||||||
Child = object of Parent
|
|
||||||
childField: int
|
|
||||||
|
|
||||||
{.this: self.}
|
|
||||||
proc sumFields(self: Child): int =
|
|
||||||
result = parentField + childField # Error: undeclared identifier: 'parentField'
|
|
||||||
|
|
||||||
proc sumFieldsWorks(self: Child): int =
|
|
||||||
result = self.parentField + childField
|
|
||||||
16
tests/usingstmt/tusingstmt.nim
Normal file
16
tests/usingstmt/tusingstmt.nim
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
type
|
||||||
|
Foo = object
|
||||||
|
|
||||||
|
using
|
||||||
|
c: Foo
|
||||||
|
x, y: int
|
||||||
|
|
||||||
|
proc usesSig(c) = discard
|
||||||
|
|
||||||
|
proc foobar(c, y) = discard
|
||||||
|
|
||||||
|
usesSig(Foo())
|
||||||
|
foobar(Foo(), 123)
|
||||||
|
doAssert not compiles(usesSig(123))
|
||||||
|
doAssert not compiles(foobar(Foo(), Foo()))
|
||||||
|
doAssert not compiles(foobar(123, 123))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue