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_passes/src | |
| 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_passes/src')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 56 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/liveness.rs | 65 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/naked_functions.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/stability.rs | 29 |
5 files changed, 104 insertions, 109 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 897a0db930c..87433538512 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -370,10 +370,13 @@ impl CheckAttrVisitor<'_> { b.push_str(&(allowed_target.to_string() + "s")); b }); - self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build(&format!("`#[{name}]` only has an effect on {}", supported_names)) - .emit(); - }); + self.tcx.struct_span_lint_hir( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + &format!("`#[{name}]` only has an effect on {}", supported_names), + |lint| lint, + ); } } @@ -877,25 +880,31 @@ impl CheckAttrVisitor<'_> { hir_id: HirId, ) -> bool { if hir_id != CRATE_HIR_ID { - self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| { - let mut err = lint.build(fluent::passes::attr_crate_level); - if attr.style == AttrStyle::Outer - && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID - { - if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) { - src.insert(1, '!'); - err.span_suggestion_verbose( - attr.span, - fluent::passes::suggestion, - src, - Applicability::MaybeIncorrect, - ); - } else { - err.span_help(attr.span, fluent::passes::help); + self.tcx.struct_span_lint_hir( + INVALID_DOC_ATTRIBUTES, + hir_id, + meta.span(), + fluent::passes::attr_crate_level, + |err| { + if attr.style == AttrStyle::Outer + && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID + { + if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) { + src.insert(1, '!'); + err.span_suggestion_verbose( + attr.span, + fluent::passes::suggestion, + src, + Applicability::MaybeIncorrect, + ); + } else { + err.span_help(attr.span, fluent::passes::help); + } } - } - err.note(fluent::passes::note).emit(); - }); + err.note(fluent::passes::note); + err + }, + ); return false; } true diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 3b1c1cd657f..08f704da62c 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, MultiSpan}; +use rustc_errors::{pluralize, Applicability, DelayDm, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -184,13 +184,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { lint::builtin::DEAD_CODE, assign.hir_id, assign.span, - |lint| { - lint.build(&format!( + DelayDm(|| format!( "useless assignment of {} of type `{}` to itself", if is_field_assign { "field" } else { "variable" }, self.typeck_results().expr_ty(lhs), - )) - .emit(); + )), + |lint| { + lint + }, ) } @@ -717,6 +718,26 @@ impl<'tcx> DeadVisitor<'tcx> { }) .collect(); + let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); + let span_len = dead_codes.len(); + let names = match &names[..] { + _ if span_len > 6 => String::new(), + [name] => format!("`{name}` "), + [names @ .., last] => { + format!( + "{} and `{last}` ", + names.iter().map(|name| format!("`{name}`")).join(", ") + ) + } + [] => unreachable!(), + }; + let msg = format!( + "{these}{descr}{s} {names}{are} never {participle}", + these = if span_len > 6 { "multiple " } else { "" }, + s = pluralize!(span_len), + are = pluralize!("is", span_len), + ); + tcx.struct_span_lint_hir( if is_positional { lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS @@ -725,27 +746,8 @@ impl<'tcx> DeadVisitor<'tcx> { }, tcx.hir().local_def_id_to_hir_id(first_id), MultiSpan::from_spans(spans.clone()), - |lint| { - let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); - let span_len = dead_codes.len(); - let names = match &names[..] { - _ if span_len > 6 => String::new(), - [name] => format!("`{name}` "), - [names @ .., last] => { - format!( - "{} and `{last}` ", - names.iter().map(|name| format!("`{name}`")).join(", ") - ) - } - [] => unreachable!(), - }; - let mut err = lint.build(&format!( - "{these}{descr}{s} {names}{are} never {participle}", - these = if span_len > 6 { "multiple " } else { "" }, - s = pluralize!(span_len), - are = pluralize!("is", span_len), - )); - + msg, + |err| { if is_positional { err.multipart_suggestion( &format!( @@ -791,7 +793,7 @@ impl<'tcx> DeadVisitor<'tcx> { ); err.note(&msg); } - err.emit(); + err }, ); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6a4cd79cde7..c6fe40f72fc 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1319,14 +1319,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. + let msg = format!("unreachable {}", descr); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNREACHABLE_CODE, expr_id, expr_span, - |lint| { - let msg = format!("unreachable {}", descr); - lint.build(&msg) - .span_label(expr_span, &msg) + &msg, + |diag| { + diag.span_label(expr_span, &msg) .span_label(orig_span, "any code following this expression is unreachable") .span_note( orig_span, @@ -1335,7 +1335,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { orig_ty ), ) - .emit(); }, ); } @@ -1491,14 +1490,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_ASSIGNMENTS, var_hir_id, vec![span], - |lint| { - lint.build(&format!( - "value captured by `{}` is never read", - name - )) - .help("did you mean to capture by reference instead?") - .emit(); - }, + format!("value captured by `{}` is never read", name), + |lint| lint.help("did you mean to capture by reference instead?"), ); } } @@ -1508,11 +1501,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_VARIABLES, var_hir_id, vec![span], - |lint| { - lint.build(&format!("unused variable: `{}`", name)) - .help("did you mean to capture by reference instead?") - .emit(); - }, + format!("unused variable: `{}`", name), + |lint| lint.help("did you mean to capture by reference instead?"), ); } } @@ -1601,20 +1591,17 @@ impl<'tcx> Liveness<'_, 'tcx> { .into_iter() .map(|(_, _, ident_span)| ident_span) .collect::<Vec<_>>(), - |lint| { - lint.build(&format!("variable `{}` is assigned to, but never used", name)) - .note(&format!("consider using `_{}` instead", name)) - .emit(); - }, + format!("variable `{}` is assigned to, but never used", name), + |lint| lint.note(&format!("consider using `_{}` instead", name)), ) } else if can_remove { self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - err.multipart_suggestion( + lint.multipart_suggestion( "try removing the field", hir_ids_and_spans .iter() @@ -1629,8 +1616,7 @@ impl<'tcx> Liveness<'_, 'tcx> { }) .collect(), Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } else { @@ -1661,14 +1647,13 @@ impl<'tcx> Liveness<'_, 'tcx> { .iter() .map(|(_, pat_span, _)| *pat_span) .collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - err.multipart_suggestion( + lint.multipart_suggestion( "try ignoring the field", shorthands, Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } else { @@ -1684,17 +1669,16 @@ impl<'tcx> Liveness<'_, 'tcx> { .iter() .map(|(_, _, ident_span)| *ident_span) .collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - if self.has_added_lit_match_name_span(&name, opt_body, &mut err) { - err.span_label(pat.span, "unused variable"); + if self.has_added_lit_match_name_span(&name, opt_body, lint) { + lint.span_label(pat.span, "unused variable"); } - err.multipart_suggestion( + lint.multipart_suggestion( "if this is intentional, prefix it with an underscore", non_shorthands, Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } @@ -1758,11 +1742,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_ASSIGNMENTS, hir_id, spans, - |lint| { - lint.build(&message(&name)) - .help("maybe it is overwritten before being read?") - .emit(); - }, + message(&name), + |lint| lint.help("maybe it is overwritten before being read?"), ) } } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 607973446fc..2690be66c21 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -65,9 +65,13 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) { if abi == Abi::Rust { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let span = tcx.def_span(def_id); - tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, span, |lint| { - lint.build("Rust ABI is unsupported in naked functions").emit(); - }); + tcx.struct_span_lint_hir( + UNDEFINED_NAKED_FUNCTION_ABI, + hir_id, + span, + "Rust ABI is unsupported in naked functions", + |lint| lint, + ); } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e50beb27d2a..34fa80228df 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -752,10 +752,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), span, - |lint| {lint - .build("an `#[unstable]` annotation here has no effect") - .note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information") - .emit();} + "an `#[unstable]` annotation here has no effect", + |lint| lint.note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information") ); } } @@ -1081,11 +1079,16 @@ fn unnecessary_partially_stable_feature_lint( implies: Symbol, since: Symbol, ) { - tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| { - lint.build(&format!( + tcx.struct_span_lint_hir( + lint::builtin::STABLE_FEATURES, + hir::CRATE_HIR_ID, + span, + format!( "the feature `{feature}` has been partially stabilized since {since} and is succeeded \ by the feature `{implies}`" - )) + ), + |lint| { + lint .span_suggestion( span, &format!( @@ -1100,8 +1103,8 @@ fn unnecessary_partially_stable_feature_lint( "", Applicability::MaybeIncorrect, ) - .emit(); - }); + }, + ); } fn unnecessary_stable_feature_lint( @@ -1113,12 +1116,8 @@ fn unnecessary_stable_feature_lint( if since.as_str() == VERSION_PLACEHOLDER { since = rust_version_symbol(); } - tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| { - lint.build(&format!( - "the feature `{feature}` has been stable since {since} and no longer requires an \ - attribute to enable", - )) - .emit(); + tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, format!("the feature `{feature}` has been stable since {since} and no longer requires an attribute to enable"), |lint| { + lint }); } |
