}
// TODO(gri) do we need this for Alias types?
- var newTArgs []Type
if t.TypeArgs().Len() != n {
return Typ[Invalid] // error reported elsewhere
}
// already instantiated
- // For each (existing) type argument targ, determine if it needs
+ // For each (existing) type argument determine if it needs
// to be substituted; i.e., if it is or contains a type parameter
// that has a type argument for it.
- for i, targ := range t.TypeArgs().list() {
- new_targ := subst.typ(targ)
- if new_targ != targ {
- if newTArgs == nil {
- newTArgs = make([]Type, n)
- copy(newTArgs, t.TypeArgs().list())
- }
- newTArgs[i] = new_targ
- }
- }
-
- if newTArgs == nil {
- return t // nothing to substitute
+ targs, updated := subst.typeList(t.TypeArgs().list())
+ if updated {
+ return subst.check.newAliasInstance(subst.pos, t.orig, targs, subst.ctxt)
}
- return subst.check.newAliasInstance(subst.pos, t.orig, newTArgs, subst.ctxt)
-
case *Array:
elem := subst.typOrNil(t.elem)
if elem != t.elem {
}
case *Named:
- // dump is for debugging
- dump := func(string, ...interface{}) {}
- if subst.check != nil && subst.check.conf.Trace {
- subst.check.indent++
- defer func() {
- subst.check.indent--
- }()
- dump = func(format string, args ...interface{}) {
- subst.check.trace(subst.pos, format, args...)
- }
- }
-
// subst is called during expansion, so in this function we need to be
// careful not to call any methods that would cause t to be expanded: doing
// so would result in deadlock.
orig := t.Origin()
n := orig.TypeParams().Len()
if n == 0 {
- dump(">>> %s is not parameterized", t)
return t // type is not parameterized
}
- var newTArgs []Type
if t.TypeArgs().Len() != n {
return Typ[Invalid] // error reported elsewhere
}
// already instantiated
- dump(">>> %s already instantiated", t)
- // For each (existing) type argument targ, determine if it needs
+ // For each (existing) type argument determine if it needs
// to be substituted; i.e., if it is or contains a type parameter
// that has a type argument for it.
- for i, targ := range t.TypeArgs().list() {
- dump(">>> %d targ = %s", i, targ)
- new_targ := subst.typ(targ)
- if new_targ != targ {
- dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
- if newTArgs == nil {
- newTArgs = make([]Type, n)
- copy(newTArgs, t.TypeArgs().list())
- }
- newTArgs[i] = new_targ
- }
+ targs, updated := subst.typeList(t.TypeArgs().list())
+ if updated {
+ // Create a new instance and populate the context to avoid endless
+ // 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.
+ return subst.check.instance(subst.pos, orig, targs, subst.expanding, subst.ctxt)
}
- if newTArgs == nil {
- dump(">>> nothing to substitute in %s", t)
- return t // nothing to substitute
- }
-
- // Create a new instance and populate the context to avoid endless
- // 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.
- return subst.check.instance(subst.pos, orig, newTArgs, subst.expanding, subst.ctxt)
-
case *TypeParam:
return subst.smap.lookup(t)
}
// TODO(gri) do we need this for Alias types?
- var newTArgs []Type
if t.TypeArgs().Len() != n {
return Typ[Invalid] // error reported elsewhere
}
// already instantiated
- // For each (existing) type argument targ, determine if it needs
+ // For each (existing) type argument determine if it needs
// to be substituted; i.e., if it is or contains a type parameter
// that has a type argument for it.
- for i, targ := range t.TypeArgs().list() {
- new_targ := subst.typ(targ)
- if new_targ != targ {
- if newTArgs == nil {
- newTArgs = make([]Type, n)
- copy(newTArgs, t.TypeArgs().list())
- }
- newTArgs[i] = new_targ
- }
- }
-
- if newTArgs == nil {
- return t // nothing to substitute
+ targs, updated := subst.typeList(t.TypeArgs().list())
+ if updated {
+ return subst.check.newAliasInstance(subst.pos, t.orig, targs, subst.ctxt)
}
- return subst.check.newAliasInstance(subst.pos, t.orig, newTArgs, subst.ctxt)
-
case *Array:
elem := subst.typOrNil(t.elem)
if elem != t.elem {
}
case *Named:
- // dump is for debugging
- dump := func(string, ...interface{}) {}
- if subst.check != nil && subst.check.conf._Trace {
- subst.check.indent++
- defer func() {
- subst.check.indent--
- }()
- dump = func(format string, args ...interface{}) {
- subst.check.trace(subst.pos, format, args...)
- }
- }
-
// subst is called during expansion, so in this function we need to be
// careful not to call any methods that would cause t to be expanded: doing
// so would result in deadlock.
orig := t.Origin()
n := orig.TypeParams().Len()
if n == 0 {
- dump(">>> %s is not parameterized", t)
return t // type is not parameterized
}
- var newTArgs []Type
if t.TypeArgs().Len() != n {
return Typ[Invalid] // error reported elsewhere
}
// already instantiated
- dump(">>> %s already instantiated", t)
- // For each (existing) type argument targ, determine if it needs
+ // For each (existing) type argument determine if it needs
// to be substituted; i.e., if it is or contains a type parameter
// that has a type argument for it.
- for i, targ := range t.TypeArgs().list() {
- dump(">>> %d targ = %s", i, targ)
- new_targ := subst.typ(targ)
- if new_targ != targ {
- dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
- if newTArgs == nil {
- newTArgs = make([]Type, n)
- copy(newTArgs, t.TypeArgs().list())
- }
- newTArgs[i] = new_targ
- }
+ targs, updated := subst.typeList(t.TypeArgs().list())
+ if updated {
+ // Create a new instance and populate the context to avoid endless
+ // 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.
+ return subst.check.instance(subst.pos, orig, targs, subst.expanding, subst.ctxt)
}
- if newTArgs == nil {
- dump(">>> nothing to substitute in %s", t)
- return t // nothing to substitute
- }
-
- // Create a new instance and populate the context to avoid endless
- // 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.
- return subst.check.instance(subst.pos, orig, newTArgs, subst.expanding, subst.ctxt)
-
case *TypeParam:
return subst.smap.lookup(t)