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

Apply deprecation lint to trait method overrides. #98991

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

m-ou-se
Copy link
Member

@m-ou-se m-ou-se commented Jul 6, 2022

Fixes #98990

Marking this as draft, because it's not completely clear whether #98990 is a bug or intentional.

@m-ou-se m-ou-se added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 6, 2022
@rustbot

This comment was marked as off-topic.

@rust-highfive
Copy link
Collaborator

r? @wesleywiser

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 6, 2022
@m-ou-se m-ou-se marked this pull request as draft July 6, 2022 22:22
@eddyb
Copy link
Member

eddyb commented Jul 7, 2022

I'm not sure what happened here, but the lack of tests for this is worrying (and may explain how this happened, if it was accidental).

self.tcx.check_stability(def_id, None, impl_item_ref.span, None);
self.tcx.check_stability(
def_id,
Some(impl_item_ref.id.hir_id()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm is it possible that all calls take Some now and Option can be removed from around it?

@eddyb
Copy link
Member

eddyb commented Jul 7, 2022

So I was able to backport this on top of 9aaf26e:

diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index f5e18e13465..084b3e19c74 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -558,8 +558,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                         let trait_item_def_id = self.tcx.associated_items(trait_did)
                             .find(|item| item.name == impl_item.name).map(|item| item.def_id);
                         if let Some(def_id) = trait_item_def_id {
-                            // Pass `DUMMY_NODE_ID` to skip deprecation warnings.
-                            self.tcx.check_stability(def_id, ast::DUMMY_NODE_ID, impl_item.span);
+                            self.tcx.check_stability(def_id, impl_item.id, impl_item.span);
                         }
                     }
                 }

And the result is more or less what I was expecting: that would've been a behavior change.
The most immediate outcome is that core stopped building:

(click to open core errors)
error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:147:5
    |
147 |     fn nan() -> f32 {
    |     ^
    |
note: lint level defined here
   --> src/libcore/lib.rs:68:31
    |
68  | #![cfg_attr(not(stage0), deny(warnings))]
    |                               ^^^^^^^^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:152:5
    |
152 |     fn infinity() -> f32 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:157:5
    |
157 |     fn neg_infinity() -> f32 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:162:5
    |
162 |     fn zero() -> f32 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:167:5
    |
167 |     fn neg_zero() -> f32 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:172:5
    |
172 |     fn one() -> f32 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f32.rs:218:5
    |
218 |     fn integer_decode(self) -> (u64, i16, i8) {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:147:5
    |
147 |     fn nan() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:152:5
    |
152 |     fn infinity() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:157:5
    |
157 |     fn neg_infinity() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:162:5
    |
162 |     fn zero() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:167:5
    |
167 |     fn neg_zero() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:172:5
    |
172 |     fn one() -> f64 {
    |     ^

error: use of deprecated item: never really came to fruition and easily implementable outside the standard library
   --> src/libcore/num/f64.rs:218:5
    |
218 |     fn integer_decode(self) -> (u64, i16, i8) {
    |     ^

error: aborting due to 14 previous errors

So even if I did add the comment in that commit, not warning was the existing behavior.
I went to before the PR that commit was from, and I think I found the cause of the behavior:

// For implementations of traits, check the stability of each item
// individually as it's possible to have a stable trait with unstable
// items.
hir::ItemImpl(.., Some(ref t), _, ref impl_item_refs) => {
let trait_did = tcx.expect_def(t.ref_id).def_id();
for impl_item_ref in impl_item_refs {
let impl_item = tcx.map.impl_item(impl_item_ref.id);
let item = tcx.associated_items(trait_did)
.find(|item| item.name == impl_item.name).unwrap();
if warn_about_defns {
maybe_do_stability_check(tcx, item.def_id, impl_item.span, cb);

Note how it's conditional on warn_about_defns - that's the only use of warn_about_defns in the entire function, it only exists to silence diagnostics from associated items.

That function has two calls:

  • stability checks (with true passed to warn_about_defns):
    check_item(self.tcx, item, true,
    &mut |id, sp, stab, depr| self.check(id, sp, stab, depr));
  • deprecation lint (with false passed to warn_about_defns):
    stability::check_item(cx.tcx,
    item,
    false,
    &mut |id, sp, stab, depr| self.lint(cx, id, sp, &stab, &depr));

And going backwards past that, looks like it has remained unchanged in behavior since 0cf2d00 (which introduced stability checks for associated items, but didn't enable deprecation checks for them).

So my understanding is that there was an assumed asymmetry:

  • stability always matters, whether it's using or defining/implementing something
  • deprecation is use-oriented: calling a deprecated trait method warns, but including it in an implementation doesn't (since you're just providing it, to potential users)
    • if we still want to keep this logic we could gate it on whether there's a default (and maybe even give a better message) - after all, there's no way around specifying a non-defaulted method

@bors
Copy link
Contributor

bors commented Sep 26, 2022

☔ The latest upstream changes (presumably #102051) made this pull request unmergeable. Please resolve the merge conflicts.

@jackh726 jackh726 added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Feb 10, 2023
@Noratrieb Noratrieb removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

#[deprecated] lint doesn't trigger when overriding deprecated method
8 participants