The constraint comparable is predeclared and supported by the language specifications. You can't "manually" make a type implement it. The documentation is available in the specs (under Type Constraints):
The predeclared interface type comparable denotes the set of all concrete (non-interface) types that are comparable. Specifically, a type T implements comparable if:
T is not an interface type and T supports the operations == and !=; or
T is an interface type and each type in T's type set implements comparable.
Your type Vector[T comparable] doesn't meet any of those conditions. It is not an interface type, and it does not otherwise support the equality operations, because one of its fields data_ []T is not comparable due to being a slice — even if element type is constrained by comparable.
The purpose of the comparable constraint is really just to allow writing generic code with == and != operators. If a type is not comparable by design, you can't write such code. That would be true even if Vector didn't have a type parameter.
If your goal is instantiating Vector[Vector[T]] and allow equality tests between instances of Vector[T], you might want to add an Equal method that takes care of this specific use case — only vectors instantiated with the same type parameter as the receiver will be allowed:
func (v *Vector[T]) Equal(e Vector[T]) bool {
// test equality in a way that makes sense for this type
}
Worth mentioning that there is a way to make Vector[T comparable] comparable itself, i.e. change the data_ field to be a pointer-to-slice:
type Vector[T comparable] struct {
data_ *[]T
}
Now instantiation with Vector[Vector[int]] compiles. However, beside being very cumbersome to initialize with struct literals (playground), it comes with all caveats of pointer comparison. More specifically:
Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
Now the comparison x == e tests that the memory address stored in the data_ field in x and e is the same. This might skew the semantics of comparing two Vector[T] instances — is it correct to say that two vector instances are equal if they hold a reference to the same slice? Maybe. It depends on the assumptions your program wants to make. Personally, I don't think this is actually better than having a separate Equal method and/or redesigning your data types, but as usual, YMMV.
Note also that if you instantiate as Vector[float64] and compare NaN values, the comparison will be false.