-
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
reflect: do not deprecate Ptr APIs just yet #48665
Comments
Oh, and CC @dominikh for staticcheck, though I'm still fairly sure that it's correct here. At least as long as deprecation notices don't carry Go version information. |
See previously #38149. |
I'm going to mark this as a release blocker, because some time has passed and I fear it might go under the radar given all that's happening for 1.18. We definitely need to make a choice before 1.18 comes out, and ideally before the first beta is out as well. |
I didn't realize tools would be so aggressive about this. I'm fine tweaking the docs to a pattern recognizable to humans but not to tools for a few releases. Want to send a change? |
We'll need the same for CL 350691 which deprecated |
FWIW, Staticcheck maintains a handwritten mapping of Go identifiers to 1) when they were deprecated 2) when their recommended alternative became available. As such, Staticcheck won't flag uses of a deprecated identifier if the user is targeting an older version of Go. We usually update that mapping close to a Go release (either closely before or closely after...) and make a new release.
Generally speaking, Go has always immediately deprecated things when alternatives became available. io/ioutil is the odd one out here. |
(as an aside, the reflect documentation still mentions Ptr and PtrTo in various places, such as in the documentation of New and UnsafePointer; someone should fix that) |
Change https://golang.org/cl/358454 mentions this issue: |
Updates #47651 Updates #48665 Change-Id: I69a87b45a5cad7a07fbd855040cd9935cf874554 Reviewed-on: https://go-review.googlesource.com/c/go/+/358454 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
I see, I didn't know that. Would there be a way to not issue warnings for deprecations that haven't been released yet?
If that is our policy in a consistent way, then that's fine by me - as long as tools follow it as well. I shouldn't be getting warnings to fix my code before I am able to do so, even if I happen to be developing on tip. |
Now I'm curious what makes ioutil special so that we should wait a few releases to deprecate it. |
A way for users right now? No. A way for me to change Staticcheck to behave that way? Trivially.
Hm, seeing these messages, I'm not sure reflect.Ptr should be deprecated, either.
/cc @rsc @ianlancetaylor |
We should remove the // Deprecated here. We don't want tools to complain about perfectly valid code. |
@rsc to be clear, and also don't deprecate |
@cuonglm That is a separate issue, but it does seem reasonable to me. |
Change https://golang.org/cl/359175 mentions this issue: |
Deprecated does not imply the code isn't valid. If a tool is suggesting that, it's a problem with the tool and not with the deprecation mark. |
Here is how Staticcheck handles deprecation, based on an example: package pkg
import (
"io"
"os"
)
func Fn(r io.ReadSeeker) {
r.Seek(0, os.SEEK_SET)
}
Feel free to tell me if you disagree with that behavior. |
I kind of agree, but with the following caveat. The version you pass to |
Or maybe @mvdan should just be using |
Right, if you use the
The problem here is that Staticcheck refers to a list of deprecated objects in the standard library, and if it can't find an entry, falls back to always reporting the deprecation. That means that between Go deprecating something, and us updating the list, Staticcheck will complain about it, even if you were to target Go 1.0. Or, in other words: if we don't know that we shouldn't report it, we'll report it. It seems pretty obvious that this behavior is bad, and we should instead not report it. However, that doesn't answer the following question: should reflect.Ptr get flagged as deprecated when targeting Go 1.18 as the minimum version? There doesn't seem to be consensus on that matter. I believe that traditionally, we've deprecated things the moment an alternative became available. We have broken with that tradition with io/ioutil, and Russ and Ian seem to advocate for not deprecating things that aren't harmful to use. I am, however, worried that Staticcheck being too noisy about deprecations in the past has affected their opinion. |
Thinking out loud. If an identifier is deprecated because it is unsafe or dangerous, then we want that deprecation warning to be issued in all cases. If an identifier is deprecated because we have a newer, cooler, replacement, and the replacement is first available in Go 1.N, then it seems to me that the warning should be issued if compiling for Go 1.N+2. This is because when we are targeting Go 1.N+2, then Go 1.N is no longer supported and it's not so important to ensure that things still work for people using it. This is because writing "go 1.N' in a go.mod file does not mean that only go 1.N is supported. It means that we should use Go 1.N semantics, but in general it may still be OK to build with Go 1.N-1. I'm not sure how to make that work with staticcheck. Separately, perhaps if staticcheck can't get the Go version from a go.mod file, it should use 1.16 (or perhaps 1.11), as that is what cmd/go does (https://go.googlesource.com/go/+/refs/heads/master/src/cmd/go/internal/modload/modfile.go#84). |
Staticcheck actually does do that for some deprecated objects, such as insecure cryptographic functions. These will get flagged regardless of the version in which they were deprecated. These are the objects marked with
You're right that Probably related: #30791.
In Staticcheck, we make this the user's responsibility. Instead of us subtracting 2 from the determined version, we expect the user to either use the desired version in their
This will probably become much less of a concern once Go drops support for GOPATH, as all packages will have a |
Fair enough, but we don't want people to start replacing |
Thanks all for the input and solution. Just to double check - are we ending up with clear guidelines on how and when standard library APIs should be deprecated? I would hope so, and that they would be documented somewhere, so we don't end up here again next cycle :) |
I think the guidelines wind up being: if function |
That's fair. Where could we document that for future reference? |
Good point - I've made an edit. Feel free to tweak it as necessary. I reused your wording with a bit of context. |
Thanks. |
In basically all of my modules, I support the two latest major Go versions - right now, this means 1.16 and 1.17.
I develop on Go master, for the sake of helping with testing and developing new features.
In one of the codebases that must still support Go 1.16, I got the following warning from staticcheck:
Staticcheck is right: the type is marked as deprecated.
Unfortunately for me, this is a warning that will be bothering me for six to twelve months before I can fix it.
reflect.Pointer
won't appear until Go 1.18, and I won't drop support for 1.17 until 1.19 comes out.I think the standard library needs to at least wait one major release before formally deprecating APIs.
That is, the earliest we could deprecate
reflect.Ptr
would be in Go 1.19, when the majority of module authors can stop worrying about Go 1.17 and older.Alternatively, to be extra conservative towards module authors who move slowly, we could make the general rule to wait two major releases.
I thought this rule was already common knowledge, as https://go-review.googlesource.com/c/go/+/284777/ was rejected for deprecating
io/ioutil
too early.We seem to have dealt with the reflect API changes differently, though.
Perhaps this means we should write down this general standard library deprecation rule?
Marking as NeedsDecision for 1.18, as making a decision after 1.18 would be a bit late :)
cc @ianlancetaylor @bradfitz @rsc
The text was updated successfully, but these errors were encountered: