diff options
| author | bors <bors@rust-lang.org> | 2022-10-01 10:44:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-10-01 10:44:25 +0000 |
| commit | 744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1 (patch) | |
| tree | 1721987352b5f0a8548fc46984821d974b661934 /compiler/rustc_lint/src/context.rs | |
| parent | 277bb6653b55475b5fbce6309e9852fa2100dabe (diff) | |
| parent | b5b3ffe3fc9cfb524a6432ec60a0fc95c514d2e1 (diff) | |
| download | rust-744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1.tar.gz rust-744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1.zip | |
Auto merge of #101986 - WaffleLapkin:move_lint_note_to_the_bottom, r=estebank
Move lint level source explanation to the bottom So, uhhhhh r? `@estebank` ## User-facing change "note: `#[warn(...)]` on by default" and such are moved to the bottom of the diagnostic: ```diff - = note: `#[warn(unsupported_calling_conventions)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678> + = note: `#[warn(unsupported_calling_conventions)]` on by default ``` Why warning is enabled is the least important thing, so it shouldn't be the first note the user reads, IMO. ## Developer-facing change `struct_span_lint` and similar methods have a different signature. Before: `..., impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>)` After: `..., impl Into<DiagnosticMessage>, impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>` The reason for this is that `struct_span_lint` needs to edit the diagnostic _after_ `decorate` closure is called. This also makes lint code a little bit nicer in my opinion. Another option is to use `impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) -> DiagnosticBuilder<'a, ()>` altough I don't _really_ see reasons to do `let lint = lint.build(message)` everywhere. ## Subtle problem By moving the message outside of the closure (that may not be called if the lint is disabled) `format!(...)` is executed earlier, possibly formatting `Ty` which may call a query that trims paths that crashes the compiler if there were no warnings... I don't think it's that big of a deal, considering that we move from `format!(...)` to `fluent` (which is lazy by-default) anyway, however this required adding a workaround which is unfortunate. ## P.S. I'm sorry, I do not how to make this PR smaller/easier to review. Changes to the lint API affect SO MUCH 😢
Diffstat (limited to 'compiler/rustc_lint/src/context.rs')
| -rw-r--r-- | compiler/rustc_lint/src/context.rs | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cbab56f2066..87007728e9d 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -25,10 +25,8 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject}; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; -use rustc_errors::add_elided_lifetime_in_path_suggestion; -use rustc_errors::{ - Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle, -}; +use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage}; +use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; @@ -580,13 +578,14 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option<impl Into<MultiSpan>>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, diagnostic: BuiltinLintDiagnostics, ) { - self.lookup(lint, span, |lint| { - // We first generate a blank diagnostic. - let mut db = lint.build(""); - + // We first generate a blank diagnostic. + self.lookup(lint, span, msg,|db| { // Now, set up surrounding context. let sess = self.sess(); match diagnostic { @@ -660,7 +659,7 @@ pub trait LintContext: Sized { ) => { add_elided_lifetime_in_path_suggestion( sess.source_map(), - &mut db, + db, n, path_span, incl_angl_brckt, @@ -696,7 +695,7 @@ pub trait LintContext: Sized { } } BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(&mut db, "macro", suggestion, span) + stability::deprecation_suggestion(db, "macro", suggestion, span) } BuiltinLintDiagnostics::UnusedDocComment(span) => { db.span_label(span, "rustdoc does not generate documentation for macro invocations"); @@ -867,7 +866,7 @@ pub trait LintContext: Sized { } } // Rewrap `db`, and pass control to the user. - decorate(LintDiagnosticBuilder::new(db)); + decorate(db) }); } @@ -877,7 +876,10 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ); /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -888,31 +890,39 @@ pub trait LintContext: Sized { span: S, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.lookup(lint, Some(span), |diag| decorator.decorate_lint(diag)); + self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag)); } fn struct_span_lint<S: Into<MultiSpan>>( &self, lint: &'static Lint, span: S, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.lookup(lint, Some(span), decorate); + self.lookup(lint, Some(span), msg, decorate); } /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) { - self.lookup(lint, None as Option<Span>, |diag| decorator.decorate_lint(diag)); + self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| { + decorator.decorate_lint(diag) + }); } /// Emit a lint at the appropriate level, with no associated span. fn lint( &self, lint: &'static Lint, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.lookup(lint, None as Option<Span>, decorate); + self.lookup(lint, None as Option<Span>, msg, decorate); } /// This returns the lint level for the given lint at the current location. @@ -975,13 +985,16 @@ impl<'tcx> LintContext for LateContext<'tcx> { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { let hir_id = self.last_node_with_lint_attrs; match span { - Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, decorate), - None => self.tcx.struct_lint_node(lint, hir_id, decorate), + Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg, decorate), + None => self.tcx.struct_lint_node(lint, hir_id, msg, decorate), } } @@ -1006,9 +1019,12 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.builder.struct_lint(lint, span.map(|s| s.into()), decorate) + self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate) } fn get_lint_level(&self, lint: &'static Lint) -> Level { |
