diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index bdb098131124..dd14e9143569 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -27,10 +27,9 @@ use rustc_ast_pretty::pprust::{self, State}; use rustc_attr_parsing::validate_attr; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::{DiagCtxtHandle, LintBuffer}; +use rustc_errors::{DiagCtxtHandle, Diagnostic, LintBuffer}; use rustc_feature::Features; use rustc_session::Session; -use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::{ DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN, PATTERNS_IN_FNS_WITHOUT_BODY, UNUSED_VISIBILITIES, @@ -1424,7 +1423,7 @@ fn visit_item(&mut self, item: &'a Item) { UNUSED_VISIBILITIES, item.id, item.vis.span, - BuiltinLintDiag::UnusedVisibility(item.vis.span), + errors::UnusedVisibility { span: item.vis.span }, ) } @@ -1731,14 +1730,19 @@ fn visit_fn(&mut self, fk: FnKind<'a>, attrs: &AttrVec, span: Span, id: NodeId) Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if let Some(ident) = ident { - self.lint_buffer.buffer_lint( + let is_foreign = matches!(ctxt, FnCtxt::Foreign); + self.lint_buffer.dyn_buffer_lint( PATTERNS_IN_FNS_WITHOUT_BODY, id, span, - BuiltinLintDiag::PatternsInFnsWithoutBody { - span, - ident, - is_foreign: matches!(ctxt, FnCtxt::Foreign), + move |dcx, level| { + let sub = errors::PatternsInFnsWithoutBodySub { ident, span }; + if is_foreign { + errors::PatternsInFnsWithoutBody::Foreign { sub } + } else { + errors::PatternsInFnsWithoutBody::Bodiless { sub } + } + .into_diag(dcx, level) }, ) } @@ -1828,11 +1832,26 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) { Some((right, snippet)) } }; - self.lint_buffer.buffer_lint( + let left_sp = err.span; + self.lint_buffer.dyn_buffer_lint( DEPRECATED_WHERE_CLAUSE_LOCATION, item.id, err.span, - BuiltinLintDiag::DeprecatedWhereclauseLocation(err.span, sugg), + move |dcx, level| { + let suggestion = match sugg { + Some((right_sp, sugg)) => { + errors::DeprecatedWhereClauseLocationSugg::MoveToEnd { + left: left_sp, + right: right_sp, + sugg, + } + } + None => { + errors::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp } + } + }; + errors::DeprecatedWhereClauseLocation { suggestion }.into_diag(dcx, level) + }, ); } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 390c1556f191..b3a22c0c9954 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -1150,3 +1150,72 @@ pub(crate) struct RequiresRustAbi { #[label("not using the Rust ABI because of this")] pub extern_abi_span: Span, } + +#[derive(Diagnostic)] +#[diag("visibility qualifiers have no effect on `const _` declarations")] +#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] +pub(crate) struct UnusedVisibility { + #[suggestion( + "remove the qualifier", + style = "short", + code = "", + applicability = "machine-applicable" + )] + pub span: Span, +} + +#[derive(Subdiagnostic)] +#[suggestion( + "remove `mut` from the parameter", + code = "{ident}", + applicability = "machine-applicable" +)] +pub(crate) struct PatternsInFnsWithoutBodySub { + #[primary_span] + pub span: Span, + + pub ident: Ident, +} + +#[derive(Diagnostic)] +pub(crate) enum PatternsInFnsWithoutBody { + #[diag("patterns aren't allowed in foreign function declarations")] + Foreign { + #[subdiagnostic] + sub: PatternsInFnsWithoutBodySub, + }, + #[diag("patterns aren't allowed in functions without bodies")] + Bodiless { + #[subdiagnostic] + sub: PatternsInFnsWithoutBodySub, + }, +} + +#[derive(Diagnostic)] +#[diag("where clause not allowed here")] +#[note("see issue #89122 for more information")] +pub(crate) struct DeprecatedWhereClauseLocation { + #[subdiagnostic] + pub suggestion: DeprecatedWhereClauseLocationSugg, +} + +#[derive(Subdiagnostic)] +pub(crate) enum DeprecatedWhereClauseLocationSugg { + #[multipart_suggestion( + "move it to the end of the type declaration", + applicability = "machine-applicable" + )] + MoveToEnd { + #[suggestion_part(code = "")] + left: Span, + #[suggestion_part(code = "{sugg}")] + right: Span, + + sugg: String, + }, + #[suggestion("remove this `where`", code = "", applicability = "machine-applicable")] + RemoveWhere { + #[primary_span] + span: Span, + }, +} diff --git a/compiler/rustc_errors/src/decorate_diag.rs b/compiler/rustc_errors/src/decorate_diag.rs index a11082e29663..c7e0d508c173 100644 --- a/compiler/rustc_errors/src/decorate_diag.rs +++ b/compiler/rustc_errors/src/decorate_diag.rs @@ -81,4 +81,21 @@ pub fn buffer_lint( diagnostic: decorate.into(), }); } + + pub fn dyn_buffer_lint< + F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static, + >( + &mut self, + lint: &'static Lint, + node_id: NodeId, + span: impl Into, + callback: F, + ) { + self.add_early_lint(BufferedEarlyLint { + lint_id: LintId::of(lint), + node_id, + span: Some(span.into()), + diagnostic: DecorateDiagCompat::Dynamic(Box::new(callback)), + }); + } } diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index d5cd26dd75e3..43bb3971d7ac 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -116,35 +116,16 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind } .into_diag(dcx, level) } - BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { - let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; - if is_foreign { - lints::PatternsInFnsWithoutBody::Foreign { sub } - } else { - lints::PatternsInFnsWithoutBody::Bodiless { sub } - } - .into_diag(dcx, level) - } - BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { - let suggestion = match sugg { - Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { - left: left_sp, - right: right_sp, - sugg, - }, - None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, - }; - lints::DeprecatedWhereClauseLocation { suggestion }.into_diag(dcx, level) - } BuiltinLintDiag::SingleUseLifetime { param_span, - use_span: Some((use_span, elide)), + use_span, + elidable, deletion_span, ident, } => { debug!(?param_span, ?use_span, ?deletion_span); let suggestion = if let Some(deletion_span) = deletion_span { - let (use_span, replace_lt) = if elide { + let (use_span, replace_lt) = if elidable { let use_span = self.sess.source_map().span_extend_while_whitespace(use_span); (use_span, String::new()) @@ -165,9 +146,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { lints::SingleUseLifetime { suggestion, param_span, use_span, ident } .into_diag(dcx, level) } - BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { - lints::UnusedLifetime { deletion_span, ident }.into_diag(dcx, level) - } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, position_sp_for_msg, @@ -257,9 +235,6 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> { BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => { lints::UnusedCrateDependency { extern_crate, local_crate }.into_diag(dcx, level) } - BuiltinLintDiag::UnusedVisibility(span) => { - lints::UnusedVisibility { span }.into_diag(dcx, level) - } BuiltinLintDiag::AttributeLint(kind) => { DecorateAttrLint { sess: self.sess, tcx: self.tcx, diagnostic: &kind } .into_diag(dcx, level) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index d5b5a50d281a..c7c92356c378 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3125,62 +3125,6 @@ pub(crate) enum RedundantImportSub { }, } -#[derive(Diagnostic)] -pub(crate) enum PatternsInFnsWithoutBody { - #[diag("patterns aren't allowed in foreign function declarations")] - Foreign { - #[subdiagnostic] - sub: PatternsInFnsWithoutBodySub, - }, - #[diag("patterns aren't allowed in functions without bodies")] - Bodiless { - #[subdiagnostic] - sub: PatternsInFnsWithoutBodySub, - }, -} - -#[derive(Subdiagnostic)] -#[suggestion( - "remove `mut` from the parameter", - code = "{ident}", - applicability = "machine-applicable" -)] -pub(crate) struct PatternsInFnsWithoutBodySub { - #[primary_span] - pub span: Span, - - pub ident: Ident, -} - -#[derive(Diagnostic)] -#[diag("where clause not allowed here")] -#[note("see issue #89122 for more information")] -pub(crate) struct DeprecatedWhereClauseLocation { - #[subdiagnostic] - pub suggestion: DeprecatedWhereClauseLocationSugg, -} - -#[derive(Subdiagnostic)] -pub(crate) enum DeprecatedWhereClauseLocationSugg { - #[multipart_suggestion( - "move it to the end of the type declaration", - applicability = "machine-applicable" - )] - MoveToEnd { - #[suggestion_part(code = "")] - left: Span, - #[suggestion_part(code = "{sugg}")] - right: Span, - - sugg: String, - }, - #[suggestion("remove this `where`", code = "", applicability = "machine-applicable")] - RemoveWhere { - #[primary_span] - span: Span, - }, -} - #[derive(Diagnostic)] #[diag("lifetime parameter `{$ident}` only used once")] pub(crate) struct SingleUseLifetime { @@ -3205,15 +3149,6 @@ pub(crate) struct SingleUseLifetimeSugg { pub replace_lt: String, } -#[derive(Diagnostic)] -#[diag("lifetime parameter `{$ident}` never used")] -pub(crate) struct UnusedLifetime { - #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] - pub deletion_span: Option, - - pub ident: Ident, -} - #[derive(Diagnostic)] #[diag("named argument `{$named_arg_name}` is not used by name")] pub(crate) struct NamedArgumentUsedPositionally { @@ -3644,19 +3579,6 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion { pub right: Span, } -#[derive(Diagnostic)] -#[diag("visibility qualifiers have no effect on `const _` declarations")] -#[note("`const _` does not declare a name, so there is nothing for the qualifier to apply to")] -pub(crate) struct UnusedVisibility { - #[suggestion( - "remove the qualifier", - style = "short", - code = "", - applicability = "machine-applicable" - )] - pub span: Span, -} - #[derive(Diagnostic)] #[diag("doc alias is duplicated")] pub(crate) struct DocAliasDuplicated { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index e2e4ffc64bea..0faa50442961 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -673,13 +673,6 @@ pub enum BuiltinLintDiag { path: String, since_kind: DeprecatedSinceKind, }, - PatternsInFnsWithoutBody { - span: Span, - ident: Ident, - is_foreign: bool, - }, - /// `##` or `#"` in edition < 2024. - DeprecatedWhereclauseLocation(Span, Option<(Span, String)>), SingleUseLifetime { /// Span of the parameter which declares this lifetime. param_span: Span, @@ -688,7 +681,8 @@ pub enum BuiltinLintDiag { deletion_span: Option, /// Span of the single use, or None if the lifetime is never used. /// If true, the lifetime will be fully elided. - use_span: Option<(Span, bool)>, + use_span: Span, + elidable: bool, ident: Ident, }, NamedArgumentUsedPositionally { @@ -737,7 +731,6 @@ pub enum BuiltinLintDiag { extern_crate: Symbol, local_crate: Symbol, }, - UnusedVisibility(Span), AttributeLint(AttributeLintKind), UnreachableCfg { span: Span, diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 24c923de6794..25c7c625ff93 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1583,3 +1583,12 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { diag } } + +#[derive(Diagnostic)] +#[diag("lifetime parameter `{$ident}` never used")] +pub(crate) struct UnusedLifetime { + #[suggestion("elide the unused lifetime", code = "", applicability = "machine-applicable")] + pub deletion_span: Option, + + pub ident: Ident, +} diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5105f5694d2d..cf048231bd60 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3653,7 +3653,8 @@ pub(crate) fn maybe_report_lifetime_uses( param.ident.span, lint::BuiltinLintDiag::SingleUseLifetime { param_span: param.ident.span, - use_span: Some((use_span, elidable)), + use_span, + elidable, deletion_span, ident: param.ident, }, @@ -3669,12 +3670,7 @@ pub(crate) fn maybe_report_lifetime_uses( lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, - lint::BuiltinLintDiag::SingleUseLifetime { - param_span: param.ident.span, - use_span: None, - deletion_span, - ident: param.ident, - }, + errors::UnusedLifetime { deletion_span, ident: param.ident }, ); } }