@@ -955,3 +955,123 @@ func detectGlobal() {
955955 print (globalVar )
956956 }
957957}
958+
959+ func detectSinkType () {
960+ // Call argument context.
961+ _ = acceptReader (newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
962+ _ = acceptReader (newIface ("sink is io.Reader" ).(io.Reader )) // want `true`
963+ _ = acceptReader ((newIface ("sink is io.Reader" ).(io.Reader ))) // want `true`
964+ _ = acceptBuffer (newIface ("sink is io.Reader" ).(* bytes.Buffer ))
965+ _ = acceptReaderVariadic (10 , newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
966+ _ = acceptReaderVariadic (10 , newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
967+ _ = acceptReaderVariadic (10 , nil , newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
968+ _ = acceptReaderVariadic (10 , newIface ("sink is io.Reader" ).([]io.Reader )... )
969+ _ = acceptWriterVariadic (10 , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
970+ _ = acceptWriterVariadic (10 , nil , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
971+ _ = acceptWriterVariadic (10 , nil , nil , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
972+ _ = acceptVariadic (10 , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
973+ _ = acceptVariadic (10 , nil , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
974+ _ = acceptVariadic (10 , nil , nil , newIface ("sink is io.Reader" ).(* bytes.Buffer ))
975+ fmt .Println (newIface ("sink is interface{}" ).(int )) // want `true`
976+ fmt .Println (1 , newIface ("sink is interface{}" ).(io.Reader )) // want `true`
977+
978+ // Type conversion context.
979+ _ = io .Reader (newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
980+ _ = io .Writer (newIface ("sink is io.Reader" ).(* bytes.Buffer ))
981+
982+ // Return stmt context.
983+ {
984+ _ = func () (io.Reader , io.Writer ) {
985+ return newIface ("sink is io.Reader" ).(* bytes.Buffer ), nil // want `true`
986+ }
987+ _ = func () (io.Reader , io.Writer ) {
988+ return nil , newIface ("sink is io.Reader" ).(* bytes.Buffer )
989+ }
990+ _ = func () (io.Writer , io.Reader ) {
991+ return nil , newIface ("sink is io.Reader" ).(* bytes.Buffer ) // want `true`
992+ }
993+ }
994+
995+ // Assignment context.
996+ {
997+ var r io.Reader = (newIface ("sink is io.Reader" ).(* bytes.Buffer )) // want `true`
998+ var _ io.Reader = newIface ("sink is io.Reader" ).(* bytes.Buffer ) // want `true`
999+ var w io.Writer = newIface ("sink is io.Reader" ).(* bytes.Buffer )
1000+ x := newIface ("sink is io.Reader" ).(* bytes.Buffer )
1001+ _ = r
1002+ _ = w
1003+ _ = x
1004+ var readers map [string ]io.Reader
1005+ readers ["foo" ] = newIface ("sink is io.Reader" ).(* bytes.Buffer ) // want `true`
1006+ var writers map [string ]io.Writer
1007+ writers ["foo" ] = newIface ("sink is io.Reader" ).(* bytes.Buffer )
1008+ var foo exampleStruct
1009+ foo .r = newIface ("sink is io.Reader" ).(* bytes.Buffer ) // want `true`
1010+ foo .buf = newIface ("sink is io.Reader" ).(* bytes.Buffer )
1011+ foo .w = newIface ("sink is io.Reader" ).(* bytes.Buffer )
1012+ }
1013+
1014+ // Index expr context
1015+ {
1016+ var readerKeys map [io.Reader ]string
1017+ readerKeys [newIface ("sink is io.Reader" ).(* bytes.Buffer )] = "ok" // want `true`
1018+ readerKeys [(newIface ("sink is io.Reader" ).(* bytes.Buffer ))] = "ok" // want `true`
1019+ var writerKeys map [io.Writer ]string
1020+ writerKeys [newIface ("sink is io.Reader" ).(* bytes.Buffer )] = "ok"
1021+ writerKeys [(newIface ("sink is io.Reader" ).(* bytes.Buffer ))] = "ok"
1022+ }
1023+
1024+ // Composite lit element context.
1025+ _ = []io.Reader {
1026+ newIface ("sink is io.Reader" ).(* bytes.Buffer ), // want `true`
1027+ }
1028+ _ = []io.Reader {
1029+ 10 : newIface ("sink is io.Reader" ).(* bytes.Buffer ), // want `true`
1030+ }
1031+ _ = [10 ]io.Reader {
1032+ 4 : newIface ("sink is io.Reader" ).(* bytes.Buffer ), // want `true`
1033+ }
1034+ _ = map [string ]io.Reader {
1035+ "foo" : newIface ("sink is io.Reader" ).(* bytes.Buffer ), // want `true`
1036+ }
1037+ _ = map [io.Reader ]string {
1038+ newIface ("sink is io.Reader" ).(* bytes.Buffer ): "foo" , // want `true`
1039+ }
1040+ _ = map [io.Reader ]string {
1041+ (newIface ("sink is io.Reader" ).(* bytes.Buffer )): "foo" , // want `true`
1042+ }
1043+ _ = []io.Writer {
1044+ (newIface ("sink is io.Reader" ).(* bytes.Buffer )),
1045+ }
1046+ _ = exampleStruct {
1047+ w : newIface ("sink is io.Reader" ).(* bytes.Buffer ),
1048+ r : newIface ("sink is io.Reader" ).(* bytes.Buffer ), // want `true`
1049+ }
1050+ _ = []interface {}{
1051+ newIface ("sink is interface{}" ).(* bytes.Buffer ), // want `true`
1052+ newIface ("sink is interface{}" ).(int ), // want `true`
1053+ }
1054+ }
1055+
1056+ func detectSinkType2 () io.Reader {
1057+ return newIface ("sink is io.Reader" ).(* bytes.Buffer ) // want `true`
1058+ }
1059+
1060+ func detectSinkType3 () io.Writer {
1061+ return newIface ("sink is io.Reader" ).(* bytes.Buffer )
1062+ }
1063+
1064+ func newIface (key string ) interface {} { return nil }
1065+
1066+ func acceptReaderVariadic (a int , r ... io.Reader ) int { return 0 }
1067+ func acceptWriterVariadic (a int , r ... io.Writer ) int { return 0 }
1068+ func acceptVariadic (a int , r ... interface {}) int { return 0 }
1069+ func acceptReader (r io.Reader ) int { return 0 }
1070+ func acceptWriter (r io.Writer ) int { return 0 }
1071+ func acceptBuffer (b * bytes.Buffer ) int { return 0 }
1072+
1073+ type exampleStruct struct {
1074+ r io.Reader
1075+ w io.Writer
1076+ buf * bytes.Buffer
1077+ }
0 commit comments