package gorules
import "github.com/quasilyte/go-ruleguard/dsl"
// Type filters make it possible to reject matches based on the submatch expr types.
func copyStringToBytes(m dsl.Matcher) {
	// It's not necessary to do a string->[]byte conversion for the copy() argument
	// when copying a string into []byte. In this rule, we require that $s is string-typed.
	m.Match(`copy($b, []byte($s))`).
		Where(m["s"].Type.Is(`string`)).
		Suggest(`copy($b, $s)`)
}
func sprintStringer(m dsl.Matcher) {
	// Instead of calling fmt.Sprint on a value that implements fmt.Stringer,
	// we can call its String() method directly. In order to report such cases,
	// it's necessary to assert that $x is something that implements that interface.
	m.Match(`fmt.Sprint($x)`).
		Where(m["x"].Type.Implements(`fmt.Stringer`)).
		Suggest(`$x.String()`)
}
package main
import "fmt"
type myStringer struct{}
func (myStringer) String() string { return "example" }
func main() {
	var s string
	var b []byte
	var stringer myStringer
	copy(b, []byte(s)) // Excessive conversion
	copy(b, s)         // Neat, no excessive conversion here
	println(fmt.Sprint(myStringer{}))
	println(fmt.Sprint(stringer))
	println(stringer.String()) // Good
}
Notes:
int16) and qualified types from the stdlib (e.g. io.Reader)