mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-28 23:58:40 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ff626dcee |
+26
-30
@@ -196,34 +196,30 @@ func TestImplements(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: AssignableTo should be possible to implement now that Implements()
|
||||
// mostly works.
|
||||
var assignableTests = []struct {
|
||||
x any
|
||||
t any
|
||||
b bool
|
||||
}{
|
||||
{new(chan int), new(<-chan int), true},
|
||||
{new(<-chan int), new(chan int), false},
|
||||
{new(*int), new(IntPtr), true},
|
||||
{new(IntPtr), new(*int), true},
|
||||
{new(IntPtr), new(IntPtr1), false},
|
||||
{new(Ch), new(<-chan any), true},
|
||||
// test runs implementsTests too
|
||||
}
|
||||
|
||||
//var assignableTests = []struct {
|
||||
// x any
|
||||
// t any
|
||||
// b bool
|
||||
//}{
|
||||
// {new(chan int), new(<-chan int), true},
|
||||
// {new(<-chan int), new(chan int), false},
|
||||
// {new(*int), new(IntPtr), true},
|
||||
// {new(IntPtr), new(*int), true},
|
||||
// {new(IntPtr), new(IntPtr1), false},
|
||||
// {new(Ch), new(<-chan any), true},
|
||||
// // test runs implementsTests too
|
||||
//}
|
||||
//
|
||||
//type IntPtr *int
|
||||
//type IntPtr1 *int
|
||||
//type Ch <-chan any
|
||||
//
|
||||
//func TestAssignableTo(t *testing.T) {
|
||||
// for _, tt := range append(assignableTests, implementsTests...) {
|
||||
// xv := TypeOf(tt.x).Elem()
|
||||
// xt := TypeOf(tt.t).Elem()
|
||||
// if b := xv.AssignableTo(xt); b != tt.b {
|
||||
// t.Errorf("(%s).AssignableTo(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
type IntPtr *int
|
||||
type IntPtr1 *int
|
||||
type Ch <-chan any
|
||||
|
||||
func TestAssignableTo(t *testing.T) {
|
||||
for _, tt := range append(assignableTests, implementsTests...) {
|
||||
xv := TypeOf(tt.x).Elem()
|
||||
xt := TypeOf(tt.t).Elem()
|
||||
if b := xv.AssignableTo(xt); b != tt.b {
|
||||
t.Errorf("(%s).AssignableTo(%s) = %v, want %v", xv.String(), xt.String(), b, tt.b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
-6
@@ -972,17 +972,52 @@ func (t *rawType) FieldAlign() int {
|
||||
// AssignableTo returns whether a value of type t can be assigned to a variable
|
||||
// of type u.
|
||||
func (t *rawType) AssignableTo(u Type) bool {
|
||||
if t == u.(*rawType) {
|
||||
return true
|
||||
}
|
||||
|
||||
if u.Kind() == Interface && u.NumMethod() == 0 {
|
||||
// Quotes come from the language spec:
|
||||
// https://go.dev/ref/spec#Assignability
|
||||
// > A value x of type V is assignable to a variable of type T ("x is
|
||||
// > assignable to T") if one of the following conditions applies:
|
||||
// [...]
|
||||
// (Replace T with t, and x with u).
|
||||
u_raw := u.(*rawType)
|
||||
if t == u_raw {
|
||||
// > V and T are identical.
|
||||
return true
|
||||
}
|
||||
|
||||
if u.Kind() == Interface {
|
||||
panic("reflect: unimplemented: AssignableTo with interface")
|
||||
// > T is an interface type, but not a type parameter, and x implements
|
||||
// > T.
|
||||
u_itf := (*interfaceType)(unsafe.Pointer(u_raw.underlying()))
|
||||
res := typeImplementsMethodSet(unsafe.Pointer(t), unsafe.Pointer(&u_itf.methods))
|
||||
return res
|
||||
}
|
||||
|
||||
t_named := t.isNamed()
|
||||
u_named := u_raw.isNamed()
|
||||
if t_named && u_named {
|
||||
return false
|
||||
}
|
||||
if t.underlying() == u_raw.underlying() {
|
||||
// > V and T have identical underlying types but are not type parameters
|
||||
// > and at least one of V or T is not a named type.
|
||||
return true
|
||||
}
|
||||
|
||||
if t.Kind() == Chan && u_raw.Kind() == Chan {
|
||||
// > V and T are channel types with identical element types, V is a
|
||||
// > bidirectional channel, and at least one of V or T is not a named
|
||||
// > type.
|
||||
t_chan := (*elemType)(unsafe.Pointer(t.underlying()))
|
||||
u_chan := (*elemType)(unsafe.Pointer(u_raw.underlying()))
|
||||
if t_chan.elem != u_chan.elem {
|
||||
return false
|
||||
}
|
||||
if t_chan.ChanDir() != BothDir {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -592,15 +592,6 @@ func TestTinyNumMethods(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssignableTo(t *testing.T) {
|
||||
var a any
|
||||
refa := ValueOf(&a).Elem()
|
||||
refa.Set(ValueOf(4))
|
||||
if got, want := refa.Interface().(int), 4; got != want {
|
||||
t.Errorf("AssignableTo / Set failed, got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
v := ValueOf(int64(3))
|
||||
c := v.Convert(TypeOf(byte(0)))
|
||||
|
||||
Reference in New Issue
Block a user