Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
faa7966
fix #[expect(dead_code)] liveness propagation
mu001999 Mar 25, 2026
821d9b2
tests: add whitespace tests for vertical tab behavior
Brace1000 Apr 9, 2026
1609baf
tests: add ignore-tidy-tab directive to whitespace tests
Brace1000 Apr 9, 2026
7c00dc2
tests: expand vertical tab lexer test to cover all Pattern_White_Spac…
Brace1000 Apr 11, 2026
1546b1d
tests: add whitespace/ README entry explaining lexer vs stdlib mismatch
Brace1000 Apr 11, 2026
5b487fc
Update ascii_whitespace_excludes_vertical_tab.rs
Brace1000 Apr 9, 2026
91fd464
Update ascii_whitespace_excludes_vertical_tab.rs
Brace1000 Apr 9, 2026
874a618
Update ascii_whitespace_excludes_vertical_tab.rs
Brace1000 Apr 9, 2026
b727680
fix tidy: add whitespace README entry
Brace1000 Apr 9, 2026
52f1d1e
Update README.md with missing full stop
Brace1000 Apr 9, 2026
c5aea24
Update ascii_whitespace_excludes_vertical_tab.rs
Brace1000 Apr 9, 2026
f219e91
fix tidy: use full path format for whitespace README entry
Brace1000 Apr 11, 2026
87fcb28
fix tidy: README order, trailing newlines in whitespace tests
Brace1000 Apr 11, 2026
47fb045
fix: add run-pass directive and restore embedded whitespace bytes
Brace1000 Apr 11, 2026
f06914b
fix tidy: remove duplicate whitespace README entry
Brace1000 Apr 11, 2026
7027a64
Brace1000 Apr 14, 2026
4d8a428
git add tests/ui/whitespace/invalid_whitespace.rs
Brace1000 Apr 14, 2026
93b13d3
Fix tidy: add trailing newline
Brace1000 Apr 14, 2026
7e47ea6
Update invalid_whitespace.rs
Brace1000 Apr 14, 2026
00a37bb
Update invalid_whitespace.rs
Brace1000 Apr 14, 2026
a2e128a
Clean up whitespace in invalid_whitespace.rs
Brace1000 Apr 14, 2026
233f744
Update invalid_whitespace.rs
Brace1000 Apr 14, 2026
b32995b
Clarify ZERO WIDTH SPACE usage in test
Brace1000 Apr 14, 2026
ead2b71
Improve error messages for invalid whitespace
Brace1000 Apr 14, 2026
d0bc9e4
Modify invalid_whitespace test for clarity
Brace1000 Apr 14, 2026
2f981ce
Resolve unknown token error in invalid_whitespace.rs
Brace1000 Apr 14, 2026
3d1ad29
Remove invisible character from variable assignment
Brace1000 Apr 14, 2026
2506ce4
Improve error message for invalid whitespace
Brace1000 Apr 14, 2026
f1eb5e7
Improve error handling for invisible characters
Brace1000 Apr 14, 2026
16b2655
Document error for unknown token due to whitespace
Brace1000 Apr 14, 2026
701bc97
Update error message for invalid whitespace handling
Brace1000 Apr 14, 2026
ece7316
Modify invalid_whitespace.rs for whitespace checks
Brace1000 Apr 14, 2026
a1eb231
Correct whitespace in variable declaration
Brace1000 Apr 14, 2026
6e459b9
Update error message for invalid whitespace
Brace1000 Apr 14, 2026
dc0d44a
Update invalid_whitespace.stderr
Brace1000 Apr 14, 2026
5661524
Refine error handling for invalid whitespace test
Brace1000 Apr 14, 2026
523f70a
Update invalid_whitespace.rs
Brace1000 Apr 14, 2026
1db9763
Fix whitespace issues in invalid_whitespace.rs
Brace1000 Apr 14, 2026
52225e6
Update invalid_whitespace.stderr file
Brace1000 Apr 15, 2026
185a582
Clean up whitespace in invalid_whitespace.rs
Brace1000 Apr 15, 2026
43f045c
Update invalid_whitespace.stderr
Brace1000 Apr 15, 2026
ae05a49
Fix wrong suggestion for returning async closure
chenyukang Jan 13, 2026
21cd762
Rewrite `FlatMapInPlace`.
nnethercote Apr 21, 2026
b1c7595
Ensure we don't feed owners from ast lowering if we ever make that qu…
oli-obk Apr 20, 2026
39f517f
Move diagnostic::on_const target check
mejrs Apr 20, 2026
5ba06cc
Always refer to non-const trait impls
mejrs Apr 20, 2026
26d2c30
Move diagnostic::on_move target check
mejrs Apr 20, 2026
59503ec
Move diagnostic::on_unimplemented target check
mejrs Apr 20, 2026
c62be6e
Move diagnostic::on_unknown target check
mejrs Apr 20, 2026
80fb0aa
Move diagnostic::do_not_recommend target checking
mejrs Apr 20, 2026
3990dda
say "implementation(s) in "not on trait impl" lints
mejrs Apr 20, 2026
a4c79fc
Rollup merge of #155028 - Brace1000:whitespace-tests, r=chenyukang
jhpratt Apr 21, 2026
4348c16
Rollup merge of #155582 - nnethercote:overhaul-flat_map_in_place, r=c…
jhpratt Apr 21, 2026
6e9a1c5
Rollup merge of #151194 - chenyukang:yukang-fix-150701-async-closure,…
jhpratt Apr 21, 2026
a46164f
Rollup merge of #154377 - mu001999-contrib:fix/dead-code, r=TaKO8Ki
jhpratt Apr 21, 2026
b6d4b38
Rollup merge of #155572 - mejrs:move_target_checks, r=JonathanBrouwer…
jhpratt Apr 21, 2026
d8aff48
Rollup merge of #155586 - oli-obk:assert-ignored-feed, r=petrochenkov
jhpratt Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
use rustc_errors::Diagnostic;
use rustc_feature::{AttributeTemplate, template};
use rustc_hir::Target;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::AttributeLintKind;
use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_session::lint::builtin::{
MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES,
};
use rustc_span::{Symbol, sym};

