From 2d213f757d5305f4f6b585ac65bd960cb74b0b84 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 Jan 2023 20:46:56 +0000 Subject: [PATCH 1/9] Make ExitStatus an inhabited type on all platforms Even where actually running processes is not supported. Needed for the next commit. The manual trait implementations now belong on ExitStatusError, which still can't exist. --- library/std/src/sys/unsupported/process.rs | 37 +++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index a494f2d6b4c15..d8259ce6e5497 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -99,58 +99,59 @@ impl fmt::Debug for Command { } } -pub struct ExitStatus(!); +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[non_exhaustive] +pub struct ExitStatus(); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { - self.0 + Ok(()) } pub fn code(&self) -> Option { - self.0 + Some(0) } } -impl Clone for ExitStatus { - fn clone(&self) -> ExitStatus { - self.0 +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "") } } -impl Copy for ExitStatus {} +pub struct ExitStatusError(!); -impl PartialEq for ExitStatus { - fn eq(&self, _other: &ExitStatus) -> bool { +impl Clone for ExitStatusError { + fn clone(&self) -> ExitStatusError { self.0 } } -impl Eq for ExitStatus {} +impl Copy for ExitStatusError {} -impl fmt::Debug for ExitStatus { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl PartialEq for ExitStatusError { + fn eq(&self, _other: &ExitStatusError) -> bool { self.0 } } -impl fmt::Display for ExitStatus { +impl Eq for ExitStatusError {} + +impl fmt::Debug for ExitStatusError { fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0 } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(ExitStatus); - impl Into for ExitStatusError { fn into(self) -> ExitStatus { - self.0.0 + self.0 } } impl ExitStatusError { pub fn code(self) -> Option { - self.0.0 + self.0 } } From 35d88d30a70f94bb6a0e37a6ecd8c59b69bda924 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 3 Jan 2023 20:47:07 +0000 Subject: [PATCH 2/9] impl Default for ExitStatus --- library/std/src/process.rs | 2 +- library/std/src/sys/unix/process/process_unix.rs | 2 +- library/std/src/sys/unix/process/process_unsupported.rs | 2 +- library/std/src/sys/unix/process/process_vxworks.rs | 2 +- library/std/src/sys/unsupported/process.rs | 2 +- library/std/src/sys/windows/process.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 62ce2cb33dc55..a2962da671756 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -1460,7 +1460,7 @@ impl From for Stdio { // vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a // matter of convention and tradition. For clarity we usually speak of `exit`, even when we might // mean an underlying system call such as `_exit`. -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] #[stable(feature = "process", since = "1.0.0")] pub struct ExitStatus(imp::ExitStatus); diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 39d1c8b1d8ebc..4a1639787cc49 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -647,7 +647,7 @@ impl Process { // // This is not actually an "exit status" in Unix terminology. Rather, it is a "wait status". // See the discussion in comments and doc comments for `std::process::ExitStatus`. -#[derive(PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy, Default)] pub struct ExitStatus(c_int); impl fmt::Debug for ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index f28ca58d02038..8e0b971af7316 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -55,7 +55,7 @@ impl Process { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs index f549d37c30116..e3c0dfd4ce1ee 100644 --- a/library/std/src/sys/unix/process/process_vxworks.rs +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -182,7 +182,7 @@ impl Process { } /// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c_int); impl ExitStatus { diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index d8259ce6e5497..77b675aaa4e49 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -99,7 +99,7 @@ impl fmt::Debug for Command { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] #[non_exhaustive] pub struct ExitStatus(); diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 10bc949e1f45f..2cc7521eaaaf2 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -647,7 +647,7 @@ impl Process { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] pub struct ExitStatus(c::DWORD); impl ExitStatus { From 021a12c00da634539f95ae9c4e1b52ed51b3b009 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 25 Apr 2023 17:30:05 +0000 Subject: [PATCH 3/9] Sprinkle some `#[inline]` in `rustc_data_structures::tagged_ptr` --- compiler/rustc_data_structures/src/tagged_ptr/copy.rs | 9 +++++++++ compiler/rustc_data_structures/src/tagged_ptr/drop.rs | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs index 691e92f196a26..e893a2c781346 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs @@ -82,11 +82,13 @@ where /// drop, use [`TaggedPtr`] instead. /// /// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr + #[inline] pub fn new(pointer: P, tag: T) -> Self { Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_ghost: PhantomData } } /// Retrieves the pointer. + #[inline] pub fn pointer(self) -> P where P: Copy, @@ -123,6 +125,7 @@ where /// according to `self.packed` encoding scheme. /// /// [`P::into_ptr`]: Pointer::into_ptr + #[inline] fn pack(ptr: NonNull, tag: T) -> NonNull { // Trigger assert! let () = Self::ASSERTION; @@ -145,6 +148,7 @@ where } /// Retrieves the original raw pointer from `self.packed`. + #[inline] pub(super) fn pointer_raw(&self) -> NonNull { self.packed.map_addr(|addr| unsafe { NonZeroUsize::new_unchecked(addr.get() << T::BITS) }) } @@ -184,6 +188,7 @@ where P: Pointer + Copy, T: Tag, { + #[inline] fn clone(&self) -> Self { *self } @@ -196,6 +201,7 @@ where { type Target = P::Target; + #[inline] fn deref(&self) -> &Self::Target { // Safety: // `pointer_raw` returns the original pointer from `P::into_ptr` which, @@ -209,6 +215,7 @@ where P: Pointer + DerefMut, T: Tag, { + #[inline] fn deref_mut(&mut self) -> &mut Self::Target { // Safety: // `pointer_raw` returns the original pointer from `P::into_ptr` which, @@ -235,6 +242,7 @@ where P: Pointer, T: Tag, { + #[inline] fn eq(&self, other: &Self) -> bool { self.packed == other.packed } @@ -252,6 +260,7 @@ where P: Pointer, T: Tag, { + #[inline] fn hash(&self, state: &mut H) { self.packed.hash(state); } diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs index d418c06b7ebb4..4e42b5b4afe8a 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs @@ -30,16 +30,19 @@ where T: Tag, { /// Tags `pointer` with `tag`. + #[inline] pub fn new(pointer: P, tag: T) -> Self { TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) } } /// Retrieves the tag. + #[inline] pub fn tag(&self) -> T { self.raw.tag() } /// Sets the tag to a new value. + #[inline] pub fn set_tag(&mut self, tag: T) { self.raw.set_tag(tag) } @@ -63,6 +66,8 @@ where T: Tag, { type Target = P::Target; + + #[inline] fn deref(&self) -> &Self::Target { self.raw.deref() } @@ -73,6 +78,7 @@ where P: Pointer + DerefMut, T: Tag, { + #[inline] fn deref_mut(&mut self) -> &mut Self::Target { self.raw.deref_mut() } @@ -108,6 +114,7 @@ where P: Pointer, T: Tag, { + #[inline] fn eq(&self, other: &Self) -> bool { self.raw.eq(&other.raw) } @@ -125,6 +132,7 @@ where P: Pointer, T: Tag, { + #[inline] fn hash(&self, state: &mut H) { self.raw.hash(state); } From 6a41cfe0958cce1fa97ebc173d591129add78f79 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 25 Apr 2023 18:42:42 +0100 Subject: [PATCH 4/9] Migrate `rustc_passes` to translatable diagnostics --- compiler/rustc_passes/messages.ftl | 43 ++++- compiler/rustc_passes/src/check_attr.rs | 32 +-- compiler/rustc_passes/src/errors.rs | 160 ++++++++++++++- compiler/rustc_passes/src/lib.rs | 2 + compiler/rustc_passes/src/liveness.rs | 204 ++++++++------------ compiler/rustc_passes/src/stability.rs | 42 ++-- tests/rustdoc-ui/doc_cfg_hide.stderr | 2 +- tests/rustdoc-ui/invalid-doc-attr.rs | 2 +- tests/rustdoc-ui/invalid-doc-attr.stderr | 2 +- tests/ui/attributes/invalid-doc-attr.rs | 2 +- tests/ui/attributes/invalid-doc-attr.stderr | 2 +- 11 files changed, 313 insertions(+), 180 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 055682a1509ef..406801506013b 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -139,7 +139,6 @@ passes_doc_attr_not_crate_level = passes_attr_crate_level = this attribute can only be applied at the crate level .suggestion = to apply to the crate, use an inner attribute - .help = to apply to the crate, use an inner attribute .note = read for more information passes_doc_test_unknown = @@ -724,3 +723,45 @@ passes_skipping_const_checks = skipping const checks passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments + +passes_unreachable_due_to_uninhabited = unreachable {$descr} + .label = unreachable {$descr} + .label_orig = any code following this expression is unreachable + .note = this expression has type `{$ty}`, which is uninhabited + +passes_unused_var_maybe_capture_ref = unused variable: `{$name}` + .help = did you mean to capture by reference instead? + +passes_unused_capture_maybe_capture_ref = value captured by `{$name}` is never read + .help = did you mean to capture by reference instead? + +passes_unused_var_remove_field = unused variable: `{$name}` +passes_unused_var_remove_field_suggestion = try removing the field + +passes_unused_var_assigned_only = variable `{$name}` is assigned to, but never used + .note = consider using `_{$name}` instead + +passes_unnecessary_stable_feature = the feature `{$feature}` has been stable since {$since} and no longer requires an attribute to enable + +passes_unnecessary_partial_stable_feature = the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}` + .suggestion = if you are using features which are still unstable, change to using `{$implies}` + .suggestion_remove = if you are using features which are now stable, remove this line + +passes_ineffective_unstable_impl = an `#[unstable]` annotation here has no effect + .note = see issue #55436 for more information + +passes_unused_assign = value assigned to `{$name}` is never read + .help = maybe it is overwritten before being read? + +passes_unused_assign_passed = value passed to `{$name}` is never read + .help = maybe it is overwritten before being read? + +passes_maybe_string_interpolation = you might have meant to use string interpolation in this string literal +passes_string_interpolation_only_works = string interpolation only works in `format!` invocations + +passes_unused_variable_try_prefix = unused variable: `{$name}` + .label = unused variable + .suggestion = if this is intentional, prefix it with an underscore + +passes_unused_variable_try_ignore = unused variable: `{$name}` + .suggestion = try ignoring the field diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 085a28626ea00..3f28ac26f8617 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -29,7 +29,7 @@ use rustc_session::lint::builtin::{ }; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; @@ -927,30 +927,18 @@ impl CheckAttrVisitor<'_> { hir_id: HirId, ) -> bool { if hir_id != CRATE_HIR_ID { - self.tcx.struct_span_lint_hir( + // insert a bang between `#` and `[...` + let bang_span = attr.span.lo() + BytePos(1); + let sugg = (attr.style == AttrStyle::Outer + && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID) + .then_some(errors::AttrCrateLevelOnlySugg { + attr: attr.span.with_lo(bang_span).with_hi(bang_span), + }); + self.tcx.emit_spanned_lint( 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); - err - }, + errors::AttrCrateLevelOnly { sugg }, ); return false; } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index e8603b3a2f173..99fc69d1bec7b 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -6,7 +6,8 @@ use std::{ use crate::fluent_generated as fluent; use rustc_ast::Label; use rustc_errors::{ - error_code, Applicability, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan, + error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticSymbolList, ErrorGuaranteed, + IntoDiagnostic, MultiSpan, }; use rustc_hir::{self as hir, ExprKind, Target}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -1555,3 +1556,160 @@ pub struct SkippingConstChecks { #[primary_span] pub span: Span, } + +#[derive(LintDiagnostic)] +#[diag(passes_unreachable_due_to_uninhabited)] +pub struct UnreachableDueToUninhabited<'desc, 'tcx> { + pub descr: &'desc str, + #[label] + pub expr: Span, + #[label(passes_label_orig)] + #[note] + pub orig: Span, + pub ty: Ty<'tcx>, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_var_maybe_capture_ref)] +#[help] +pub struct UnusedVarMaybeCaptureRef { + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_capture_maybe_capture_ref)] +#[help] +pub struct UnusedCaptureMaybeCaptureRef { + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_var_remove_field)] +pub struct UnusedVarRemoveField { + pub name: String, + #[subdiagnostic] + pub sugg: UnusedVarRemoveFieldSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + passes_unused_var_remove_field_suggestion, + applicability = "machine-applicable" +)] +pub struct UnusedVarRemoveFieldSugg { + #[suggestion_part(code = "")] + pub spans: Vec, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_var_assigned_only)] +#[note] +pub struct UnusedVarAssignedOnly { + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unnecessary_stable_feature)] +pub struct UnnecessaryStableFeature { + pub feature: Symbol, + pub since: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unnecessary_partial_stable_feature)] +pub struct UnnecessaryPartialStableFeature { + #[suggestion(code = "{implies}", applicability = "maybe-incorrect")] + pub span: Span, + #[suggestion(passes_suggestion_remove, code = "", applicability = "maybe-incorrect")] + pub line: Span, + pub feature: Symbol, + pub since: Symbol, + pub implies: Symbol, +} + +#[derive(LintDiagnostic)] +#[diag(passes_ineffective_unstable_impl)] +#[note] +pub struct IneffectiveUnstableImpl; + +#[derive(LintDiagnostic)] +#[diag(passes_unused_assign)] +#[help] +pub struct UnusedAssign { + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_assign_passed)] +#[help] +pub struct UnusedAssignPassed { + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_variable_try_prefix)] +pub struct UnusedVariableTryPrefix { + #[label] + pub label: Option, + #[subdiagnostic] + pub string_interp: Vec, + #[subdiagnostic] + pub sugg: UnusedVariableTryPrefixSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(passes_suggestion, applicability = "machine-applicable")] +pub struct UnusedVariableTryPrefixSugg { + #[suggestion_part(code = "_{name}")] + pub spans: Vec, + pub name: String, +} + +pub struct UnusedVariableStringInterp { + pub lit: Span, + pub lo: Span, + pub hi: Span, +} + +impl AddToDiagnostic for UnusedVariableStringInterp { + fn add_to_diagnostic_with(self, diag: &mut Diagnostic, _: F) { + diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation); + diag.multipart_suggestion( + crate::fluent_generated::passes_string_interpolation_only_works, + vec![(self.lo, String::from("format!(")), (self.hi, String::from(")"))], + Applicability::MachineApplicable, + ); + } +} + +#[derive(LintDiagnostic)] +#[diag(passes_unused_variable_try_ignore)] +pub struct UnusedVarTryIgnore { + #[subdiagnostic] + pub sugg: UnusedVarTryIgnoreSugg, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(passes_suggestion, applicability = "machine-applicable")] +pub struct UnusedVarTryIgnoreSugg { + #[suggestion_part(code = "{name}: _")] + pub shorthands: Vec, + #[suggestion_part(code = "_")] + pub non_shorthands: Vec, + pub name: String, +} + +#[derive(LintDiagnostic)] +#[diag(passes_attr_crate_level)] +#[note] +pub struct AttrCrateLevelOnly { + #[subdiagnostic] + pub sugg: Option, +} + +#[derive(Subdiagnostic)] +#[suggestion(passes_suggestion, applicability = "maybe-incorrect", code = "!", style = "verbose")] +pub struct AttrCrateLevelOnlySugg { + #[primary_span] + pub attr: Span, +} diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index eca3bae9a1cfd..8b7338e29aa07 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -12,6 +12,8 @@ #![feature(min_specialization)] #![feature(try_blocks)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_middle; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 7d8f6add63282..6758024419d31 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -81,13 +81,13 @@ //! We generate various special nodes for various, well, special purposes. //! These are described in the `Liveness` struct. +use crate::errors; + use self::LiveNodeKind::*; use self::VarKind::*; use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxIndexMap; -use rustc_errors::Applicability; -use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; @@ -1297,13 +1297,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.exit_ln } - fn warn_about_unreachable( + fn warn_about_unreachable<'desc>( &mut self, orig_span: Span, orig_ty: Ty<'tcx>, expr_span: Span, expr_id: HirId, - descr: &str, + descr: &'desc str, ) { if !orig_ty.is_never() { // Unreachable code warnings are already emitted during type checking. @@ -1316,22 +1316,15 @@ 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( + self.ir.tcx.emit_spanned_lint( lint::builtin::UNREACHABLE_CODE, expr_id, expr_span, - &msg, - |diag| { - diag.span_label(expr_span, &msg) - .span_label(orig_span, "any code following this expression is unreachable") - .span_note( - orig_span, - &format!( - "this expression has type `{}`, which is uninhabited", - orig_ty - ), - ) + errors::UnreachableDueToUninhabited { + expr: expr_span, + orig: orig_span, + descr, + ty: orig_ty, }, ); } @@ -1483,23 +1476,21 @@ impl<'tcx> Liveness<'_, 'tcx> { if self.used_on_entry(entry_ln, var) { if !self.live_on_entry(entry_ln, var) { if let Some(name) = self.should_warn(var) { - self.ir.tcx.struct_span_lint_hir( + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_ASSIGNMENTS, var_hir_id, vec![span], - format!("value captured by `{}` is never read", name), - |lint| lint.help("did you mean to capture by reference instead?"), + errors::UnusedCaptureMaybeCaptureRef { name }, ); } } } else { if let Some(name) = self.should_warn(var) { - self.ir.tcx.struct_span_lint_hir( + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_VARIABLES, var_hir_id, vec![span], - format!("unused variable: `{}`", name), - |lint| lint.help("did you mean to capture by reference instead?"), + errors::UnusedVarMaybeCaptureRef { name }, ); } } @@ -1514,11 +1505,14 @@ impl<'tcx> Liveness<'_, 'tcx> { Some(entry_ln), Some(body), |spans, hir_id, ln, var| { - if !self.live_on_entry(ln, var) { - self.report_unused_assign(hir_id, spans, var, |name| { - format!("value passed to `{}` is never read", name) - }); - } + if !self.live_on_entry(ln, var) + && let Some(name) = self.should_warn(var) { + self.ir.tcx.emit_spanned_lint( + lint::builtin::UNUSED_ASSIGNMENTS, + hir_id, + spans, + errors::UnusedAssignPassed { name }, + ); } }, ); } @@ -1587,39 +1581,35 @@ impl<'tcx> Liveness<'_, 'tcx> { if ln == self.exit_ln { false } else { self.assigned_on_exit(ln, var) }; if is_assigned { - self.ir.tcx.struct_span_lint_hir( + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans .into_iter() .map(|(_, _, ident_span)| ident_span) .collect::>(), - format!("variable `{}` is assigned to, but never used", name), - |lint| lint.note(&format!("consider using `_{}` instead", name)), + errors::UnusedVarAssignedOnly { name }, ) } else if can_remove { - self.ir.tcx.struct_span_lint_hir( + let spans = hir_ids_and_spans + .iter() + .map(|(_, pat_span, _)| { + let span = self + .ir + .tcx + .sess + .source_map() + .span_extend_to_next_char(*pat_span, ',', true); + span.with_hi(BytePos(span.hi().0 + 1)) + }) + .collect(); + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::>(), - format!("unused variable: `{}`", name), - |lint| { - lint.multipart_suggestion( - "try removing the field", - hir_ids_and_spans - .iter() - .map(|(_, pat_span, _)| { - let span = self - .ir - .tcx - .sess - .source_map() - .span_extend_to_next_char(*pat_span, ',', true); - (span.with_hi(BytePos(span.hi().0 + 1)), String::new()) - }) - .collect(), - Applicability::MachineApplicable, - ) + errors::UnusedVarRemoveField { + name, + sugg: errors::UnusedVarRemoveFieldSugg { spans }, }, ); } else { @@ -1633,55 +1623,46 @@ impl<'tcx> Liveness<'_, 'tcx> { // the field" message, and suggest `_` for the non-shorthands. If we only // have non-shorthand, then prefix with an underscore instead. if !shorthands.is_empty() { - let shorthands = shorthands - .into_iter() - .map(|(_, pat_span, _)| (pat_span, format!("{}: _", name))) - .chain( - non_shorthands - .into_iter() - .map(|(_, pat_span, _)| (pat_span, "_".to_string())), - ) - .collect::>(); + let shorthands = + shorthands.into_iter().map(|(_, pat_span, _)| pat_span).collect(); + let non_shorthands = + non_shorthands.into_iter().map(|(_, pat_span, _)| pat_span).collect(); - self.ir.tcx.struct_span_lint_hir( + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans .iter() .map(|(_, pat_span, _)| *pat_span) .collect::>(), - format!("unused variable: `{}`", name), - |lint| { - lint.multipart_suggestion( - "try ignoring the field", + errors::UnusedVarTryIgnore { + sugg: errors::UnusedVarTryIgnoreSugg { shorthands, - Applicability::MachineApplicable, - ) + non_shorthands, + name, + }, }, ); } else { let non_shorthands = non_shorthands .into_iter() - .map(|(_, _, ident_span)| (ident_span, format!("_{}", name))) + .map(|(_, _, ident_span)| ident_span) .collect::>(); - - self.ir.tcx.struct_span_lint_hir( + let suggestions = self.string_interp_suggestions(&name, opt_body); + self.ir.tcx.emit_spanned_lint( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans .iter() .map(|(_, _, ident_span)| *ident_span) .collect::>(), - format!("unused variable: `{}`", name), - |lint| { - if self.has_added_lit_match_name_span(&name, opt_body, lint) { - lint.span_label(pat.span, "unused variable"); - } - lint.multipart_suggestion( - "if this is intentional, prefix it with an underscore", - non_shorthands, - Applicability::MachineApplicable, - ) + errors::UnusedVariableTryPrefix { + label: if !suggestions.is_empty() { Some(pat.span) } else { None }, + sugg: errors::UnusedVariableTryPrefixSugg { + spans: non_shorthands, + name, + }, + string_interp: suggestions, }, ); } @@ -1689,65 +1670,40 @@ impl<'tcx> Liveness<'_, 'tcx> { } } - fn has_added_lit_match_name_span( + fn string_interp_suggestions( &self, name: &str, opt_body: Option<&hir::Body<'_>>, - err: &mut Diagnostic, - ) -> bool { - let mut has_litstring = false; - let Some(opt_body) = opt_body else {return false;}; + ) -> Vec { + let mut suggs = Vec::new(); + let Some(opt_body) = opt_body else { return suggs; }; let mut visitor = CollectLitsVisitor { lit_exprs: vec![] }; intravisit::walk_body(&mut visitor, opt_body); for lit_expr in visitor.lit_exprs { let hir::ExprKind::Lit(litx) = &lit_expr.kind else { continue }; let rustc_ast::LitKind::Str(syb, _) = litx.node else{ continue; }; let name_str: &str = syb.as_str(); - let mut name_pa = String::from("{"); - name_pa.push_str(&name); - name_pa.push('}'); + let name_pa = format!("{{{name}}}"); if name_str.contains(&name_pa) { - err.span_label( - lit_expr.span, - "you might have meant to use string interpolation in this string literal", - ); - err.multipart_suggestion( - "string interpolation only works in `format!` invocations", - vec![ - (lit_expr.span.shrink_to_lo(), "format!(".to_string()), - (lit_expr.span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MachineApplicable, - ); - has_litstring = true; + suggs.push(errors::UnusedVariableStringInterp { + lit: lit_expr.span, + lo: lit_expr.span.shrink_to_lo(), + hi: lit_expr.span.shrink_to_hi(), + }); } } - has_litstring + suggs } fn warn_about_dead_assign(&self, spans: Vec, hir_id: HirId, ln: LiveNode, var: Variable) { - if !self.live_on_exit(ln, var) { - self.report_unused_assign(hir_id, spans, var, |name| { - format!("value assigned to `{}` is never read", name) - }); - } - } - - fn report_unused_assign( - &self, - hir_id: HirId, - spans: Vec, - var: Variable, - message: impl Fn(&str) -> String, - ) { - if let Some(name) = self.should_warn(var) { - self.ir.tcx.struct_span_lint_hir( - lint::builtin::UNUSED_ASSIGNMENTS, - hir_id, - spans, - message(&name), - |lint| lint.help("maybe it is overwritten before being read?"), - ) - } + if !self.live_on_exit(ln, var) + && let Some(name) = self.should_warn(var) { + self.ir.tcx.emit_spanned_lint( + lint::builtin::UNUSED_ASSIGNMENTS, + hir_id, + spans, + errors::UnusedAssign { name }, + ); + } } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 4a35c6794663e..9615f283ff423 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -7,7 +7,6 @@ use rustc_attr::{ UnstableReason, VERSION_PLACEHOLDER, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -759,12 +758,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // do not lint when the trait isn't resolved, since resolution error should // be fixed first if t.path.res != Res::Err && c.fully_stable { - self.tcx.struct_span_lint_hir( + self.tcx.emit_spanned_lint( INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), span, - "an `#[unstable]` annotation here has no effect", - |lint| lint.note("see issue #55436 for more information") + errors::IneffectiveUnstableImpl, ); } } @@ -1095,29 +1093,16 @@ fn unnecessary_partially_stable_feature_lint( implies: Symbol, since: Symbol, ) { - tcx.struct_span_lint_hir( + tcx.emit_spanned_lint( 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!( - "if you are using features which are still unstable, change to using `{implies}`" - ), - implies, - Applicability::MaybeIncorrect, - ) - .span_suggestion( - tcx.sess.source_map().span_extend_to_line(span), - "if you are using features which are now stable, remove this line", - "", - Applicability::MaybeIncorrect, - ) + errors::UnnecessaryPartialStableFeature { + span, + line: tcx.sess.source_map().span_extend_to_line(span), + feature, + since, + implies, }, ); } @@ -1131,7 +1116,10 @@ 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, format!("the feature `{feature}` has been stable since {since} and no longer requires an attribute to enable"), |lint| { - lint - }); + tcx.emit_spanned_lint( + lint::builtin::STABLE_FEATURES, + hir::CRATE_HIR_ID, + span, + errors::UnnecessaryStableFeature { feature, since }, + ); } diff --git a/tests/rustdoc-ui/doc_cfg_hide.stderr b/tests/rustdoc-ui/doc_cfg_hide.stderr index 03623368cd047..b7e8870fdf548 100644 --- a/tests/rustdoc-ui/doc_cfg_hide.stderr +++ b/tests/rustdoc-ui/doc_cfg_hide.stderr @@ -16,7 +16,7 @@ LL | #![deny(warnings)] help: to apply to the crate, use an inner attribute | LL | #![doc(cfg_hide(doc))] - | ~~~~~~~~~~~~~~~~~~~~~~ + | + error: `#[doc(cfg_hide(...)]` takes a list of attributes --> $DIR/doc_cfg_hide.rs:4:8 diff --git a/tests/rustdoc-ui/invalid-doc-attr.rs b/tests/rustdoc-ui/invalid-doc-attr.rs index de004b41e27bc..c231e43b35caf 100644 --- a/tests/rustdoc-ui/invalid-doc-attr.rs +++ b/tests/rustdoc-ui/invalid-doc-attr.rs @@ -5,7 +5,7 @@ //~^ ERROR can only be applied at the crate level //~| WARN is being phased out //~| HELP to apply to the crate, use an inner attribute -//~| SUGGESTION #![doc(test(no_crate_inject))] +//~| SUGGESTION ! #[doc(inline)] //~^ ERROR can only be applied to a `use` item //~| WARN is being phased out diff --git a/tests/rustdoc-ui/invalid-doc-attr.stderr b/tests/rustdoc-ui/invalid-doc-attr.stderr index 3c66e587b470d..b23b8ded8674b 100644 --- a/tests/rustdoc-ui/invalid-doc-attr.stderr +++ b/tests/rustdoc-ui/invalid-doc-attr.stderr @@ -16,7 +16,7 @@ LL | #![deny(warnings)] help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] - | + | + error: this attribute can only be applied to a `use` item --> $DIR/invalid-doc-attr.rs:9:7 diff --git a/tests/ui/attributes/invalid-doc-attr.rs b/tests/ui/attributes/invalid-doc-attr.rs index de004b41e27bc..c231e43b35caf 100644 --- a/tests/ui/attributes/invalid-doc-attr.rs +++ b/tests/ui/attributes/invalid-doc-attr.rs @@ -5,7 +5,7 @@ //~^ ERROR can only be applied at the crate level //~| WARN is being phased out //~| HELP to apply to the crate, use an inner attribute -//~| SUGGESTION #![doc(test(no_crate_inject))] +//~| SUGGESTION ! #[doc(inline)] //~^ ERROR can only be applied to a `use` item //~| WARN is being phased out diff --git a/tests/ui/attributes/invalid-doc-attr.stderr b/tests/ui/attributes/invalid-doc-attr.stderr index 3c66e587b470d..b23b8ded8674b 100644 --- a/tests/ui/attributes/invalid-doc-attr.stderr +++ b/tests/ui/attributes/invalid-doc-attr.stderr @@ -16,7 +16,7 @@ LL | #![deny(warnings)] help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] - | + | + error: this attribute can only be applied to a `use` item --> $DIR/invalid-doc-attr.rs:9:7 From 3402e286d547fe7a6e58a7190d8774e71124f50b Mon Sep 17 00:00:00 2001 From: Jan David Date: Wed, 26 Apr 2023 16:08:01 +0200 Subject: [PATCH 5/9] Downsize builders for i686-gnu The infra-team is continuously monitoring the efficiency of the build system in an effort to improve overall build times and resource usage. The builders for the `i686-gnu` targets have used much less resources than allocated in the past, so we are testing a smaller builder size for them. --- .github/workflows/ci.yml | 4 ++-- src/ci/github-actions/ci.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dacf929278ab9..fd9843fad4455 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -260,10 +260,10 @@ jobs: os: ubuntu-20.04-8core-32gb env: {} - name: i686-gnu - os: ubuntu-20.04-16core-64gb + os: ubuntu-20.04-8core-32gb env: {} - name: i686-gnu-nopt - os: ubuntu-20.04-16core-64gb + os: ubuntu-20.04-8core-32gb env: {} - name: mingw-check os: ubuntu-20.04-8core-32gb diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 8c7798aad8bdf..4af24867ffb30 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -416,10 +416,10 @@ jobs: <<: *job-linux-8c - name: i686-gnu - <<: *job-linux-16c + <<: *job-linux-8c - name: i686-gnu-nopt - <<: *job-linux-16c + <<: *job-linux-8c - name: mingw-check <<: *job-linux-8c From 4cbe65db8b805d0d961b72ccdcc8a36159e2563c Mon Sep 17 00:00:00 2001 From: Jan David Date: Wed, 26 Apr 2023 16:40:12 +0200 Subject: [PATCH 6/9] Downsize builder for mingw-check The infra-team is continuously monitoring the efficiency of the build system in an effort to improve overall build times and resource usage. The builder for the `mingw-check` target have used much less resources than allocated in the past, so we are testing a smaller builder size for it. --- .github/workflows/ci.yml | 2 +- src/ci/github-actions/ci.yml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd9843fad4455..5a4bd7bfd425b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -266,7 +266,7 @@ jobs: os: ubuntu-20.04-8core-32gb env: {} - name: mingw-check - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: test-various os: ubuntu-20.04-8core-32gb diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 4af24867ffb30..db79358aa35f4 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -73,6 +73,10 @@ x--expand-yaml-anchors--remove: - &base-job env: {} + - &job-linux-4c + os: ubuntu-20.04-4core-16gb + <<: *base-job + - &job-linux-8c os: ubuntu-20.04-8core-32gb <<: *base-job @@ -422,7 +426,7 @@ jobs: <<: *job-linux-8c - name: mingw-check - <<: *job-linux-8c + <<: *job-linux-4c - name: test-various <<: *job-linux-8c From 47528c0b144f4c49adf58e34e8d3d47ff8e80c34 Mon Sep 17 00:00:00 2001 From: Jan David Date: Wed, 26 Apr 2023 16:52:39 +0200 Subject: [PATCH 7/9] Downsize builders for some x86_64-gnu targets The infra-team is continuously monitoring the efficiency of the build system in an effort to improve overall build times and resource usage. The builders for some of the `x86_64-gnu` targets have used much less resources than allocated in the past, so we are testing a smaller builder size for them. --- .github/workflows/ci.yml | 8 ++++---- src/ci/github-actions/ci.yml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a4bd7bfd425b..2c97c681fa4e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -275,16 +275,16 @@ jobs: os: ubuntu-20.04-8core-32gb env: {} - name: x86_64-gnu - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-stable env: IMAGE: x86_64-gnu RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable CI_ONLY_WHEN_CHANNEL: nightly - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb - name: x86_64-gnu-aux - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-debug os: ubuntu-20.04-8core-32gb @@ -309,7 +309,7 @@ jobs: RUST_BACKTRACE: 1 os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-nopt - os: ubuntu-20.04-8core-32gb + os: ubuntu-20.04-4core-16gb env: {} - name: x86_64-gnu-tools env: diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index db79358aa35f4..967703ae582c9 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -435,7 +435,7 @@ jobs: <<: *job-linux-8c - name: x86_64-gnu - <<: *job-linux-8c + <<: *job-linux-4c # This job ensures commits landing on nightly still pass the full # test suite on the stable channel. There are some UI tests that @@ -450,10 +450,10 @@ jobs: # could cause failures when `dev: 1` in `stage0.txt`, and running # this on stable is useless. CI_ONLY_WHEN_CHANNEL: nightly - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-aux - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-debug <<: *job-linux-8c @@ -482,7 +482,7 @@ jobs: <<: *job-linux-8c - name: x86_64-gnu-nopt - <<: *job-linux-8c + <<: *job-linux-4c - name: x86_64-gnu-tools env: From ef6d4c504dd76619c2cd22eaf0ed30e38555de2c Mon Sep 17 00:00:00 2001 From: cui fliter Date: Wed, 26 Apr 2023 00:01:54 +0800 Subject: [PATCH 8/9] Remove repeated definite articles Signed-off-by: cui fliter --- library/core/src/macros/panic.md | 2 +- tests/debuginfo/thread.rs | 2 +- tests/ui/generic-associated-types/self-outlives-lint.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index 98fb7e9e41d7a..8b549e187ba81 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -42,7 +42,7 @@ the successful result of some computation, `Ok(T)`, or error types that represent an anticipated runtime failure mode of that computation, `Err(E)`. `Result` is used alongside user defined types which represent the various anticipated runtime failure modes that the associated computation could -encounter. `Result` must be propagated manually, often with the the help of the +encounter. `Result` must be propagated manually, often with the help of the `?` operator and `Try` trait, and they must be reported manually, often with the help of the `Error` trait. diff --git a/tests/debuginfo/thread.rs b/tests/debuginfo/thread.rs index 388d50c5cdc43..e7e83c7aacd47 100644 --- a/tests/debuginfo/thread.rs +++ b/tests/debuginfo/thread.rs @@ -1,4 +1,4 @@ -// Testing the the display of JoinHandle and Thread in cdb. +// Testing the display of JoinHandle and Thread in cdb. // cdb-only // min-cdb-version: 10.0.18317.1001 diff --git a/tests/ui/generic-associated-types/self-outlives-lint.rs b/tests/ui/generic-associated-types/self-outlives-lint.rs index 673891fc3d1b4..0ea81b5aecb9e 100644 --- a/tests/ui/generic-associated-types/self-outlives-lint.rs +++ b/tests/ui/generic-associated-types/self-outlives-lint.rs @@ -189,7 +189,7 @@ trait MultipleMethods { } // We would normally require `Self: 'a`, but we can prove that `Self: 'static` -// because of the the bounds on the trait, so the bound is proven +// because of the bounds on the trait, so the bound is proven trait Trait: 'static { type Assoc<'a>; fn make_assoc(_: &u32) -> Self::Assoc<'_>; From 0776a4bf27bd8fe813e33354b43b5b50e5469852 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 16 Apr 2023 14:48:36 -0500 Subject: [PATCH 9/9] docs(style): add more let-else examples Co-authored-by: Michael Goulet --- src/doc/style-guide/src/statements.md | 37 ++++++++++++++++++--------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md index 4ab1c36f97652..671e6d31a5775 100644 --- a/src/doc/style-guide/src/statements.md +++ b/src/doc/style-guide/src/statements.md @@ -138,18 +138,31 @@ Otherwise, the `else` keyword and opening brace should be placed on the next lin For example: ```rust -let Some(x) = abcdef() - .foo( - "abc", - some_really_really_really_long_ident, - "ident", - "123456", - ) - .bar() - .baz() - .qux("fffffffffffffffff") -else { - foo_bar() +fn main() { + let Some(x) = abcdef() + .foo( + "abc", + some_really_really_really_long_ident, + "ident", + "123456", + ) + .bar() + .baz() + .qux("fffffffffffffffff") + else { + return + }; + + let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name + else { + return; + }; + + let Some(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) = + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb + else { + return; + }; } ```