Skip to content

Commit 3655153

Browse files
committed
Auto merge of #155596 - jhpratt:rollup-zyXU16X, r=jhpratt
Rollup of 6 pull requests Successful merges: - #155028 (tests: add whitespace tests for vertical tab behavior) - #155582 (Rewrite `FlatMapInPlace`.) - #151194 (Fix wrong suggestion for returning async closure) - #154377 (Fix `#[expect(dead_code)]` liveness propagation) - #155572 (Move diagnostic attribute target checks from check_attr) - #155586 (Ensure we don't feed owners from ast lowering if we ever make that query tracked)
2 parents 93637f3 + b646067 commit 3655153

34 files changed

Lines changed: 836 additions & 293 deletions

compiler/rustc_attr_parsing/src/attributes/diagnostic/do_not_recommend.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1+
use rustc_errors::Diagnostic;
12
use rustc_feature::{AttributeTemplate, template};
3+
use rustc_hir::Target;
24
use rustc_hir::attrs::AttributeKind;
35
use rustc_hir::lints::AttributeLintKind;
4-
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
6+
use rustc_session::lint::builtin::{
7+
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES,
8+
};
59
use rustc_span::{Symbol, sym};
610

711
use crate::attributes::{OnDuplicate, SingleAttributeParser};
812
use crate::context::{AcceptContext, Stage};
13+
use crate::errors::IncorrectDoNotRecommendLocation;
914
use crate::parser::ArgParser;
1015
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
1116

1217
pub(crate) struct DoNotRecommendParser;
1318
impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
1419
const PATH: &[Symbol] = &[sym::diagnostic, sym::do_not_recommend];
1520
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
16-
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); // Checked in check_attr.
21+
// "Allowed" on any target, noop on all but trait impls
22+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
1723
const TEMPLATE: AttributeTemplate = template!(Word /*doesn't matter */);
1824

1925
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
@@ -25,6 +31,19 @@ impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
2531
attr_span,
2632
);
2733
}
34+
35+
if !matches!(cx.target, Target::Impl { of_trait: true }) {
36+
let target_span = cx.target_span;
37+
cx.emit_dyn_lint(
38+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
39+
move |dcx, level| {
40+
IncorrectDoNotRecommendLocation { target_span }.into_diag(dcx, level)
41+
},
42+
attr_span,
43+
);
44+
return None;
45+
}
46+
2847
Some(AttributeKind::DoNotRecommend { attr_span })
2948
}
3049
}

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use rustc_errors::Diagnostic;
12
use rustc_hir::attrs::diagnostic::Directive;
3+
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
24

35
use crate::attributes::diagnostic::*;
46
use crate::attributes::prelude::*;
5-
7+
use crate::errors::DiagnosticOnConstOnlyForTraitImpls;
68
#[derive(Default)]
79
pub(crate) struct OnConstParser {
810
span: Option<Span>,
@@ -21,6 +23,21 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
2123

2224
let span = cx.attr_span;
2325
this.span = Some(span);
26+
27+
// FIXME(mejrs) no constness field on `Target`,
28+
// so non-constness is still checked in check_attr.rs
29+
if !matches!(cx.target, Target::Impl { of_trait: true }) {
30+
let target_span = cx.target_span;
31+
cx.emit_dyn_lint(
32+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
33+
move |dcx, level| {
34+
DiagnosticOnConstOnlyForTraitImpls { target_span }.into_diag(dcx, level)
35+
},
36+
span,
37+
);
38+
return;
39+
}
40+
2441
let mode = Mode::DiagnosticOnConst;
2542

2643
let Some(items) = parse_list(cx, args, mode) else { return };
@@ -32,7 +49,8 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
3249
},
3350
)];
3451

35-
//FIXME Still checked in `check_attr.rs`
52+
// "Allowed" on all targets; noop on anything but non-const trait impls;
53+
// this linted on in parser.
3654
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
3755

3856
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use rustc_errors::Diagnostic;
12
use rustc_feature::template;
23
use rustc_hir::attrs::AttributeKind;
4+
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
35
use rustc_span::sym;
46

57
use crate::attributes::diagnostic::*;
68
use crate::attributes::prelude::*;
79
use crate::context::{AcceptContext, Stage};
10+
use crate::errors::DiagnosticOnMoveOnlyForAdt;
811
use crate::parser::ArgParser;
912
use crate::target_checking::{ALL_TARGETS, AllowedTargets};
1013

