Code change:
pub fn normal_test_fn() { #[expect(unused_mut, reason = "this expectation will create a diagnostic with the default lint level")] //~^ WARNING this lint expectation is unfulfilled <ins> //~| WARNING this lint expectation is unfulfilled </ins> //~| NOTE this expectation will create a diagnostic with the default lint level <ins> //~| NOTE this expectation will create a diagnostic with the default lint level //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` </ins> let mut v = vec![1, 1, 2, 3, 5]; v.sort(); // Check that lint lists including `unfulfilled_lint_expectations` are also handled correctly #[expect(unused, unfulfilled_lint_expectations, reason = "the expectation for `unused` should be fulfilled")] //~^ WARNING this lint expectation is unfulfilled <ins> //~| WARNING this lint expectation is unfulfilled //~| NOTE the expectation for `unused` should be fulfilled </ins> //~| NOTE the expectation for `unused` should be fulfilled //~| NOTE the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message <ins> //~| NOTE the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message //~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` </ins> let value = "I'm unused"; }

Related discussion:
text: I tried this code: I expected to catch lint and suppress it, as it should. Instead, compiler issues a diagnostic both about unused value and unfulfilled lint expectation: It does work as expected though if is applied to function. I used the latest stable (Rust 1.81), but it is reproducible both on latest beta (2024-09-04 ) and latest nightly (2024-09-05 ). labels: +F-lintreasons, +A-diagnostics <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
This issue is not limited to just . Others attrs like or don't work either. For instance, the following variant of the reproducer with replaced with emits the warning even though it shouldn't: Playground: This broken behaviour goes as far back as at least 2021 (couldn't build and test earlier rustc) We emit the lint on the HIR node corresponding to . However, the or levels, which are supposed to override the default level of the lint, are associated with or bound to the node underlying the as shown in the figure below: The end result is that the lint's level is never knocked down to or since when searching for levels we start from the node on which the lint is triggered and go up the chain of parents. So in this case we look for the level on and then on the and so on. We never look for it on the where the levels actually exist. As it happens in the lowered HIR does have the / attrs for both the node and its child node. However when adding the levels in the we do not add anything for the node as shown here (note the comment): If were to add the level for as well the issue will go away. However, if we do that we will still have one problem in the case of which is that we will end up with two expectations and the one on the will not be fullfilled and hence we will still see a warning about unfulfilled expectation. To prevent that I think we should take the following approach: when an attr like or etc.