-
Notifications
You must be signed in to change notification settings - Fork 39
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
sem: all tuple fields now have an owning sym #816
base: devel
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -430,7 +430,6 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = | |
result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared}) | ||
if result.isError: | ||
markUsed(c, n.info, result) | ||
|
||
# XXX: move to propagating nkError, skError, and tyError | ||
localReport(c.config, result.ast) | ||
elif result != nil: | ||
|
@@ -447,7 +446,6 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = | |
if result.typ.sym == nil: | ||
let err = newError(c.config, n, PAstDiag(kind: adSemTypeExpected)) | ||
localReport(c.config, err) | ||
|
||
return errorSym(c, n, err) | ||
result = result.typ.sym.copySym(nextSymId c.idgen) | ||
result.typ = exactReplica(result.typ) | ||
|
@@ -479,7 +477,6 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = | |
let err = newError(c.config, n, PAstDiag(kind: adSemTypeExpected)) | ||
if result.kind != skError: | ||
localReport(c.config, err) | ||
|
||
return errorSym(c, n, err) | ||
if result.typ.kind != tyGenericParam: | ||
# XXX get rid of this hack! | ||
|
@@ -500,6 +497,17 @@ proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType = | |
if n.len == 0: | ||
localReport(c.config, n, reportSem rsemTypeExpected) | ||
result = newOrPrevType(tyTuple, prev, c) | ||
let setupOwner = c.inGenericContext == 0 and result.sym.isNil | ||
if setupOwner: | ||
# xxx: instead of "AnonType" maybe generate a name from the field | ||
# names+types with some caching so the same structures have the same | ||
# names/symbols. | ||
let sym = newSym(skType, getIdent(c.cache, "AnonType"), | ||
nextSymId c.idgen, c.getCurrOwner(), n.info) | ||
saem marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sym.flags.incl sfAnon | ||
sym.typ = result | ||
result.owner = sym | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a symbol directly represents the type, then it is generally assigned to the types's There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It did, but more so for the silly |
||
pushOwner(c, sym) | ||
for it in n: | ||
let t = semTypeNode(c, it, nil).skipIntLit(c.idgen) | ||
if prev != nil and prev.aliasesType(t): | ||
|
@@ -508,13 +516,26 @@ proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType = | |
break | ||
else: | ||
rawAddSon(result, t) | ||
if setupOwner: | ||
popOwner(c) | ||
|
||
proc semTuple(c: PContext, n: PNode, prev: PType): PType = | ||
# TODO: replace with a node returning variant that can in band errors | ||
addInNimDebugUtils(c.config, "semTuple", n, prev, result) | ||
var typ: PType | ||
result = newOrPrevType(tyTuple, prev, c) | ||
result.n = newNodeI(nkRecList, n.info) | ||
let setupOwner = c.inGenericContext == 0 and result.sym.isNil | ||
if setupOwner: | ||
# xxx: instead of "AnonType" maybe generate a name from the field | ||
# names+types with some caching so the same structures have the same | ||
# names/symbols. | ||
let sym = newSym(skType, getIdent(c.cache, "AnonType"), | ||
nextSymId c.idgen, c.getCurrOwner(), n.info) | ||
saem marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sym.flags.incl sfAnon | ||
sym.typ = result | ||
result.owner = sym | ||
pushOwner(c, sym) | ||
var check = initIntSet() | ||
var counter = 0 | ||
for i in ord(n.kind == nkBracketExpr)..<n.len: | ||
|
@@ -523,17 +544,14 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = | |
c.config.globalReport(reportAst( | ||
rsemIllformedAst, a, | ||
str = "Expected identDefs for node, but found " & $a.kind)) | ||
|
||
checkMinSonsLen(a, 3, c.config) | ||
if a[^2].kind != nkEmpty: | ||
typ = semTypeNode(c, a[^2], nil) | ||
else: | ||
localReport(c.config, a, reportSem rsemTypeExpected) | ||
typ = errorType(c) | ||
|
||
if a[^1].kind != nkEmpty: | ||
localReport(c.config, a[^1], reportSem rsemInitHereNotAllowed) | ||
|
||
for j in 0 ..< a.len - 2: | ||
let | ||
fieldNode = newSymGNode(skField, a[j], c) | ||
|
@@ -547,13 +565,13 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = | |
else: | ||
result.n.add newSymNode(field) | ||
addSonSkipIntLit(result, typ, c.idgen) | ||
|
||
styleCheckDef(c.config, a[j].info, field) | ||
|
||
if result.n.len == 0: result.n = nil | ||
if isTupleRecursive(result): | ||
localReport(c.config, n.info, reportTyp( | ||
rsemIllegalRecursion, result)) | ||
if setupOwner: | ||
popOwner(c) | ||
|
||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, | ||
allowed: TSymFlags): PSym = | ||
|
@@ -862,7 +880,6 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, | |
var it = n[i] | ||
if it == nil: | ||
semReportIllformedAst(c.config, n, "nil") | ||
|
||
var idx = 1 | ||
case it.kind | ||
of nkElifBranch: | ||
|
@@ -880,7 +897,6 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, | |
else: | ||
semReportIllformedAst( | ||
c.config, n, "Expected elifBranch of else, but found" & $it.kind) | ||
|
||
if c.inGenericContext > 0: | ||
# use a new check intset here for each branch: | ||
var newCheck: IntSet | ||
|
@@ -936,12 +952,10 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, | |
inc(pos) | ||
if containsOrIncl(check, f.name.id): | ||
localReport(c.config, info, reportSym(rsemRedefinitionOf, f)) | ||
|
||
if a.kind == nkEmpty: | ||
father.add newSymNode(f) | ||
else: | ||
a.add newSymNode(f) | ||
|
||
styleCheckDef(c.config, f) | ||
if a.kind != nkEmpty: father.add a | ||
of nkSym: | ||
|
@@ -950,7 +964,6 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, | |
# There is no branch validity check here | ||
if containsOrIncl(check, n.sym.name.id): | ||
localReport(c.config, n.info, reportSym(rsemRedefinitionOf, n.sym)) | ||
|
||
father.add n | ||
of nkEmpty: | ||
if father.kind in {nkElse, nkOfBranch}: | ||
|
@@ -1026,7 +1039,6 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType | |
if concreteBase.kind != tyError: | ||
localReport(c.config, n[1].info, reportTyp( | ||
rsemExpectNonFinalForBase, realBase)) | ||
|
||
base = nil | ||
realBase = nil | ||
c.config.internalAssert(n.kind == nkObjectTy, n.info, "semObjectNode") | ||
|
@@ -1049,7 +1061,6 @@ proc semObjectNode(c: PContext, n: PNode, prev: PType; flags: TTypeFlags): PType | |
# check if we got any errors and if so report them | ||
for e in ifErrorWalkErrors(c.config, n[0]): | ||
localReport(c.config, e) | ||
|
||
if base == nil and tfInheritable notin result.flags: | ||
incl(result.flags, tfFinal) | ||
|
||
|
@@ -2142,7 +2153,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = | |
var base = semTypeNode(c, n[1], nil) | ||
if base.kind in {tyVar, tyLent}: | ||
localReport(c.config, n.info, reportTyp(rsemVarVarNotAllowed, prev)) | ||
|
||
base = base[0] | ||
addSonSkipIntLit(result, base, c.idgen) | ||
of mRef: result = semAnyRef(c, n, tyRef, prev) | ||
|
@@ -2177,7 +2187,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = | |
if s.typ == nil: | ||
if s.kind != skError: | ||
localReport(c.config, n, reportSem rsemTypeExpected) | ||
|
||
result = newOrPrevType(tyError, prev, c) | ||
elif s.kind == skParam and s.typ.kind == tyTypeDesc: | ||
c.config.internalAssert s.typ.base.kind != tyNone and prev == nil | ||
|
@@ -2216,7 +2225,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = | |
else: | ||
if s.kind != skError: | ||
localReport(c.config, n.info, reportSym(rsemTypeExpected, s)) | ||
|
||
result = newOrPrevType(tyError, prev, c) | ||
of nkObjectTy: result = semObjectNode(c, n, prev, {}) | ||
of nkTupleTy: result = semTuple(c, n, prev) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't verified it, but I think the check is an issue in the following case:
When the tuple type is sem-checked,
inGenericContext
is greater than 0 andresult.sym
is nil.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh, good call.
I was suspicious of the owner pushing in the right hand side type section analysis for generics, and I think that's coming home to roost here.