use crate::attributes::{OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::errors::IncorrectDoNotRecommendLocation;
use crate::parser::ArgParser;
use crate::target_checking::{ALL_TARGETS, AllowedTargets};

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

fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
Expand All @@ -25,6 +31,19 @@ impl<S: Stage> SingleAttributeParser<S> for DoNotRecommendParser {
attr_span,
);
}

if !matches!(cx.target, Target::Impl { of_trait: true }) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
IncorrectDoNotRecommendLocation { target_span }.into_diag(dcx, level)
},
attr_span,
);
return None;
}

Some(AttributeKind::DoNotRecommend { attr_span })
}
}
22 changes: 20 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;

use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;

use crate::errors::DiagnosticOnConstOnlyForTraitImpls;
#[derive(Default)]
pub(crate) struct OnConstParser {
span: Option<Span>,
Expand All @@ -21,6 +23,21 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {

let span = cx.attr_span;
this.span = Some(span);

// FIXME(mejrs) no constness field on `Target`,
// so non-constness is still checked in check_attr.rs
if !matches!(cx.target, Target::Impl { of_trait: true }) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
DiagnosticOnConstOnlyForTraitImpls { target_span }.into_diag(dcx, level)
},
span,
);
return;
}

let mode = Mode::DiagnosticOnConst;

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

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

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use rustc_errors::Diagnostic;
use rustc_feature::template;
use rustc_hir::attrs::AttributeKind;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::sym;

use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::context::{AcceptContext, Stage};
use crate::errors::DiagnosticOnMoveOnlyForAdt;
use crate::parser::ArgParser;
use crate::target_checking::{ALL_TARGETS, AllowedTargets};

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

if !matches!(cx.target, Target::Enum | Target::Struct | Target::Union) {
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| DiagnosticOnMoveOnlyForAdt.into_diag(dcx, level),
span,
);
return;
}

let Some(items) = parse_list(cx, args, mode) else { return };

if let Some(directive) = parse_directive_items(cx, mode, items.mixed(), true) {
Expand All @@ -44,6 +56,8 @@ impl<S: Stage> AttributeParser<S> for OnMoveParser {
this.parse(cx, args, Mode::DiagnosticOnMove);
},
)];

// "Allowed" for all targets but noop if used on not-adt.
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;

use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::errors::DiagnosticOnUnimplementedOnlyForTraits;

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

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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use rustc_errors::Diagnostic;
use rustc_hir::attrs::diagnostic::Directive;
use rustc_session::lint::builtin::MISPLACED_DIAGNOSTIC_ATTRIBUTES;

use crate::ShouldEmit;
use crate::attributes::diagnostic::*;
use crate::attributes::prelude::*;
use crate::errors::DiagnosticOnUnknownOnlyForImports;

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

// At early parsing we get passed `Target::Crate` regardless of the item we're on.
// Only do target checking if we're late.
let early = matches!(cx.stage.should_emit(), ShouldEmit::Nothing);

if !early && !matches!(cx.target, Target::Use) {
let target_span = cx.target_span;
cx.emit_dyn_lint(
MISPLACED_DIAGNOSTIC_ATTRIBUTES,
move |dcx, level| {
DiagnosticOnUnknownOnlyForImports { target_span }.into_diag(dcx, level)
},
span,
);
return;
}

let Some(items) = parse_list(cx, args, mode) else { return };

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

fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_attr_parsing/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,32 @@ pub(crate) struct DocUnknownAny {
#[derive(Diagnostic)]
#[diag("expected boolean for `#[doc(auto_cfg = ...)]`")]
pub(crate) struct DocAutoCfgWrongLiteral;

#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait implementations")]
pub(crate) struct DiagnosticOnConstOnlyForTraitImpls {
#[label("not a trait implementation")]
pub target_span: Span,
}

#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_move]` can only be applied to enums, structs or unions")]
pub(crate) struct DiagnosticOnMoveOnlyForAdt;

#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unimplemented]` can only be applied to trait definitions")]
pub(crate) struct DiagnosticOnUnimplementedOnlyForTraits;

#[derive(Diagnostic)]
#[diag("`#[diagnostic::on_unknown]` can only be applied to `use` statements")]
pub(crate) struct DiagnosticOnUnknownOnlyForImports {
#[label("not an import")]
pub target_span: Span,
}

#[derive(Diagnostic)]
#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")]
pub(crate) struct IncorrectDoNotRecommendLocation {
#[label("not a trait implementation")]
pub target_span: Span,
}
Loading
Loading