@@ -29,6 +32,15 @@ impl OnMoveParser {
2932
let span = cx.attr_span;
3033
self.span = Some(span);
3134

35+
if !matches!(cx.target, Target::Enum | Target::Struct | Target::Union) {
36+
cx.emit_dyn_lint(
37+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
38+
move |dcx, level| DiagnosticOnMoveOnlyForAdt.into_diag(dcx, level),
39+
span,
40+
);
41+
return;
42+
}
43+
3244
let Some(items) = parse_list(cx, args, mode) else { return };
3345

3446
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
@@ -44,6 +56,8 @@ impl<S: Stage> AttributeParser<S> for OnMoveParser {
4456
this.parse(cx, args, Mode::DiagnosticOnMove);
4557
},
4658
)];
59+
60+
// "Allowed" for all targets but noop if used on not-adt.
4761
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
4862

4963
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unimplemented.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use rustc_errors::Diagnostic;
12
use rustc_hir::attrs::diagnostic::Directive;
3+
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
24

35
use crate::attributes::diagnostic::*;
46
use crate::attributes::prelude::*;
7+
use crate::errors::DiagnosticOnUnimplementedOnlyForTraits;
58

69
#[derive(Default)]
710
pub(crate) struct OnUnimplementedParser {
@@ -19,11 +22,12 @@ impl OnUnimplementedParser {
1922
let span = cx.attr_span;
2023
self.span = Some(span);
2124

22-
// If target is not a trait, returning early will make `finalize` emit a
23-
// `AttributeKind::OnUnimplemented {span, directive: None }`, to prevent it being
24-
// accidentally used on non-trait items like trait aliases.
2525
if !matches!(cx.target, Target::Trait) {
26-
// Lint later emitted in check_attr
26+
cx.emit_dyn_lint(
27+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
28+
move |dcx, level| DiagnosticOnUnimplementedOnlyForTraits.into_diag(dcx, level),
29+
span,
30+
);
2731
return;
2832
}
2933

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
use rustc_errors::Diagnostic;
12
use rustc_hir::attrs::diagnostic::Directive;
3+
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
24

5+
use crate::ShouldEmit;
36
use crate::attributes::diagnostic::*;
47
use crate::attributes::prelude::*;
8+
use crate::errors::DiagnosticOnUnknownOnlyForImports;
59

610
#[derive(Default)]
711
pub(crate) struct OnUnknownParser {
@@ -25,6 +29,22 @@ impl OnUnknownParser {
2529
let span = cx.attr_span;
2630
self.span = Some(span);
2731

32+
// At early parsing we get passed `Target::Crate` regardless of the item we're on.
33+
// Only do target checking if we're late.
34+
let early = matches!(cx.stage.should_emit(), ShouldEmit::Nothing);
35+
36+
if !early && !matches!(cx.target, Target::Use) {
37+
let target_span = cx.target_span;
38+
cx.emit_dyn_lint(
39+
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
40+
move |dcx, level| {
41+
DiagnosticOnUnknownOnlyForImports { target_span }.into_diag(dcx, level)
42+
},
43+
span,
44+
);
45+
return;
46+
}
47+
2848
let Some(items) = parse_list(cx, args, mode) else { return };
2949

3050
if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
@@ -41,7 +61,7 @@ impl<S: Stage> AttributeParser<S> for OnUnknownParser {
4161
this.parse(cx, args, Mode::DiagnosticOnUnknown);
4262
},
4363
)];
44-
//FIXME attribute is not parsed for non-use statements but diagnostics are issued in `check_attr.rs`
64+
// "Allowed" for all targets, but noop for all but use statements.
4565
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
4666

4767
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {

compiler/rustc_attr_parsing/src/errors.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,32 @@ pub(crate) struct DocUnknownAny {
252252
#[derive(Diagnostic)]
253253
#[diag("expected boolean for `#[doc(auto_cfg = ...)]`")]
254254
pub(crate) struct DocAutoCfgWrongLiteral;
255+
256+
#[derive(Diagnostic)]
257+
#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait implementations")]
258+
pub(crate) struct DiagnosticOnConstOnlyForTraitImpls {
259+
#[label("not a trait implementation")]
260+
pub target_span: Span,
261+
}
262+
263+
#[derive(Diagnostic)]
264+
#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
265+
pub(crate) struct DiagnosticOnMoveOnlyForAdt;
266+
267+
#[derive(Diagnostic)]
268+
#[diag("`#[diagnostic::on_unimplemented]` can only be applied to trait definitions")]
269+
pub(crate) struct DiagnosticOnUnimplementedOnlyForTraits;
270+
271+
#[derive(Diagnostic)]
272+
#[diag("`#[diagnostic::on_unknown]` can only be applied to `use` statements")]
273+
pub(crate) struct DiagnosticOnUnknownOnlyForImports {
274+
#[label("not an import")]
275+
pub target_span: Span,
276+
}
277+
278+
#[derive(Diagnostic)]
279+
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
280+
pub(crate) struct IncorrectDoNotRecommendLocation {
281+
#[label("not a trait implementation")]
282+
pub target_span: Span,
283+
}

0 commit comments

Comments
 (0)