diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index ac63a075ac65f..5d56b0ffe8de9 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -196,25 +196,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ParenthesizedGenericArgs::Err => { let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); err.span_label(data.span, "only `Fn` traits may use parentheses"); - if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { - // Do not suggest going from `Trait()` to `Trait<>` - if !data.inputs.is_empty() { - // Suggest replacing `(` and `)` with `<` and `>` - // The snippet may be missing the closing `)`, skip that case - if snippet.ends_with(')') { - if let Some(split) = snippet.find('(') { - let trait_name = &snippet[0..split]; - let args = &snippet[split + 1..snippet.len() - 1]; - err.span_suggestion( - data.span, - "use angle brackets instead", - format!("{}<{}>", trait_name, args), - Applicability::MaybeIncorrect, - ); - } - } - } - }; + // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait` + if !data.inputs.is_empty() { + // Start of the span to the 1st character of 1st argument + let open_param = data.inputs_span.shrink_to_lo().to(data + .inputs + .first() + .unwrap() + .span + .shrink_to_lo()); + // Last character position of last argument to the end of the span + let close_param = data + .inputs + .last() + .unwrap() + .span + .shrink_to_hi() + .to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + &format!("use angle brackets instead",), + vec![ + (open_param, String::from("<")), + (close_param, String::from(">")), + ], + Applicability::MaybeIncorrect, + ); + } err.emit(); ( self.lower_angle_bracketed_parameter_data( diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 649558e1f662a..f45b94bcdff45 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -649,39 +649,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn borrow_pat_suggestion( - &self, - err: &mut Diagnostic, - pat: &Pat<'_>, - inner: &Pat<'_>, - expected: Ty<'tcx>, - ) { + // Precondition: pat is a Ref(_) pattern + fn borrow_pat_suggestion(&self, err: &mut Diagnostic, pat: &Pat<'_>) { let tcx = self.tcx; - if let PatKind::Binding(..) = inner.kind { + if let PatKind::Ref(inner, mutbl) = pat.kind + && let PatKind::Binding(_, _, binding, ..) = inner.kind { let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id); let binding_parent = tcx.hir().get(binding_parent_id); - debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent); + debug!(?inner, ?pat, ?binding_parent); + + let mutability = match mutbl { + ast::Mutability::Mut => "mut", + ast::Mutability::Not => "", + }; + match binding_parent { - hir::Node::Param(hir::Param { span, .. }) - if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) => - { - err.span_suggestion( - *span, - &format!("did you mean `{snippet}`"), - format!(" &{expected}"), - Applicability::MachineApplicable, + // Check that there is explicit type (ie this is not a closure param with inferred type) + // so we don't suggest moving something to the type that does not exist + hir::Node::Param(hir::Param { ty_span, .. }) if binding.span != *ty_span => { + err.multipart_suggestion_verbose( + format!("to take parameter `{binding}` by reference, move `&{mutability}` to the type"), + vec![ + (pat.span.until(inner.span), "".to_owned()), + (ty_span.shrink_to_lo(), format!("&{}", mutbl.prefix_str())), + ], + Applicability::MachineApplicable ); } - hir::Node::Arm(_) | hir::Node::Pat(_) => { + hir::Node::Param(_) | hir::Node::Arm(_) | hir::Node::Pat(_) => { // rely on match ergonomics or it might be nested `&&pat` - if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) { - err.span_suggestion( - pat.span, - "you can probably remove the explicit borrow", - snippet, - Applicability::MaybeIncorrect, - ); - } + err.span_suggestion_verbose( + pat.span.until(inner.span), + format!("consider removing `&{mutability}` from the pattern"), + "", + Applicability::MaybeIncorrect, + ); } _ => {} // don't provide suggestions in other cases #55175 } @@ -1836,6 +1838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { box_ty } + // Precondition: Pat is Ref(inner) fn check_pat_ref( &self, pat: &'tcx Pat<'tcx>, @@ -1853,7 +1856,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Take region, inner-type from expected type if we can, // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). + // the bad interactions of the given hack detailed in (note_1). debug!("check_pat_ref: expected={:?}", expected); match *expected.kind() { ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), @@ -1869,7 +1872,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Look for a case like `fn foo(&foo: u32)` and suggest // `fn foo(foo: &u32)` if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat, inner, expected); + self.borrow_pat_suggestion(&mut err, pat); err.emit(); } (rptr_ty, inner_ty) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 7c10ed65c4c4c..43ba2dc287490 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2363,6 +2363,7 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { #[rustc_const_unstable(feature = "const_eval_select", issue = "none")] #[lang = "const_eval_select"] #[rustc_do_not_const_check] +#[inline] pub const unsafe fn const_eval_select( arg: ARG, _called_in_const: F, diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 247bdd954589c..1212ff6f74ac3 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -45,6 +45,22 @@ use crate::sys_common::{AsInner, FromInner, IntoInner}; /// values, encoded in a less-strict variant of UTF-8. This is useful to /// understand when handling capacity and length values. /// +/// # Capacity of `OsString` +/// +/// Capacity uses units of UTF-8 bytes for OS strings which were created from valid unicode, and +/// uses units of bytes in an unspecified encoding for other contents. On a given target, all +/// `OsString` and `OsStr` values use the same units for capacity, so the following will work: +/// ``` +/// use std::ffi::{OsStr, OsString}; +/// +/// fn concat_os_strings(a: &OsStr, b: &OsStr) -> OsString { +/// let mut ret = OsString::with_capacity(a.len() + b.len()); // This will allocate +/// ret.push(a); // This will not allocate further +/// ret.push(b); // This will not allocate further +/// ret +/// } +/// ``` +/// /// # Creating an `OsString` /// /// **From a Rust string**: `OsString` implements @@ -186,7 +202,7 @@ impl OsString { /// OS strings without reallocating. If `capacity` is 0, the string will not /// allocate. /// - /// See main `OsString` documentation information about encoding. + /// See the main `OsString` documentation information about encoding and capacity units. /// /// # Examples /// @@ -229,7 +245,7 @@ impl OsString { /// Returns the capacity this `OsString` can hold without reallocating. /// - /// See `OsString` introduction for information about encoding. + /// See the main `OsString` documentation information about encoding and capacity units. /// /// # Examples /// @@ -251,6 +267,8 @@ impl OsString { /// /// The collection may reserve more space to avoid frequent reallocations. /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Examples /// /// ``` @@ -272,6 +290,8 @@ impl OsString { /// greater than or equal to `self.len() + additional`. Does nothing if /// capacity is already sufficient. /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Errors /// /// If the capacity overflows, or the allocator reports a failure, then an error @@ -313,6 +333,8 @@ impl OsString { /// /// [`reserve`]: OsString::reserve /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Examples /// /// ``` @@ -340,6 +362,8 @@ impl OsString { /// /// [`try_reserve`]: OsString::try_reserve /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Errors /// /// If the capacity overflows, or the allocator reports a failure, then an error @@ -373,6 +397,8 @@ impl OsString { /// Shrinks the capacity of the `OsString` to match its length. /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Examples /// /// ``` @@ -399,6 +425,8 @@ impl OsString { /// /// If the current capacity is less than the lower limit, this is a no-op. /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Examples /// /// ``` @@ -773,6 +801,8 @@ impl OsStr { /// This number is simply useful for passing to other methods, like /// [`OsString::with_capacity`] to avoid reallocations. /// + /// See the main `OsString` documentation information about encoding and capacity units. + /// /// # Examples /// /// ``` diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 58c036e0b3ca3..14d8a942977d6 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -32,10 +32,10 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { fullPath += elem["name"] + "/"; name.onclick = () => { - if (hasClass(this, "expand")) { - removeClass(this, "expand"); + if (hasClass(name, "expand")) { + removeClass(name, "expand"); } else { - addClass(this, "expand"); + addClass(name, "expand"); } }; name.innerText = elem["name"]; diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index f338050bee0f9..0964b757e74f5 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -181,15 +181,44 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { let name = item.name; let item_id = item.item_id; if let Some(mut new_item) = self.convert_item(item) { - if let types::ItemEnum::Trait(ref mut t) = new_item.inner { - t.implementations = self.get_trait_implementors(item_id.expect_def_id()) - } else if let types::ItemEnum::Struct(ref mut s) = new_item.inner { - s.impls = self.get_impls(item_id.expect_def_id()) - } else if let types::ItemEnum::Enum(ref mut e) = new_item.inner { - e.impls = self.get_impls(item_id.expect_def_id()) - } else if let types::ItemEnum::Union(ref mut u) = new_item.inner { - u.impls = self.get_impls(item_id.expect_def_id()) - } + let can_be_ignored = match new_item.inner { + types::ItemEnum::Trait(ref mut t) => { + t.implementations = self.get_trait_implementors(item_id.expect_def_id()); + false + } + types::ItemEnum::Struct(ref mut s) => { + s.impls = self.get_impls(item_id.expect_def_id()); + false + } + types::ItemEnum::Enum(ref mut e) => { + e.impls = self.get_impls(item_id.expect_def_id()); + false + } + types::ItemEnum::Union(ref mut u) => { + u.impls = self.get_impls(item_id.expect_def_id()); + false + } + + types::ItemEnum::Method(_) + | types::ItemEnum::AssocConst { .. } + | types::ItemEnum::AssocType { .. } => true, + types::ItemEnum::Module(_) + | types::ItemEnum::ExternCrate { .. } + | types::ItemEnum::Import(_) + | types::ItemEnum::StructField(_) + | types::ItemEnum::Variant(_) + | types::ItemEnum::Function(_) + | types::ItemEnum::TraitAlias(_) + | types::ItemEnum::Impl(_) + | types::ItemEnum::Typedef(_) + | types::ItemEnum::OpaqueTy(_) + | types::ItemEnum::Constant(_) + | types::ItemEnum::Static(_) + | types::ItemEnum::ForeignType + | types::ItemEnum::Macro(_) + | types::ItemEnum::ProcMacro(_) + | types::ItemEnum::PrimitiveType(_) => false, + }; let removed = self .index .borrow_mut() @@ -199,7 +228,11 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { // to make sure the items are unique. The main place this happens is when an item, is // reexported in more than one place. See `rustdoc-json/reexport/in_root_and_mod` if let Some(old_item) = removed { - assert_eq!(old_item, new_item); + // In case of generic implementations (like `impl Trait for T {}`), all the + // inner items will be duplicated so we can ignore if they are slightly different. + if !can_be_ignored { + assert_eq!(old_item, new_item); + } } } diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index 509739c9f2951..188b2605f0f13 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -1,4 +1,4 @@ -// Checks that the interactions with the source code pages are workined as expected. +// Checks that the interactions with the source code pages are working as expected. goto: file://|DOC_PATH|/src/test_docs/lib.rs.html // Check that we can click on the line number. click: ".line-numbers > span:nth-child(4)" // This is the span for line 4. @@ -27,3 +27,26 @@ assert-position: ("//*[@id='1']", {"x": 104, "y": 103}) // We click on the left of the "1" span but still in the "line-number" `
`.
 click: (103, 103)
 assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)
+
+// Checking the source code sidebar.
+
+// First we "open" it.
+click: "#sidebar-toggle"
+assert: ".sidebar.expanded"
+
+// We check that the first entry of the sidebar is collapsed (which, for whatever reason,
+// is number 2 and not 1...).
+assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name"})
+assert-text: ("#source-sidebar .name:nth-child(2)", "implementors")
+// We also check its children are hidden too.
+assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "none"})
+// We now click on it.
+click: "#source-sidebar .name:nth-child(2)"
+assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name expand"})
+// Checking that its children are displayed as well.
+assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "block"})
+
+// And now we collapse it again.
+click: "#source-sidebar .name:nth-child(2)"
+assert-attribute: ("#source-sidebar .name:nth-child(2)", {"class": "name"})
+assert-css: ("#source-sidebar .name:nth-child(2) + .children", {"display": "none"})
diff --git a/src/test/rustdoc-json/generic_impl.rs b/src/test/rustdoc-json/generic_impl.rs
new file mode 100644
index 0000000000000..ac68ba578b6fb
--- /dev/null
+++ b/src/test/rustdoc-json/generic_impl.rs
@@ -0,0 +1,24 @@
+// Regression test for .
+
+// @has generic_impl.json
+// @has - "$.index[*][?(@.name=='f')]"
+// @has - "$.index[*][?(@.name=='AssocTy')]"
+// @has - "$.index[*][?(@.name=='AssocConst')]"
+
+pub mod m {
+    pub struct S;
+}
+
+pub trait F {
+    type AssocTy;
+    const AssocConst: usize;
+    fn f() -> m::S;
+}
+
+impl F for T {
+    type AssocTy = u32;
+    const AssocConst: usize = 0;
+    fn f() -> m::S {
+        m::S
+    }
+}
diff --git a/src/test/ui/associated-consts/issue-93775.rs b/src/test/ui/associated-consts/issue-93775.rs
new file mode 100644
index 0000000000000..7a007b732de8e
--- /dev/null
+++ b/src/test/ui/associated-consts/issue-93775.rs
@@ -0,0 +1,29 @@
+// build-pass
+// ignore-tidy-linelength
+
+// Regression for #93775, needs build-pass to test it.
+
+#![recursion_limit = "1000"]
+
+use std::marker::PhantomData;
+
+struct Z;
+struct S(PhantomData);
+
+type Nested = S>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
+
+trait AsNum {
+    const NUM: u32;
+}
+
+impl AsNum for Z {
+    const NUM: u32 = 0;
+}
+
+impl AsNum for S {
+    const NUM: u32 = T::NUM + 1;
+}
+
+fn main() {
+    let _ = Nested::NUM;
+}
diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr
index 302917ca02e00..1291517928e3d 100644
--- a/src/test/ui/destructure-trait-ref.stderr
+++ b/src/test/ui/destructure-trait-ref.stderr
@@ -23,10 +23,14 @@ LL |     let &&x = &1isize as &dyn T;
    |          ^^   ----------------- this expression has type `&dyn T`
    |          |
    |          expected trait object `dyn T`, found reference
-   |          help: you can probably remove the explicit borrow: `x`
    |
    = note: expected trait object `dyn T`
                  found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let &&x = &1isize as &dyn T;
+LL +     let &x = &1isize as &dyn T;
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/destructure-trait-ref.rs:36:11
@@ -35,10 +39,14 @@ LL |     let &&&x = &(&1isize as &dyn T);
    |           ^^   -------------------- this expression has type `&&dyn T`
    |           |
    |           expected trait object `dyn T`, found reference
-   |           help: you can probably remove the explicit borrow: `x`
    |
    = note: expected trait object `dyn T`
                  found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let &&&x = &(&1isize as &dyn T);
+LL +     let &&x = &(&1isize as &dyn T);
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/destructure-trait-ref.rs:40:13
diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr
index bcbd3a91cb951..e0179aac27fb3 100644
--- a/src/test/ui/error-codes/E0214.stderr
+++ b/src/test/ui/error-codes/E0214.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/E0214.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!["foo"];
-   |            ^^^^^^^^^
-   |            |
-   |            only `Fn` traits may use parentheses
-   |            help: use angle brackets instead: `Vec<&str>`
+   |            ^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let v: Vec<&str> = vec!["foo"];
+   |               ~    ~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr
index e065e17c280f9..1a91f5e04dbce 100644
--- a/src/test/ui/issues/issue-23589.stderr
+++ b/src/test/ui/issues/issue-23589.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/issue-23589.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!['1', '2'];
-   |            ^^^^^^^^^
-   |            |
-   |            only `Fn` traits may use parentheses
-   |            help: use angle brackets instead: `Vec<&str>`
+   |            ^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let v: Vec<&str> = vec!['1', '2'];
+   |               ~    ~
 
 error[E0308]: mismatched types
   --> $DIR/issue-23589.rs:2:29
diff --git a/src/test/ui/mismatched_types/issue-38371-unfixable.rs b/src/test/ui/mismatched_types/issue-38371-unfixable.rs
new file mode 100644
index 0000000000000..c4316bfdd18dc
--- /dev/null
+++ b/src/test/ui/mismatched_types/issue-38371-unfixable.rs
@@ -0,0 +1,5 @@
+fn ugh(&[bar]: &u32) {} //~ ERROR expected an array or slice
+
+fn bgh(&&bar: u32) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/mismatched_types/issue-38371-unfixable.stderr b/src/test/ui/mismatched_types/issue-38371-unfixable.stderr
new file mode 100644
index 0000000000000..3c5e765abfbe2
--- /dev/null
+++ b/src/test/ui/mismatched_types/issue-38371-unfixable.stderr
@@ -0,0 +1,21 @@
+error[E0529]: expected an array or slice, found `u32`
+  --> $DIR/issue-38371-unfixable.rs:1:9
+   |
+LL | fn ugh(&[bar]: &u32) {}
+   |         ^^^^^ pattern cannot match with input type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-38371-unfixable.rs:3:8
+   |
+LL | fn bgh(&&bar: u32) {}
+   |        ^^^^^  --- expected due to this
+   |        |
+   |        expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0529.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/issue-38371.fixed b/src/test/ui/mismatched_types/issue-38371.fixed
new file mode 100644
index 0000000000000..0e20835bef05f
--- /dev/null
+++ b/src/test/ui/mismatched_types/issue-38371.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+// see also issue-38371-unfixable.rs
+#![allow(dead_code)]
+
+#[derive(Copy, Clone)]
+struct Foo {}
+
+fn foo(_a: &Foo) {} //~ ERROR mismatched types
+
+fn bar(_a: Foo) {}
+
+fn qux(_a: &Foo) {}
+
+fn zar(&_a: &Foo) {}
+
+fn agh(&_a: &u32) {} //~ ERROR mismatched types
+
+fn main() {}
diff --git a/src/test/ui/mismatched_types/issue-38371.rs b/src/test/ui/mismatched_types/issue-38371.rs
index d2cd2b88ab706..fb9e4c173e7a8 100644
--- a/src/test/ui/mismatched_types/issue-38371.rs
+++ b/src/test/ui/mismatched_types/issue-38371.rs
@@ -1,27 +1,18 @@
-struct Foo {
-}
+// run-rustfix
+// see also issue-38371-unfixable.rs
+#![allow(dead_code)]
 
-fn foo(&foo: Foo) { //~ ERROR mismatched types
-}
+#[derive(Copy, Clone)]
+struct Foo {}
 
-fn bar(foo: Foo) {
-}
+fn foo(&_a: Foo) {} //~ ERROR mismatched types
 
-fn qux(foo: &Foo) {
-}
+fn bar(_a: Foo) {}
 
-fn zar(&foo: &Foo) {
-}
+fn qux(_a: &Foo) {}
 
-// The somewhat unexpected help message in this case is courtesy of
-// match_default_bindings.
-fn agh(&&bar: &u32) { //~ ERROR mismatched types
-}
+fn zar(&_a: &Foo) {}
 
-fn bgh(&&bar: u32) { //~ ERROR mismatched types
-}
-
-fn ugh(&[bar]: &u32) { //~ ERROR expected an array or slice
-}
+fn agh(&&_a: &u32) {} //~ ERROR mismatched types
 
 fn main() {}
diff --git a/src/test/ui/mismatched_types/issue-38371.stderr b/src/test/ui/mismatched_types/issue-38371.stderr
index 5d2ce9302ece6..003f17cda1553 100644
--- a/src/test/ui/mismatched_types/issue-38371.stderr
+++ b/src/test/ui/mismatched_types/issue-38371.stderr
@@ -1,46 +1,35 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:4:8
+  --> $DIR/issue-38371.rs:8:8
    |
-LL | fn foo(&foo: Foo) {
-   |        ^^^^-----
-   |        |     |
-   |        |     expected due to this
+LL | fn foo(&_a: Foo) {}
+   |        ^^^  --- expected due to this
+   |        |
    |        expected struct `Foo`, found reference
-   |        help: did you mean `foo`: `&Foo`
    |
    = note: expected struct `Foo`
            found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+   |
+LL - fn foo(&_a: Foo) {}
+LL + fn foo(_a: &Foo) {}
+   | 
 
 error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:18:9
+  --> $DIR/issue-38371.rs:16:9
    |
-LL | fn agh(&&bar: &u32) {
-   |         ^^^^  ---- expected due to this
+LL | fn agh(&&_a: &u32) {}
+   |         ^^^  ---- expected due to this
    |         |
    |         expected `u32`, found reference
-   |         help: you can probably remove the explicit borrow: `bar`
-   |
-   = note:   expected type `u32`
-           found reference `&_`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-38371.rs:21:8
-   |
-LL | fn bgh(&&bar: u32) {
-   |        ^^^^^  --- expected due to this
-   |        |
-   |        expected `u32`, found reference
    |
    = note:   expected type `u32`
            found reference `&_`
-
-error[E0529]: expected an array or slice, found `u32`
-  --> $DIR/issue-38371.rs:24:9
+help: consider removing `&` from the pattern
    |
-LL | fn ugh(&[bar]: &u32) {
-   |         ^^^^^ pattern cannot match with input type `u32`
+LL - fn agh(&&_a: &u32) {}
+LL + fn agh(&_a: &u32) {}
+   | 
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0308, E0529.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/mismatched_types/ref-pat-suggestions.fixed b/src/test/ui/mismatched_types/ref-pat-suggestions.fixed
new file mode 100644
index 0000000000000..ab8483eef49fa
--- /dev/null
+++ b/src/test/ui/mismatched_types/ref-pat-suggestions.fixed
@@ -0,0 +1,24 @@
+// run-rustfix
+
+fn _f0(_a: &u32) {} //~ ERROR mismatched types
+fn _f1(_a: &mut u32) {} //~ ERROR mismatched types
+fn _f2(&_a: &u32) {} //~ ERROR mismatched types
+fn _f3(&mut _a: &mut u32) {} //~ ERROR mismatched types
+fn _f4(&_a: &u32) {} //~ ERROR mismatched types
+fn _f5(&mut _a: &mut u32) {} //~ ERROR mismatched types
+
+fn main() {
+    let _: fn(u32) = |_a| (); //~ ERROR mismatched types
+    let _: fn(u32) = |_a| (); //~ ERROR mismatched types
+    let _: fn(&u32) = |&_a| (); //~ ERROR mismatched types
+    let _: fn(&mut u32) = |&mut _a| (); //~ ERROR mismatched types
+    let _: fn(&u32) = |&_a| (); //~ ERROR mismatched types
+    let _: fn(&mut u32) = |&mut _a| (); //~ ERROR mismatched types
+
+    let _ = |_a: &u32| (); //~ ERROR mismatched types
+    let _ = |_a: &mut u32| (); //~ ERROR mismatched types
+    let _ = |&_a: &u32| (); //~ ERROR mismatched types
+    let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
+    let _ = |&_a: &u32| (); //~ ERROR mismatched types
+    let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/mismatched_types/ref-pat-suggestions.rs b/src/test/ui/mismatched_types/ref-pat-suggestions.rs
new file mode 100644
index 0000000000000..7e55539aa3d1b
--- /dev/null
+++ b/src/test/ui/mismatched_types/ref-pat-suggestions.rs
@@ -0,0 +1,24 @@
+// run-rustfix
+
+fn _f0(&_a: u32) {} //~ ERROR mismatched types
+fn _f1(&mut _a: u32) {} //~ ERROR mismatched types
+fn _f2(&&_a: &u32) {} //~ ERROR mismatched types
+fn _f3(&mut &_a: &mut u32) {} //~ ERROR mismatched types
+fn _f4(&&mut _a: &u32) {} //~ ERROR mismatched types
+fn _f5(&mut &mut _a: &mut u32) {} //~ ERROR mismatched types
+
+fn main() {
+    let _: fn(u32) = |&_a| (); //~ ERROR mismatched types
+    let _: fn(u32) = |&mut _a| (); //~ ERROR mismatched types
+    let _: fn(&u32) = |&&_a| (); //~ ERROR mismatched types
+    let _: fn(&mut u32) = |&mut &_a| (); //~ ERROR mismatched types
+    let _: fn(&u32) = |&&mut _a| (); //~ ERROR mismatched types
+    let _: fn(&mut u32) = |&mut &mut _a| (); //~ ERROR mismatched types
+
+    let _ = |&_a: u32| (); //~ ERROR mismatched types
+    let _ = |&mut _a: u32| (); //~ ERROR mismatched types
+    let _ = |&&_a: &u32| (); //~ ERROR mismatched types
+    let _ = |&mut &_a: &mut u32| (); //~ ERROR mismatched types
+    let _ = |&&mut _a: &u32| (); //~ ERROR mismatched types
+    let _ = |&mut &mut _a: &mut u32| (); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/mismatched_types/ref-pat-suggestions.stderr b/src/test/ui/mismatched_types/ref-pat-suggestions.stderr
new file mode 100644
index 0000000000000..0516bad49abf3
--- /dev/null
+++ b/src/test/ui/mismatched_types/ref-pat-suggestions.stderr
@@ -0,0 +1,297 @@
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:3:8
+   |
+LL | fn _f0(&_a: u32) {}
+   |        ^^^  --- expected due to this
+   |        |
+   |        expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+   |
+LL - fn _f0(&_a: u32) {}
+LL + fn _f0(_a: &u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:4:8
+   |
+LL | fn _f1(&mut _a: u32) {}
+   |        ^^^^^^^  --- expected due to this
+   |        |
+   |        expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: to take parameter `_a` by reference, move `&mut` to the type
+   |
+LL - fn _f1(&mut _a: u32) {}
+LL + fn _f1(_a: &mut u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:5:9
+   |
+LL | fn _f2(&&_a: &u32) {}
+   |         ^^^  ---- expected due to this
+   |         |
+   |         expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - fn _f2(&&_a: &u32) {}
+LL + fn _f2(&_a: &u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:6:13
+   |
+LL | fn _f3(&mut &_a: &mut u32) {}
+   |             ^^^  -------- expected due to this
+   |             |
+   |             expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL - fn _f3(&mut &_a: &mut u32) {}
+LL + fn _f3(&mut _a: &mut u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:7:9
+   |
+LL | fn _f4(&&mut _a: &u32) {}
+   |         ^^^^^^^  ---- expected due to this
+   |         |
+   |         expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL - fn _f4(&&mut _a: &u32) {}
+LL + fn _f4(&_a: &u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:8:13
+   |
+LL | fn _f5(&mut &mut _a: &mut u32) {}
+   |             ^^^^^^^  -------- expected due to this
+   |             |
+   |             expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL - fn _f5(&mut &mut _a: &mut u32) {}
+LL + fn _f5(&mut _a: &mut u32) {}
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:11:23
+   |
+LL |     let _: fn(u32) = |&_a| ();
+   |                       ^--
+   |                       ||
+   |                       |expected due to this
+   |                       expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let _: fn(u32) = |&_a| ();
+LL +     let _: fn(u32) = |_a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:12:23
+   |
+LL |     let _: fn(u32) = |&mut _a| ();
+   |                       ^^^^^--
+   |                       |    |
+   |                       |    expected due to this
+   |                       expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     let _: fn(u32) = |&mut _a| ();
+LL +     let _: fn(u32) = |_a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:13:25
+   |
+LL |     let _: fn(&u32) = |&&_a| ();
+   |                         ^--
+   |                         ||
+   |                         |expected due to this
+   |                         expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let _: fn(&u32) = |&&_a| ();
+LL +     let _: fn(&u32) = |&_a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:14:33
+   |
+LL |     let _: fn(&mut u32) = |&mut &_a| ();
+   |                                 ^--
+   |                                 ||
+   |                                 |expected due to this
+   |                                 expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let _: fn(&mut u32) = |&mut &_a| ();
+LL +     let _: fn(&mut u32) = |&mut _a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:15:25
+   |
+LL |     let _: fn(&u32) = |&&mut _a| ();
+   |                         ^^^^^--
+   |                         |    |
+   |                         |    expected due to this
+   |                         expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     let _: fn(&u32) = |&&mut _a| ();
+LL +     let _: fn(&u32) = |&_a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:16:33
+   |
+LL |     let _: fn(&mut u32) = |&mut &mut _a| ();
+   |                                 ^^^^^--
+   |                                 |    |
+   |                                 |    expected due to this
+   |                                 expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     let _: fn(&mut u32) = |&mut &mut _a| ();
+LL +     let _: fn(&mut u32) = |&mut _a| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:18:14
+   |
+LL |     let _ = |&_a: u32| ();
+   |              ^^^  --- expected due to this
+   |              |
+   |              expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: to take parameter `_a` by reference, move `&` to the type
+   |
+LL -     let _ = |&_a: u32| ();
+LL +     let _ = |_a: &u32| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:19:14
+   |
+LL |     let _ = |&mut _a: u32| ();
+   |              ^^^^^^^  --- expected due to this
+   |              |
+   |              expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: to take parameter `_a` by reference, move `&mut` to the type
+   |
+LL -     let _ = |&mut _a: u32| ();
+LL +     let _ = |_a: &mut u32| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:20:15
+   |
+LL |     let _ = |&&_a: &u32| ();
+   |               ^^^  ---- expected due to this
+   |               |
+   |               expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let _ = |&&_a: &u32| ();
+LL +     let _ = |&_a: &u32| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:21:19
+   |
+LL |     let _ = |&mut &_a: &mut u32| ();
+   |                   ^^^  -------- expected due to this
+   |                   |
+   |                   expected `u32`, found reference
+   |
+   = note:   expected type `u32`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     let _ = |&mut &_a: &mut u32| ();
+LL +     let _ = |&mut _a: &mut u32| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:22:15
+   |
+LL |     let _ = |&&mut _a: &u32| ();
+   |               ^^^^^^^  ---- expected due to this
+   |               |
+   |               expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     let _ = |&&mut _a: &u32| ();
+LL +     let _ = |&_a: &u32| ();
+   | 
+
+error[E0308]: mismatched types
+  --> $DIR/ref-pat-suggestions.rs:23:19
+   |
+LL |     let _ = |&mut &mut _a: &mut u32| ();
+   |                   ^^^^^^^  -------- expected due to this
+   |                   |
+   |                   expected `u32`, found `&mut _`
+   |
+   = note:           expected type `u32`
+           found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     let _ = |&mut &mut _a: &mut u32| ();
+LL +     let _ = |&mut _a: &mut u32| ();
+   | 
+
+error: aborting due to 18 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/pattern/for-loop-bad-item.stderr b/src/test/ui/pattern/for-loop-bad-item.stderr
index 9410e4da8d2af..886d815d70bea 100644
--- a/src/test/ui/pattern/for-loop-bad-item.stderr
+++ b/src/test/ui/pattern/for-loop-bad-item.stderr
@@ -5,10 +5,14 @@ LL |     for ((_, _), (&mut c, _)) in &mut map {
    |                   ^^^^^^         -------- this is an iterator with items of type `(&(char, char), &mut (char, char))`
    |                   |
    |                   expected `char`, found `&mut _`
-   |                   help: you can probably remove the explicit borrow: `c`
    |
    = note:           expected type `char`
            found mutable reference `&mut _`
+help: consider removing `&mut` from the pattern
+   |
+LL -     for ((_, _), (&mut c, _)) in &mut map {
+LL +     for ((_, _), (c, _)) in &mut map {
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/for-loop-bad-item.rs:14:14
diff --git a/src/test/ui/proc-macro/issue-66286.stderr b/src/test/ui/proc-macro/issue-66286.stderr
index 2854dd7d59c5e..fe2464b3b8115 100644
--- a/src/test/ui/proc-macro/issue-66286.stderr
+++ b/src/test/ui/proc-macro/issue-66286.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/issue-66286.rs:8:22
    |
 LL | pub extern fn foo(_: Vec(u32)) -> u32 {
-   |                      ^^^^^^^^
-   |                      |
-   |                      only `Fn` traits may use parentheses
-   |                      help: use angle brackets instead: `Vec`
+   |                      ^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL | pub extern fn foo(_: Vec) -> u32 {
+   |                         ~   ~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
index 63ba7893f0414..2bf072ef52175 100644
--- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
+++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
@@ -10,10 +10,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/let-binding-init-expr-as-ty.rs:2:19
    |
 LL |     let foo: i32::from_be(num);
-   |                   ^^^^^^^^^^^^
-   |                   |
-   |                   only `Fn` traits may use parentheses
-   |                   help: use angle brackets instead: `from_be`
+   |                   ^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let foo: i32::from_be;
+   |                          ~   ~
 
 error[E0223]: ambiguous associated type
   --> $DIR/let-binding-init-expr-as-ty.rs:2:14
diff --git a/src/test/ui/suggestions/match-ergonomics.stderr b/src/test/ui/suggestions/match-ergonomics.stderr
index 4eab2df30801e..a9342f9fc309d 100644
--- a/src/test/ui/suggestions/match-ergonomics.stderr
+++ b/src/test/ui/suggestions/match-ergonomics.stderr
@@ -4,13 +4,15 @@ error[E0308]: mismatched types
 LL |     match &x[..] {
    |           ------ this expression has type `&[i32]`
 LL |         [&v] => {},
-   |          ^^
-   |          |
-   |          expected `i32`, found reference
-   |          help: you can probably remove the explicit borrow: `v`
+   |          ^^ expected `i32`, found reference
    |
    = note:   expected type `i32`
            found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -         [&v] => {},
+LL +         [v] => {},
+   | 
 
 error[E0529]: expected an array or slice, found `Vec`
   --> $DIR/match-ergonomics.rs:8:9
@@ -34,13 +36,15 @@ error[E0308]: mismatched types
 LL |     match y {
    |           - this expression has type `i32`
 LL |         &v => {},
-   |         ^^
-   |         |
-   |         expected `i32`, found reference
-   |         help: you can probably remove the explicit borrow: `v`
+   |         ^^ expected `i32`, found reference
    |
    = note:   expected type `i32`
            found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -         &v => {},
+LL +         v => {},
+   | 
 
 error[E0308]: mismatched types
   --> $DIR/match-ergonomics.rs:40:13
@@ -49,10 +53,14 @@ LL |     if let [&v] = &x[..] {}
    |             ^^    ------ this expression has type `&[i32]`
    |             |
    |             expected `i32`, found reference
-   |             help: you can probably remove the explicit borrow: `v`
    |
    = note:   expected type `i32`
            found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL -     if let [&v] = &x[..] {}
+LL +     if let [v] = &x[..] {}
+   | 
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr
index 199fd6a23f755..71c357865fed9 100644
--- a/src/test/ui/type/issue-91268.stderr
+++ b/src/test/ui/type/issue-91268.stderr
@@ -29,6 +29,11 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
    |
 LL |     0: u8(ţ
    |        ^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     0: u8<ţ>
+   |          ~ +
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/issue-91268.rs:9:11
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
index f5cf6db30f99c..4df404e8198fa 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13
    |
 LL |     let b = Bar::(isize, usize)::new(); // OK too (for the parser)
-   |             ^^^^^^^^^^^^^^^^^^^
-   |             |
-   |             only `Fn` traits may use parentheses
-   |             help: use angle brackets instead: `Bar::`
+   |             ^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let b = Bar::::new(); // OK too (for the parser)
+   |                  ~            ~
 
 error: aborting due to previous error