From 42aa1273b0dd317c4aafdcf649f40cbad4499b60 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Tue, 7 Nov 2023 19:32:48 +0000 Subject: When encountering struct fn call literal with private fields, suggest all builders When encountering code like `Box(42)`, suggest `Box::new(42)` and *all* other associated functions that return `-> Box`. --- compiler/rustc_errors/src/diagnostic.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 470f318eb33..b379d17dc22 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -759,6 +759,9 @@ impl Diagnostic { suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self { + let mut suggestions: Vec<_> = suggestions.into_iter().collect(); + suggestions.sort(); + self.span_suggestions_with_style( sp, msg, @@ -768,7 +771,9 @@ impl Diagnostic { ) } - /// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`]. + /// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`]. This version + /// *doesn't* sort the suggestions, so the caller has control of the order in which they are + /// presented. pub fn span_suggestions_with_style( &mut self, sp: Span, @@ -777,9 +782,7 @@ impl Diagnostic { applicability: Applicability, style: SuggestionStyle, ) -> &mut Self { - let mut suggestions: Vec<_> = suggestions.into_iter().collect(); - suggestions.sort(); - + let suggestions: Vec<_> = suggestions.into_iter().collect(); debug_assert!( !(sp.is_empty() && suggestions.iter().any(|suggestion| suggestion.is_empty())), "Span must not be empty and have no suggestion" -- cgit 1.4.1-3-g733a5 From f1ae02f4bd971acc384ed3422e235fb1eb07dfa7 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 8 Nov 2023 18:24:49 +0000 Subject: Don't sort `span_suggestions`, leave that to caller --- compiler/rustc_errors/src/diagnostic.rs | 7 +------ compiler/rustc_hir_analysis/src/astconv/mod.rs | 6 +++++- compiler/rustc_hir_typeck/src/expr.rs | 3 ++- compiler/rustc_hir_typeck/src/method/suggest.rs | 14 ++++++-------- .../rustc_macros/src/diagnostics/diagnostic_builder.rs | 4 +--- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_resolve/src/late/diagnostics.rs | 14 +++++++++----- src/tools/clippy/clippy_lints/src/booleans.rs | 3 ++- tests/ui/parser/bad-pointer-type.stderr | 4 ++-- tests/ui/parser/double-pointer.stderr | 4 ++-- 10 files changed, 31 insertions(+), 29 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index b379d17dc22..1c1da89c557 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -759,9 +759,6 @@ impl Diagnostic { suggestions: impl IntoIterator, applicability: Applicability, ) -> &mut Self { - let mut suggestions: Vec<_> = suggestions.into_iter().collect(); - suggestions.sort(); - self.span_suggestions_with_style( sp, msg, @@ -771,9 +768,7 @@ impl Diagnostic { ) } - /// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`]. This version - /// *doesn't* sort the suggestions, so the caller has control of the order in which they are - /// presented. + /// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`]. pub fn span_suggestions_with_style( &mut self, sp: Span, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8126b451181..3542fc7cd33 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -945,7 +945,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Applicability::MachineApplicable, ); } else { - match (types, traits) { + let mut types = types.to_vec(); + types.sort(); + let mut traits = traits.to_vec(); + traits.sort(); + match (&types[..], &traits[..]) { ([], []) => { err.span_suggestion_verbose( span, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 6c99044d0aa..9180d4aad32 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2703,7 +2703,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.get_field_candidates_considering_privacy(span, ty, mod_id, id) { let field_names = found_fields.iter().map(|field| field.name).collect::>(); - let candidate_fields: Vec<_> = found_fields + let mut candidate_fields: Vec<_> = found_fields .into_iter() .filter_map(|candidate_field| { self.check_for_nested_field_satisfying( @@ -2724,6 +2724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect::() }) .collect::>(); + candidate_fields.sort(); let len = candidate_fields.len(); if len > 0 { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 6956778f974..cdb08cfd7d9 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1426,6 +1426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !suggs.is_empty() && let Some(span) = sugg_span { + suggs.sort(); err.span_suggestions( span.with_hi(item_name.span.lo()), "use fully-qualified syntax to disambiguate", @@ -2000,8 +2001,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.get_diagnostic_item(sym::Borrow), self.tcx.get_diagnostic_item(sym::BorrowMut), ]; - let candidate_fields: Vec<_> = fields - .iter() + let mut candidate_fields: Vec<_> = fields .filter_map(|candidate_field| { self.check_for_nested_field_satisfying( span, @@ -2035,6 +2035,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .join(".") }) .collect(); + candidate_fields.sort(); let len = candidate_fields.len(); if len > 0 { @@ -2567,13 +2568,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.item_name(*trait_did), ) }); + let mut sugg: Vec<_> = path_strings.chain(glob_path_strings).collect(); + sugg.sort(); - err.span_suggestions( - span, - msg, - path_strings.chain(glob_path_strings), - Applicability::MaybeIncorrect, - ); + err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect); } fn suggest_valid_traits( diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index a078a9e00ae..2755a161d91 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -442,12 +442,10 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { self.formatting_init.extend(code_init); Ok(quote! { - let mut code: Vec<_> = #code_field.into_iter().collect(); - code.sort(); #diag.span_suggestions_with_style( #span_field, crate::fluent_generated::#slug, - code, + #code_field, #applicability, #style ); diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f7396598220..e6c46fc2528 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -186,6 +186,7 @@ fn emit_malformed_attribute( msg.push_str(&format!("`{code}`")); suggestions.push(code); } + suggestions.sort(); if should_warn(name) { sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, msg); } else { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3b59af89a98..ce4e0eecf39 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1639,9 +1639,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } else { 3 }; - return Some((order, item.name)); + Some((order, item.name)) + } else { + None } - None }) .collect::>(); items.sort_by_key(|(order, _)| *order); @@ -2147,11 +2148,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { if suggest_only_tuple_variants { // Suggest only tuple variants regardless of whether they have fields and do not // suggest path with added parentheses. - let suggestable_variants = variants + let mut suggestable_variants = variants .iter() .filter(|(.., kind)| *kind == CtorKind::Fn) .map(|(variant, ..)| path_names_to_string(variant)) .collect::>(); + suggestable_variants.sort(); let non_suggestable_variant_count = variants.len() - suggestable_variants.len(); @@ -2202,7 +2204,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } }; - let suggestable_variants = variants + let mut suggestable_variants = variants .iter() .filter(|(_, def_id, kind)| !needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) @@ -2211,6 +2213,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { CtorKind::Fn => format!("({variant}())"), }) .collect::>(); + suggestable_variants.sort(); let no_suggestable_variant = suggestable_variants.is_empty(); if !no_suggestable_variant { @@ -2228,7 +2231,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ); } - let suggestable_variants_with_placeholders = variants + let mut suggestable_variants_with_placeholders = variants .iter() .filter(|(_, def_id, kind)| needs_placeholder(*def_id, *kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) @@ -2237,6 +2240,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { _ => None, }) .collect::>(); + suggestable_variants_with_placeholders.sort(); if !suggestable_variants_with_placeholders.is_empty() { let msg = diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs index d4f2e316890..2cb599964d2 100644 --- a/src/tools/clippy/clippy_lints/src/booleans.rs +++ b/src/tools/clippy/clippy_lints/src/booleans.rs @@ -424,8 +424,9 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> { improvements.push(suggestion); } } - let nonminimal_bool_lint = |suggestions: Vec<_>| { + let nonminimal_bool_lint = |mut suggestions: Vec<_>| { if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).0 != Level::Allow { + suggestions.sort(); span_lint_hir_and_then( self.cx, NONMINIMAL_BOOL, diff --git a/tests/ui/parser/bad-pointer-type.stderr b/tests/ui/parser/bad-pointer-type.stderr index b7225ca887d..e843c49886b 100644 --- a/tests/ui/parser/bad-pointer-type.stderr +++ b/tests/ui/parser/bad-pointer-type.stderr @@ -6,10 +6,10 @@ LL | fn foo(_: *()) { | help: add `mut` or `const` here | -LL | fn foo(_: *const ()) { - | +++++ LL | fn foo(_: *mut ()) { | +++ +LL | fn foo(_: *const ()) { + | +++++ error: aborting due to previous error diff --git a/tests/ui/parser/double-pointer.stderr b/tests/ui/parser/double-pointer.stderr index 28037f93265..10aedbb92a1 100644 --- a/tests/ui/parser/double-pointer.stderr +++ b/tests/ui/parser/double-pointer.stderr @@ -6,10 +6,10 @@ LL | let dptr: **const i32 = &ptr; | help: add `mut` or `const` here | -LL | let dptr: *const *const i32 = &ptr; - | +++++ LL | let dptr: *mut *const i32 = &ptr; | +++ +LL | let dptr: *const *const i32 = &ptr; + | +++++ error: aborting due to previous error -- cgit 1.4.1-3-g733a5 From 1dfec45dc99d7d699bdf470d042300102e1589bc Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 8 Nov 2023 23:23:26 +0000 Subject: Remove unnecessary .collect() --- compiler/rustc_errors/src/diagnostic.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'compiler/rustc_errors/src') diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 1c1da89c557..0aaa8ae69e1 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -777,15 +777,15 @@ impl Diagnostic { applicability: Applicability, style: SuggestionStyle, ) -> &mut Self { - let suggestions: Vec<_> = suggestions.into_iter().collect(); - debug_assert!( - !(sp.is_empty() && suggestions.iter().any(|suggestion| suggestion.is_empty())), - "Span must not be empty and have no suggestion" - ); - let substitutions = suggestions .into_iter() - .map(|snippet| Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] }) + .map(|snippet| { + debug_assert!( + !(sp.is_empty() && snippet.is_empty()), + "Span must not be empty and have no suggestion" + ); + Substitution { parts: vec![SubstitutionPart { snippet, span: sp }] } + }) .collect(); self.push_suggestion(CodeSuggestion { substitutions, -- cgit 1.4.1-3-g733a5