-
Notifications
You must be signed in to change notification settings - Fork 18k
reflect: inconsistent results between reflection and non-reflection #29469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@ianlancetaylor same problem for gccgo. |
It looks, Go spec really doesn't cover the error conversion cases. |
I think the restrictions are unnecessary. After all, the restricted conversions can be achieved in indirect ways. package main
func main() {
type C chan int
type C1 chan<- int
type C2 <-chan int
var c C
//_ = C1(c) // error:
//_ = C2(c) // error:
_ = C1(chan<- int(c)) // ok
_ = C2((<-chan int)(c)) // ok
} |
I'm not sure I understand why the conversions |
The conversions The conversions via I don't know why reflect's As is, there are no |
I tend to think this is a bug of the package main
func main() {
type MyInt int
type IntPtr *int
type MyIntPtr *MyInt
var pi = new(int)
var ip IntPtr = pi
// var _ = MyIntPtr(ip) // can't convert directly
var _ = MyIntPtr((*MyInt)((*int)(ip))) // can indirectly
} |
@go101 We know that indirect conversions are allowed in the language. But the issue remains as to why direct conversions which are invalid in the language do work via reflection. |
It looks the func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
...
// Composite types.
switch kind {
...
case Chan:
// Special case:
// x is a bidirectional channel value, T is a channel type,
// and x's type V and T have identical element types.
if V.ChanDir() == BothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
return true // !!! here is wrong. Need check whether or not one is non-defined.
}
// Otherwise continue test for identical underlying type.
return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) |
package main
import "reflect"
var _ = reflect.ValueOf
func main() {
type C chan int
type C1 chan<- int
type C2 <-chan int
var c C
var c1b C1
var c2b C2
var t = reflect.TypeOf(c)
var tc1b = reflect.TypeOf(c1b)
var tc2b = reflect.TypeOf(c2b)
println(t.ConvertibleTo(tc1b)) // true
println(t.ConvertibleTo(tc2b)) // true
println(tc1b.ConvertibleTo(t)) // false
println(tc2b.ConvertibleTo(t)) // false
} |
sorry, looks my last comment is a shit. :) |
Another bug: package main
import "reflect"
func main() {
type C chan int
var x *C
var y *chan<- int
//y = x // error
//x = y // error
//y = (*chan<- int)(x) // error
//x = (*C)(y) // error
println(reflect.TypeOf(x).AssignableTo(reflect.TypeOf(y))) // false
println(reflect.TypeOf(y).AssignableTo(reflect.TypeOf(x))) // false
println(reflect.TypeOf(x).ConvertibleTo(reflect.TypeOf(y))) // true (bug)
println(reflect.TypeOf(y).ConvertibleTo(reflect.TypeOf(x))) // false
} |
The cause of the new bug is the functionality of the |
Change https://golang.org/cl/157822 mentions this issue: |
What version of Go are you using (
go version
)?go version go1.11.3 linux/amd64
Does this issue reproduce with the latest release?
yes
What did you do?
Another bug is mentioned a below comment: #29469 (comment)
The text was updated successfully, but these errors were encountered: