Skip to content
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

#[deprecated] does nothing if placed on an impl item. #39935

Open
sgrif opened this issue Feb 18, 2017 · 8 comments
Open

#[deprecated] does nothing if placed on an impl item. #39935

sgrif opened this issue Feb 18, 2017 · 8 comments
Labels
A-stability Area: `#[stable]`, `#[unstable]` etc. C-bug Category: This is a bug.

Comments

@sgrif
Copy link
Contributor

sgrif commented Feb 18, 2017

Given the following two crates:

#![crate_name = "foo"]

pub struct Foo;
pub struct Bar;

pub trait IntoBar {
    fn into_bar(self) -> Bar;
}

#[deprecated(note = "Just pass `Bar` instead")]
impl IntoBar for Foo {
    fn into_bar(self) -> Bar {
        Bar
    }
}
extern crate foo;

use foo::*;

fn main() {
    let _ = Foo.into_bar();
}

I would expect the second crate to see a deprecation warning on the use of Foo.into_bar(). Instead, both crates compile successfully with no errors. I think that allowing deprecations on impls is a useful option to provide to authors (one that I was looking to do, and found this while seeing if it would work). However, if we do not wish to provide that ability to library authors, placing the #[deprecated] attribute on an impl should result in a compiler error.

@alexcrichton
Copy link
Member

This is unfortunately a limitation of stability today, it just doesn't work at all with trait impls. (we run into this all the time in libstd as well)

@Mark-Simulacrum Mark-Simulacrum added the A-stability Area: `#[stable]`, `#[unstable]` etc. label May 23, 2017
quodlibetor added a commit to quodlibetor/rust-chrono that referenced this issue Jul 9, 2017
Unfortunately due to rust-lang/rust#39935 placing the annotation on the `impl`s
of `Encodable`/`Decodable` for the various items have no effect whatsoever, so
we need to place it on some type that chrono actually uses internally. The only
*type* that I can find that only exists for rustc-serialize only is the
 `TsSeconds` struct.

So, marking TsSeconds deprecated causes Chrono's internal uses of `TsSeconds`
to emit deprecation warnings, both in our builds and for packages that specify
Chrono as a dependency with the `rustc-serialize` feature active. This means
that the current commit will cause a `warning: use of deprecated item:
RustcSerialize will be removed before chrono 1.0, use Serde instead` to appear
in `cargo build` output.

Unfortunately I don't think that it's possible for downstream crates to disable
the warning the warning in any way other than actually switching to Serde or
using an older chrono. That's the reason for all the `#[allow(deprecated)]`
through the code, it means that the warning appears almost exactly once,
instead of dozens of times.
@Mark-Simulacrum Mark-Simulacrum added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 27, 2017
quodlibetor added a commit to quodlibetor/rust-chrono that referenced this issue Mar 28, 2018
Unfortunately due to rust-lang/rust#39935 placing the annotation on the `impl`s
of `Encodable`/`Decodable` for the various items have no effect whatsoever, so
we need to place it on some type that chrono actually uses internally. The only
*type* that I can find that only exists for rustc-serialize only is the
 `TsSeconds` struct.

So, marking TsSeconds deprecated causes Chrono's internal uses of `TsSeconds`
to emit deprecation warnings, both in our builds and for packages that specify
Chrono as a dependency with the `rustc-serialize` feature active. This means
that the current commit will cause a `warning: use of deprecated item:
RustcSerialize will be removed before chrono 1.0, use Serde instead` to appear
in `cargo build` output.

Unfortunately I don't think that it's possible for downstream crates to disable
the warning the warning in any way other than actually switching to Serde or
using an older chrono. That's the reason for all the `#[allow(deprecated)]`
through the code, it means that the warning appears almost exactly once,
instead of dozens of times.
quodlibetor added a commit to quodlibetor/rust-chrono that referenced this issue Mar 28, 2018
Unfortunately due to rust-lang/rust#39935 placing the annotation on the `impl`s
of `Encodable`/`Decodable` for the various items have no effect whatsoever, so
we need to place it on some type that chrono actually uses internally. The only
*type* that I can find that only exists for rustc-serialize only is the
 `TsSeconds` struct.

So, marking TsSeconds deprecated causes Chrono's internal uses of `TsSeconds`
to emit deprecation warnings, both in our builds and for packages that specify
Chrono as a dependency with the `rustc-serialize` feature active. This means
that the current commit will cause a `warning: use of deprecated item:
RustcSerialize will be removed before chrono 1.0, use Serde instead` to appear
in `cargo build` output.

Unfortunately I don't think that it's possible for downstream crates to disable
the warning the warning in any way other than actually switching to Serde or
using an older chrono. That's the reason for all the `#[allow(deprecated)]`
through the code, it means that the warning appears almost exactly once,
instead of dozens of times.
quodlibetor added a commit to quodlibetor/rust-chrono that referenced this issue Apr 1, 2018
Unfortunately due to rust-lang/rust#39935 placing the annotation on the `impl`s
of `Encodable`/`Decodable` for the various items have no effect whatsoever, so
we need to place it on some type that chrono actually uses internally. The only
*type* that I can find that only exists for rustc-serialize only is the
 `TsSeconds` struct.

So, marking TsSeconds deprecated causes Chrono's internal uses of `TsSeconds`
to emit deprecation warnings, both in our builds and for packages that specify
Chrono as a dependency with the `rustc-serialize` feature active. This means
that the current commit will cause a `warning: use of deprecated item:
RustcSerialize will be removed before chrono 1.0, use Serde instead` to appear
in `cargo build` output.

Unfortunately I don't think that it's possible for downstream crates to disable
the warning the warning in any way other than actually switching to Serde or
using an older chrono. That's the reason for all the `#[allow(deprecated)]`
through the code, it means that the warning appears almost exactly once,
instead of dozens of times.
@abonander
Copy link
Contributor

@alexcrichton Do we want to support stability on trait impls or not? I remember this being discussed elsewhere but I don't remember the conclusion.

@alexcrichton
Copy link
Member

It'd be nice yeah! At this point everyone just assumes it doesn't work, so there's likely lots of misannotated impls or unintended fallout from a "bugfix" change like this, but it'd be good to implement if possible!

@sgrif
Copy link
Contributor Author

sgrif commented Sep 10, 2018

I still think we should at least make this a compiler error until we can make it work. I disagree with the "everyone assumes it doesn't work" take, I think folks do assume it works, and never verify if their users are receiving a warning or not.

@mzabaluev
Copy link
Contributor

I still think we should at least make this a compiler error until we can make it work.

A warning would be a gentler option. I agree that it's not good to let people put the deprecation attribute on and assume it will work.

@camsteffen
Copy link
Contributor

I'm surprised this hasn't received more attention. It seems like a rather common occurrence that a library will have a type that implements a trait and you want to remove it but there is no way to direct users away from using the impl Trait. For instance, I have a type that implements Iterator, but I want to change it to instead have an fn iter().

@ordian
Copy link

ordian commented Jan 4, 2021

#78626 turned this into a compile error.

rotty added a commit to rotty/lexpr-rs that referenced this issue Jan 9, 2021
Unfortunately, deprecation annotations on trait `ìmpl` blocks are
ignored by the compiler (see
<rust-lang/rust#39935>).
rotty added a commit to rotty/lexpr-rs that referenced this issue Jan 9, 2021
Unfortunately, deprecation annotations on trait `ìmpl` blocks are
ignored by the compiler (see
<rust-lang/rust#39935>).
rotty added a commit to rotty/lexpr-rs that referenced this issue Jan 9, 2021
Unfortunately, deprecation annotations on trait `ìmpl` blocks are
ignored by the compiler (see
<rust-lang/rust#39935>).
@Dylan-DPC Dylan-DPC added C-bug Category: This is a bug. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Nov 27, 2023
@RodBurman
Copy link

Given the current stable release:

cargo -V -v
cargo 1.82.0 (8f40fc59f 2024-08-21)
release: 1.82.0
commit-hash: 8f40fc59fb0c8df91c97405785197f3c630304ea
commit-date: 2024-08-21
host: aarch64-apple-darwin
libgit2: 1.8.1 (sys:0.19.0 vendored)
libcurl: 8.7.1 (sys:0.4.74+curl-8.9.0 system ssl:(SecureTransport) LibreSSL/3.3.6)
ssl: OpenSSL 1.1.1w 11 Sep 2023
os: Mac OS 15.0.1 [64-bit]

Then I am at least told that the deprecation is not going to work:

cargo build
Compiling foo v0.1.0 (/Users/rod/code/rust/triage/deprec/foo)
error: this #[deprecated] annotation has no effect
--> src/lib.rs:10:1
|
10 | #[deprecated(note = "Just pass Bar instead")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the unnecessary deprecation attribute
|
= note: #[deny(useless_deprecated)] on by default

error: could not compile foo (lib) due to 1 previous error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-stability Area: `#[stable]`, `#[unstable]` etc. C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

9 participants