Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 29 additions & 10 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ use rustc_ast::*;
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,
Expand Down Expand Up @@ -1424,7 +1423,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
UNUSED_VISIBILITIES,
item.id,
item.vis.span,
BuiltinLintDiag::UnusedVisibility(item.vis.span),
errors::UnusedVisibility { span: item.vis.span },
)
}

Expand Down Expand Up @@ -1731,14 +1730,19 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
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)
},
)
}
Expand Down Expand Up @@ -1828,11 +1832,26 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
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)
},
);
}

Expand Down
69 changes: 69 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/rust-lang/rust/issues/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,
},
}
17 changes: 17 additions & 0 deletions compiler/rustc_errors/src/decorate_diag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,21 @@ impl LintBuffer {
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<MultiSpan>,
callback: F,
) {
self.add_early_lint(BufferedEarlyLint {
lint_id: LintId::of(lint),
node_id,
span: Some(span.into()),
diagnostic: DecorateDiagCompat::Dynamic(Box::new(callback)),
});
}
}
31 changes: 3 additions & 28 deletions compiler/rustc_lint/src/early/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,35 +116,16 @@ impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> {
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())
Expand All @@ -165,9 +146,6 @@ impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> {
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,
Expand Down Expand Up @@ -257,9 +235,6 @@ impl<'a> Diagnostic<'a, ()> for DecorateBuiltinLint<'_, '_> {
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)
Expand Down
78 changes: 0 additions & 78 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://github.com/rust-lang/rust/issues/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 {
Expand All @@ -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<Span>,

pub ident: Ident,
}

#[derive(Diagnostic)]
#[diag("named argument `{$named_arg_name}` is not used by name")]
pub(crate) struct NamedArgumentUsedPositionally {
Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 2 additions & 9 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -688,7 +681,8 @@ pub enum BuiltinLintDiag {
deletion_span: Option<Span>,
/// 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 {
Expand Down Expand Up @@ -737,7 +731,6 @@ pub enum BuiltinLintDiag {
extern_crate: Symbol,
local_crate: Symbol,
},
UnusedVisibility(Span),
AttributeLint(AttributeLintKind),
UnreachableCfg {
span: Span,
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1583,3 +1583,12 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for Ambiguity {
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<Span>,

pub ident: Ident,
}
10 changes: 3 additions & 7 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3653,7 +3653,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
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,
},
Expand All @@ -3669,12 +3670,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
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 },
);
}
}
Expand Down
Loading