selfhost: fix extend-for method linked list + trait bounds check before indirect call return
- parser: extend-for only linked first 2 methods; now uses lastMethod pointer - sema: trait bounds checking was after indirect-call early return (tyFunc path), so Max<Circle>(...) skipped bounds check when callee had tekFunc refType. Moved bounds check before both indirect/direct call returns. - Negative test: Circle without Comparable impl now correctly errors. - Selfhost loop: C output IDENTICAL.
This commit is contained in:
+9
-5
@@ -1635,21 +1635,25 @@ func parserParseDecl(p: *Parser) -> *Decl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
discard parserExpect(p, tkLBrace, "expected '{'");
|
discard parserExpect(p, tkLBrace, "expected '{'");
|
||||||
|
var methods: *Decl = null as *Decl;
|
||||||
|
var lastMethod: *Decl = null as *Decl;
|
||||||
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
|
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
|
||||||
if parserCheck(p, tkNewLine) { discard parserAdvance(p); continue; }
|
if parserCheck(p, tkNewLine) { discard parserAdvance(p); continue; }
|
||||||
if parserCheck(p, tkFunc) {
|
if parserCheck(p, tkFunc) {
|
||||||
let m: *Decl = parserParseFuncDecl(p, false, false, false);
|
let m: *Decl = parserParseFuncDecl(p, false, false, false);
|
||||||
// Store method in linked list
|
if methods == null as *Decl {
|
||||||
if d.methodCount == 0 {
|
methods = m;
|
||||||
d.childDecl1 = m;
|
lastMethod = m;
|
||||||
} else if d.methodCount == 1 {
|
} else {
|
||||||
d.childDecl1.childDecl2 = m;
|
lastMethod.childDecl2 = m;
|
||||||
|
lastMethod = m;
|
||||||
}
|
}
|
||||||
d.methodCount = d.methodCount + 1;
|
d.methodCount = d.methodCount + 1;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
d.childDecl1 = methods;
|
||||||
discard parserExpect(p, tkRBrace, "expected '}'");
|
discard parserExpect(p, tkRBrace, "expected '}'");
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -565,6 +565,16 @@ func Sema_CheckExpr(sema: *Sema, expr: *Expr) -> int {
|
|||||||
ai = ai + 1;
|
ai = ai + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Trait bounds checking for explicit generic calls: Max<Circle>(...)
|
||||||
|
// Must happen before indirect/direct call returns
|
||||||
|
if expr.child1.kind == ekIdent {
|
||||||
|
let sym: Symbol = Scope_Lookup(sema.scope, expr.child1.strValue);
|
||||||
|
if sym.kind == skFunc && sym.decl != null as *Decl {
|
||||||
|
if expr.child1.genericTypeArgCount > 0 {
|
||||||
|
Sema_CheckTraitBounds(sema, sym.decl, expr.child1.genericTypeArg0, expr.child1.genericTypeArg1, expr.child1.genericTypeArgCount, expr.line, expr.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Indirect call through function-typed value
|
// Indirect call through function-typed value
|
||||||
if calleeType == tyFunc {
|
if calleeType == tyFunc {
|
||||||
if expr.child1.refType != null as *TypeExpr && expr.child1.refType.kind == tekFunc {
|
if expr.child1.refType != null as *TypeExpr && expr.child1.refType.kind == tekFunc {
|
||||||
@@ -577,17 +587,11 @@ func Sema_CheckExpr(sema: *Sema, expr: *Expr) -> int {
|
|||||||
// Direct call to named function
|
// Direct call to named function
|
||||||
if expr.child1.kind == ekIdent {
|
if expr.child1.kind == ekIdent {
|
||||||
let sym: Symbol = Scope_Lookup(sema.scope, expr.child1.strValue);
|
let sym: Symbol = Scope_Lookup(sema.scope, expr.child1.strValue);
|
||||||
if sym.kind == skFunc {
|
if sym.kind == skFunc && sym.decl != null as *Decl {
|
||||||
if sym.decl != null as *Decl {
|
|
||||||
// Trait bounds checking for explicit generic calls: Max<Circle>(...)
|
|
||||||
if expr.child1.genericTypeArgCount > 0 {
|
|
||||||
Sema_CheckTraitBounds(sema, sym.decl, expr.child1.genericTypeArg0, expr.child1.genericTypeArg1, expr.child1.genericTypeArgCount, expr.line, expr.column);
|
|
||||||
}
|
|
||||||
if sym.decl.retType != null as *TypeExpr {
|
if sym.decl.retType != null as *TypeExpr {
|
||||||
return Sema_ResolveType(sema, sym.decl.retType);
|
return Sema_ResolveType(sema, sym.decl.retType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return tyUnknown;
|
return tyUnknown;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user