-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
cmd/vet: printf: warn about verbs that don’t match a type parameter’s type set #49038
Comments
There are two possible ways to extend the printf(format, arg) check for generics:
So for example if you have a constraint int|string and format %d, then It sounds like you are suggesting (1). Does anyone object to (1)? |
Also, we may find that (2) is better by trying (1) and realizing we are getting too many errors. |
This proposal has been added to the active column of the proposals project |
@rsc yes we're suggesting (1). It's worth pointing out that when there no structural restrictions (such as with |
I did not see where the proposal states this explicitly or not so I'm going to just ask. Do we need to take the method set into account for some of the verbs? Stealing an example from https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md :
It seems like this should never complain about "%s". Maybe "%w" also needs to take this into account? Any other verbs? |
|
Generally speaking, we will have already taken the method set into account before we get to checking underlying types. Checks for whether or not a type is a formatter or stringer or error will have used |
Based on the discussion above, this proposal seems like a likely accept. |
Change https://golang.org/cl/351832 mentions this issue: |
No change in consensus, so accepted. 🎉 |
parameter’s type set Pending the acceptance of golang/go#49038, this CL updates the printf analyzer to warn if any elements of a type parameter's type set do not match the printf verb being considered. Since this may be a source of confusion, it also refactors slightly to allow providing a reason why a match failed. Updates golang/go#48704 Updates golang/go#49038 Change-Id: I92d4d58dd0e9218ae9d522bf2a2999f4c6f9fd84 Reviewed-on: https://go-review.googlesource.com/c/tools/+/351832 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> Reviewed-by: Tim King <taking@google.com> TryBot-Result: Go Bot <gobot@golang.org>
Whoops, forgot to close this. This is done. |
As a spin-off of the discussion in #48971, I propose to have
cmd/vet
report diagnostics for printf verbs that don’t match every element of a type parameter’s type set.For example, consider the following:
In this example, the type set of
P
is all types withint
underlying. There are types in that type set (such asint
itself) that do not match the verb%s
, so we would report a diagnostic – something likefmt.Printf format %s does not match type int in the underlying type set for P
.Similarly, the type set of
Q
is all types, and there are of course many types in this type set that do not match%d
, so we would report something likefmt.Printf format %d does not match constraint type ‘any’
.In these examples we might have false positives: it could be the case that
F
is only ever instantiated with arguments implementingfmt.Stringer
. It could be the case thatG
is only ever instantiated with integral types. By comparison, we explicitly do not report such diagnostics for most arguments of interface type:However, with the new interface syntax in Go 1.18, we are able to express restrictions on both the method set and underlying type of a type parameter. If arguments of type parameter type are being passed to a
%d
verb, we can prove that this is OK if the type set is restricted to integral underlying types. On the other hand, if the type set is not restricted to integral underlying types, it is highly likely that this is a user error. Specifically, it is more likely than in the case of interface types, because users could have specified structural restrictions on the type parameter.There is precedent here. In the initial implementation of printf checks for
%w
, it was decided that all arguments must be convertible toerror
(including, for example, arguments of typeinterface{}
). The rationale behind this is similar to above: the user is able to express an ‘implements’ relationship between interface types, and if they did not it is likely a user error. [see also #48931].Generics will be used to add type safety to existing code that previously used interfaces. By flagging potentially incorrect printf verbs, we can help users identify potential runtime errors and add accurate type restrictions to their type parameter constraints.
I have prototyped this feature, and think it is do-able for 1.18, though producing great diagnostic messages might be a bit tricky. I think it’s OK if we wait for 1.19.
CC @timothy-king @neild @bcmills @mvdan
The text was updated successfully, but these errors were encountered: