}
// type definition or generic type declaration
- named := check.newNamed(obj, nil, nil, nil, nil)
+ named := check.newNamed(obj, nil, nil, nil)
def.setUnderlying(named)
if tdecl.TParamList != nil {
}
if base != nil {
- base.resolve(nil) // TODO(mdempsky): Probably unnecessary.
base.AddMethod(m)
}
}
"bytes"
"cmd/compile/internal/syntax"
"fmt"
+ "runtime"
"strconv"
"strings"
)
func assert(p bool) {
if !p {
- panic("assertion failed")
+ msg := "assertion failed"
+ // Include information about the assertion location. Due to panic recovery,
+ // this location is otherwise buried in the middle of the panicking stack.
+ if _, file, line, ok := runtime.Caller(1); ok {
+ msg = fmt.Sprintf("%s:%d: %s", file, line, msg)
+ }
+ panic(msg)
}
}
switch orig := orig.(type) {
case *Named:
tname := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
- named := check.newNamed(tname, orig, nil, nil, nil) // underlying, tparams, and methods are set when named is resolved
+ named := check.newNamed(tname, orig, nil, nil) // underlying, tparams, and methods are set when named is resolved
named.targs = newTypeList(targs)
named.resolver = func(ctxt *Context, n *Named) (*TypeParamList, Type, *methodList) {
return expandNamed(ctxt, n, pos)
seen.add(named)
// look for a matching attached method
- named.resolve(nil)
if i, m := named.lookupMethod(pkg, name, foldCase); m != nil {
// potential match
// caution: method may not have a proper signature yet
if _, ok := underlying.(*Named); ok {
panic("underlying type must not be *Named")
}
- return (*Checker)(nil).newNamed(obj, nil, underlying, nil, newMethodList(methods))
+ return (*Checker)(nil).newNamed(obj, nil, underlying, newMethodList(methods))
}
func (t *Named) resolve(ctxt *Context) *Named {
}
// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
-func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tparams *TypeParamList, methods *methodList) *Named {
- typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, tparams: tparams, methods: methods}
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods *methodList) *Named {
+ typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, methods: methods}
if typ.orig == nil {
typ.orig = typ
}
// as the method."
switch T := rtyp.(type) {
case *Named:
- T.resolve(check.bestContext(nil))
// The receiver type may be an instantiated type referred to
// by an alias (which cannot have receiver parameters for now).
if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
// recursion. The position used here is irrelevant because validation only
// occurs on t (we don't call validType on named), but we use subst.pos to
// help with debugging.
- t.orig.resolve(subst.ctxt)
return subst.check.instance(subst.pos, t.orig, newTArgs, subst.ctxt)
// Note that if we were to expose substitution more generally (not just in
if inst == nil {
// x may be a selector for an imported type; use its start pos rather than x.Pos().
tname := NewTypeName(syntax.StartPos(x), orig.obj.pkg, orig.obj.name, nil)
- inst = check.newNamed(tname, orig, nil, nil, nil) // underlying, methods and tparams are set when named is resolved
+ inst = check.newNamed(tname, orig, nil, nil) // underlying, methods and tparams are set when named is resolved
inst.targs = newTypeList(targs)
inst = ctxt.update(h, orig, targs, inst).(*Named)
}
}
// type definition or generic type declaration
- named := check.newNamed(obj, nil, nil, nil, nil)
+ named := check.newNamed(obj, nil, nil, nil)
def.setUnderlying(named)
if tdecl.TypeParams != nil {
}
if base != nil {
- base.resolve(nil) // TODO(mdempsky): Probably unnecessary.
base.AddMethod(m)
}
}
"fmt"
"go/ast"
"go/token"
+ "runtime"
"strconv"
"strings"
)
func assert(p bool) {
if !p {
- panic("assertion failed")
+ msg := "assertion failed"
+ // Include information about the assertion location. Due to panic recovery,
+ // this location is otherwise buried in the middle of the panicking stack.
+ if _, file, line, ok := runtime.Caller(1); ok {
+ msg = fmt.Sprintf("%s:%d: %s", file, line, msg)
+ }
+ panic(msg)
}
}
switch orig := orig.(type) {
case *Named:
tname := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
- named := check.newNamed(tname, orig, nil, nil, nil) // underlying, tparams, and methods are set when named is resolved
+ named := check.newNamed(tname, orig, nil, nil) // underlying, tparams, and methods are set when named is resolved
named.targs = newTypeList(targs)
named.resolver = func(ctxt *Context, n *Named) (*TypeParamList, Type, *methodList) {
return expandNamed(ctxt, n, pos)
seen.add(named)
// look for a matching attached method
- named.resolve(nil)
if i, m := named.lookupMethod(pkg, name, foldCase); m != nil {
// potential match
// caution: method may not have a proper signature yet
if _, ok := underlying.(*Named); ok {
panic("underlying type must not be *Named")
}
- return (*Checker)(nil).newNamed(obj, nil, underlying, nil, newMethodList(methods))
+ return (*Checker)(nil).newNamed(obj, nil, underlying, newMethodList(methods))
}
func (t *Named) resolve(ctxt *Context) *Named {
}
// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
-func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, tparams *TypeParamList, methods *methodList) *Named {
- typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, tparams: tparams, methods: methods}
+func (check *Checker) newNamed(obj *TypeName, orig *Named, underlying Type, methods *methodList) *Named {
+ typ := &Named{check: check, obj: obj, orig: orig, fromRHS: underlying, underlying: underlying, methods: methods}
if typ.orig == nil {
typ.orig = typ
}
// as the method."
switch T := rtyp.(type) {
case *Named:
- T.resolve(check.bestContext(nil))
// The receiver type may be an instantiated type referred to
// by an alias (which cannot have receiver parameters for now).
if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
// recursion. The position used here is irrelevant because validation only
// occurs on t (we don't call validType on named), but we use subst.pos to
// help with debugging.
- t.orig.resolve(subst.ctxt)
return subst.check.instance(subst.pos, t.orig, newTArgs, subst.ctxt)
// Note that if we were to expose substitution more generally (not just in
if inst == nil {
// x may be a selector for an imported type; use its start pos rather than x.Pos().
tname := NewTypeName(ix.Pos(), orig.obj.pkg, orig.obj.name, nil)
- inst = check.newNamed(tname, orig, nil, nil, nil) // underlying, methods and tparams are set when named is resolved
+ inst = check.newNamed(tname, orig, nil, nil) // underlying, methods and tparams are set when named is resolved
inst.targs = newTypeList(targs)
inst = ctxt.update(h, orig, targs, inst).(*Named)
}