mirror of https://github.com/golang/go.git
go/types: implement conversions to generic types
Change-Id: Ifa878fddea3548a27579b3196921c6816f2d9363
This commit is contained in:
parent
75897ab270
commit
29f795f511
|
|
@ -1,6 +1,6 @@
|
|||
TODO
|
||||
- allow recursive type parameterization without need to repeat type parameters
|
||||
- if type parameters are repeated in recursive instantiation, they must be the same order
|
||||
- if type parameters are repeated in recursive instantiation, they must be the same order (not yet checked)
|
||||
- implement contract embedding
|
||||
- interface embedding doesn't take care of literal type constraints yet
|
||||
(need an allTypes list, like we have an allMethods list?)
|
||||
|
|
@ -8,7 +8,6 @@ TODO
|
|||
OPEN ISSUES
|
||||
- using a contract and enumerating type arguments currently leads to an error (e.g. func f(type T C(T)) (x T) ... )
|
||||
git add - contracts slip through in places where only types are permitted
|
||||
- conversions against parameterized types are not implemented
|
||||
- parameterized interface methods (of type bounds) need to be customized (subst) for context
|
||||
|
||||
DESIGN DECISIONS
|
||||
|
|
|
|||
|
|
@ -510,6 +510,39 @@ func (check *Checker) convertUntyped(x *operand, target Type) {
|
|||
return
|
||||
}
|
||||
|
||||
// In case of a type parameter, conversion must succeed against
|
||||
// all types enumerated by the the type parameter bound.
|
||||
if t, _ := target.Underlying().(*TypeParam); t != nil {
|
||||
types := t.Interface().types
|
||||
if len(types) == 0 {
|
||||
goto Error
|
||||
}
|
||||
|
||||
for _, t := range t.Interface().types {
|
||||
check.convertUntypedInternal(x, t)
|
||||
if x.mode == invalid {
|
||||
goto Error
|
||||
}
|
||||
}
|
||||
|
||||
x.typ = target
|
||||
check.updateExprType(x.expr, target, true) // UntypedNils are final
|
||||
return
|
||||
}
|
||||
|
||||
check.convertUntypedInternal(x, target)
|
||||
return
|
||||
|
||||
Error:
|
||||
// TODO(gri) better error message (explain cause)
|
||||
check.errorf(x.pos(), "cannot convert %s to %s", x, target)
|
||||
x.mode = invalid
|
||||
}
|
||||
|
||||
// convertUntypedInternal should only be called by convertUntyped.
|
||||
func (check *Checker) convertUntypedInternal(x *operand, target Type) {
|
||||
assert(isTyped(target))
|
||||
|
||||
// typed target
|
||||
switch t := target.Underlying().(type) {
|
||||
case *Basic:
|
||||
|
|
|
|||
|
|
@ -62,10 +62,9 @@ contract Complex(T) {
|
|||
type OrderedAbs(type T OrderedNumeric) T
|
||||
|
||||
func (a OrderedAbs(T)) Abs() T {
|
||||
// TODO(gri) implement conversions against parameterized types
|
||||
// if a < 0 {
|
||||
// return -a
|
||||
// }
|
||||
if a < 0 {
|
||||
return -a
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue