about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-01-12 17:11:03 +0000
committerbors <bors@rust-lang.org>2023-01-12 17:11:03 +0000
commit1bc3683b3275a5eb2ed13d24edcdcbc59afe5d70 (patch)
tree45a2cd6613ff1e78a0a43ffb8e665b41df71bcec
parent222d1ff68d5bfe1dc2d7f3f0c42811fe12964af9 (diff)
parent89f9569d54452bb0b93f75aaee720c487ed2b37a (diff)
downloadrust-1bc3683b3275a5eb2ed13d24edcdcbc59afe5d70.tar.gz
rust-1bc3683b3275a5eb2ed13d24edcdcbc59afe5d70.zip
Auto merge of #106773 - Nilstrieb:rollup-sq73pyg, r=Nilstrieb
Rollup of 6 pull requests

Successful merges:

 - #105806 (Support eager subdiagnostics again)
 - #106322 (Handle inference variables in `CollectAllMismatches` correctly)
 - #106579 (Suggest making private tuple struct field public)
 - #106714 (remove unreachable error code `E0490`)
 - #106751 (Fix rendering 'const' in header for intrinsics)
 - #106761 (Add `WaffleLapkin` to compiler reviewers)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs2
-rw-r--r--compiler/rustc_error_messages/locales/en-US/infer.ftl1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs35
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs25
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs4
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs24
-rw-r--r--compiler/rustc_macros/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs14
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs14
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs11
-rw-r--r--compiler/rustc_resolve/src/lib.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs13
-rw-r--r--src/librustdoc/clean/types.rs12
-rw-r--r--src/tools/tidy/src/error_codes.rs6
-rw-r--r--tests/rustdoc/const-intrinsic.rs25
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs2
-rw-r--r--tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr32
-rw-r--r--tests/ui/consts/ct-var-in-collect_all_mismatches.rs20
-rw-r--r--tests/ui/consts/ct-var-in-collect_all_mismatches.stderr22
-rw-r--r--tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs4
-rw-r--r--tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr24
-rw-r--r--tests/ui/privacy/issue-75906.stderr4
-rw-r--r--tests/ui/privacy/issue-75907.rs2
-rw-r--r--tests/ui/privacy/issue-75907.stderr8
-rw-r--r--tests/ui/privacy/privacy5.stderr96
-rw-r--r--tests/ui/privacy/suggest-making-field-public.fixed15
-rw-r--r--tests/ui/privacy/suggest-making-field-public.rs15
-rw-r--r--tests/ui/privacy/suggest-making-field-public.stderr39
-rw-r--r--tests/ui/resolve/issue-42944.rs2
-rw-r--r--tests/ui/resolve/issue-42944.stderr12
-rw-r--r--tests/ui/resolve/privacy-struct-ctor.stderr16
-rw-r--r--triagebot.toml1
32 files changed, 395 insertions, 111 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index a132a8146e9..24258974bb9 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -618,7 +618,7 @@ E0791: include_str!("./error_codes/E0791.md"),
 //  E0487, // unsafe use of destructor: destructor might be called while...
 //  E0488, // lifetime of variable does not enclose its declaration
 //  E0489, // type/lifetime parameter not in scope here
-    E0490, // a value of type `..` is borrowed for too long
+//  E0490, // removed: unreachable
     E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
 //  E0526, // shuffle indices are not constant
 //  E0540, // multiple rustc_deprecated attributes
diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl
index c1cb07cf0df..ae0091b0373 100644
--- a/compiler/rustc_error_messages/locales/en-US/infer.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl
@@ -101,7 +101,6 @@ infer_subtype_2 = ...so that {$requirement ->
 infer_reborrow = ...so that reference does not outlive borrowed content
 infer_reborrow_upvar = ...so that closure can access `{$name}`
 infer_relate_object_bound = ...so that it can be closed over into an object
-infer_data_borrowed = ...so that the type `{$name}` is not borrowed for too long
 infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
 infer_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
     [true] ...
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index 7bb79d7bda8..7504ed094a3 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -29,15 +29,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 RegionOriginNote::Plain { span, msg: fluent::infer_relate_object_bound }
                     .add_to_diagnostic(err);
             }
-            infer::DataBorrowed(ty, span) => {
-                RegionOriginNote::WithName {
-                    span,
-                    msg: fluent::infer_data_borrowed,
-                    name: &self.ty_to_string(ty),
-                    continues: false,
-                }
-                .add_to_diagnostic(err);
-            }
             infer::ReferenceOutlivesReferent(ty, span) => {
                 RegionOriginNote::WithName {
                     span,
@@ -227,32 +218,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 );
                 err
             }
-            infer::DataBorrowed(ty, span) => {
-                let mut err = struct_span_err!(
-                    self.tcx.sess,
-                    span,
-                    E0490,
-                    "a value of type `{}` is borrowed for too long",
-                    self.ty_to_string(ty)
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    &mut err,
-                    "the type is valid for ",
-                    sub,
-                    "",
-                    None,
-                );
-                note_and_explain_region(
-                    self.tcx,
-                    &mut err,
-                    "but the borrow lasts for ",
-                    sup,
-                    "",
-                    None,
-                );
-                err
-            }
             infer::ReferenceOutlivesReferent(ty, span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index da2c6fbc05f..897545046c3 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -702,26 +702,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                     // Obtain the spans for all the places that can
                     // influence the constraints on this value for
                     // richer diagnostics in `static_impl_trait`.
-                    let influences: Vec<Span> = self
-                        .data
-                        .constraints
-                        .iter()
-                        .filter_map(|(constraint, origin)| match (constraint, origin) {
-                            (
-                                Constraint::VarSubVar(_, sup),
-                                SubregionOrigin::DataBorrowed(_, sp),
-                            ) if sup == &node_vid => Some(*sp),
-                            _ => None,
-                        })
-                        .collect();
-
-                    self.collect_error_for_expanding_node(
-                        graph,
-                        &mut dup_vec,
-                        node_vid,
-                        errors,
-                        influences,
-                    );
+
+                    self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors);
                 }
             }
         }
@@ -775,7 +757,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         dup_vec: &mut IndexVec<RegionVid, Option<RegionVid>>,
         node_idx: RegionVid,
         errors: &mut Vec<RegionResolutionError<'tcx>>,
-        influences: Vec<Span>,
     ) {
         // Errors in expanding nodes result from a lower-bound that is
         // not contained by an upper-bound.
@@ -830,7 +811,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                         lower_bound.region,
                         upper_bound.origin.clone(),
                         upper_bound.region,
-                        influences,
+                        vec![],
                     ));
                     return;
                 }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 8825b5e12c3..4acd0d0edfe 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -410,9 +410,6 @@ pub enum SubregionOrigin<'tcx> {
     /// Creating a pointer `b` to contents of another reference
     Reborrow(Span),
 
-    /// Data with type `Ty<'tcx>` was borrowed
-    DataBorrowed(Ty<'tcx>, Span),
-
     /// (&'a &'b T) where a >= b
     ReferenceOutlivesReferent(Ty<'tcx>, Span),
 
@@ -1978,7 +1975,6 @@ impl<'tcx> SubregionOrigin<'tcx> {
             RelateParamBound(a, ..) => a,
             RelateRegionParamBound(a) => a,
             Reborrow(a) => a,
-            DataBorrowed(_, a) => a,
             ReferenceOutlivesReferent(_, a) => a,
             CompareImplItemObligation { span, .. } => span,
             AscribeUserTypeProvePredicate(span) => span,
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
index 82f6812026a..e405462bbb8 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs
@@ -382,10 +382,26 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
                     return Ok(quote! { #diag.subdiagnostic(#binding); });
                 }
             }
-            (Meta::List(_), "subdiagnostic") => {
-                throw_invalid_attr!(attr, &meta, |diag| {
-                    diag.help("`subdiagnostic` does not support nested attributes")
-                })
+            (Meta::List(MetaList { ref nested, .. }), "subdiagnostic") => {
+                if nested.len() == 1
+                    && let Some(NestedMeta::Meta(Meta::Path(path))) = nested.first()
+                    && path.is_ident("eager") {
+                        let handler = match &self.parent.kind {
+                            DiagnosticDeriveKind::Diagnostic { handler } => handler,
+                            DiagnosticDeriveKind::LintDiagnostic => {
+                                throw_invalid_attr!(attr, &meta, |diag| {
+                                    diag.help("eager subdiagnostics are not supported on lints")
+                                })
+                            }
+                        };
+                        return Ok(quote! { #diag.eager_subdiagnostic(#handler, #binding); });
+                } else {
+                    throw_invalid_attr!(attr, &meta, |diag| {
+                        diag.help(
+                            "`eager` is the only supported nested attribute for `subdiagnostic`",
+                        )
+                    })
+                }
             }
             _ => (),
         }
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index ac916bb6068..bb3722fe156 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -1,5 +1,6 @@
 #![feature(allow_internal_unstable)]
 #![feature(if_let_guard)]
+#![feature(let_chains)]
 #![feature(never_type)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_span)]
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 58f6fd2b006..b1b04c92a75 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -334,6 +334,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         self.r.field_names.insert(def_id, field_names);
     }
 
+    fn insert_field_visibilities_local(&mut self, def_id: DefId, vdata: &ast::VariantData) {
+        let field_vis = vdata
+            .fields()
+            .iter()
+            .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span)))
+            .collect();
+        self.r.field_visibility_spans.insert(def_id, field_vis);
+    }
+
     fn insert_field_names_extern(&mut self, def_id: DefId) {
         let field_names =
             self.r.cstore().struct_field_names_untracked(def_id, self.r.session).collect();
@@ -737,6 +746,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
 
                 // Record field names for error reporting.
                 self.insert_field_names_local(def_id, vdata);
+                self.insert_field_visibilities_local(def_id, vdata);
 
                 // If this is a tuple or unit struct, define a name
                 // in the value namespace as well.
@@ -770,6 +780,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                         Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id());
                     self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
                     self.r.visibilities.insert(ctor_def_id, ctor_vis);
+                    // We need the field visibility spans also for the constructor for E0603.
+                    self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata);
 
                     self.r
                         .struct_constructors
@@ -783,6 +795,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
 
                 // Record field names for error reporting.
                 self.insert_field_names_local(def_id, vdata);
+                self.insert_field_visibilities_local(def_id, vdata);
             }
 
             ItemKind::Trait(..) => {
@@ -1510,6 +1523,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
 
         // Record field names for error reporting.
         self.insert_field_names_local(def_id.to_def_id(), &variant.data);
+        self.insert_field_visibilities_local(def_id.to_def_id(), &variant.data);
 
         visit::walk_variant(self, variant);
     }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 7d62d67d64f..1a852de8eed 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -6,7 +6,9 @@ use rustc_ast::{self as ast, Crate, ItemKind, ModKind, NodeId, Path, CRATE_NODE_
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::struct_span_err;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{
+    pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
+};
 use rustc_feature::BUILTIN_ATTRIBUTES;
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS};
@@ -1604,6 +1606,16 @@ impl<'a> Resolver<'a> {
         err.span_label(ident.span, &format!("private {}", descr));
         if let Some(span) = ctor_fields_span {
             err.span_label(span, "a constructor is private if any of the fields is private");
+            if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) {
+                err.multipart_suggestion_verbose(
+                    &format!(
+                        "consider making the field{} publicly accessible",
+                        pluralize!(fields.len())
+                    ),
+                    fields.iter().map(|span| (*span, "pub ".to_string())).collect(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
         }
 
         // Print the whole import chain to make it easier to see what happens.
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 74522f18542..d92f5a7c05e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1451,6 +1451,17 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
                         .collect();
 
                     if non_visible_spans.len() > 0 {
+                        if let Some(fields) = self.r.field_visibility_spans.get(&def_id) {
+                            err.multipart_suggestion_verbose(
+                                &format!(
+                                    "consider making the field{} publicly accessible",
+                                    pluralize!(fields.len())
+                                ),
+                                fields.iter().map(|span| (*span, "pub ".to_string())).collect(),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+
                         let mut m: MultiSpan = non_visible_spans.clone().into();
                         non_visible_spans
                             .into_iter()
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 2182b736937..84d9794ccf2 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -881,6 +881,10 @@ pub struct Resolver<'a> {
     /// Used for hints during error reporting.
     field_names: FxHashMap<DefId, Vec<Spanned<Symbol>>>,
 
+    /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
+    /// Used for hints during error reporting.
+    field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
+
     /// All imports known to succeed or fail.
     determined_imports: Vec<&'a Import<'a>>,
 
@@ -1268,6 +1272,7 @@ impl<'a> Resolver<'a> {
 
             has_self: FxHashSet::default(),
             field_names: FxHashMap::default(),
+            field_visibility_spans: FxHashMap::default(),
 
             determined_imports: Vec::new(),
             indeterminate_imports: Vec::new(),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
index 27c207528c7..ba9ee57d409 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
 
     fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         self.infcx.probe(|_| {
-            if a.is_ty_infer() || b.is_ty_infer() {
+            if a.is_ty_var() || b.is_ty_var() {
                 Ok(a)
             } else {
                 self.infcx.super_combine_tys(self, a, b).or_else(|e| {
@@ -71,10 +71,13 @@ impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
         a: ty::Const<'tcx>,
         b: ty::Const<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
-        if a == b {
-            return Ok(a);
-        }
-        relate::super_relate_consts(self, a, b) // could do something similar here for constants!
+        self.infcx.probe(|_| {
+            if a.is_ct_infer() || b.is_ct_infer() {
+                Ok(a)
+            } else {
+                relate::super_relate_consts(self, a, b) // could do something similar here for constants!
+            }
+        })
     }
 
     fn binders<T: Relate<'tcx>>(
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5c63efef717..87de41fde63 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -676,7 +676,8 @@ impl Item {
         }
         let header = match *self.kind {
             ItemKind::ForeignFunctionItem(_) => {
-                let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi();
+                let def_id = self.item_id.as_def_id().unwrap();
+                let abi = tcx.fn_sig(def_id).abi();
                 hir::FnHeader {
                     unsafety: if abi == Abi::RustIntrinsic {
                         intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap())
@@ -684,7 +685,14 @@ impl Item {
                         hir::Unsafety::Unsafe
                     },
                     abi,
-                    constness: hir::Constness::NotConst,
+                    constness: if abi == Abi::RustIntrinsic
+                        && tcx.is_const_fn(def_id)
+                        && is_unstable_const_fn(tcx, def_id).is_none()
+                    {
+                        hir::Constness::Const
+                    } else {
+                        hir::Constness::NotConst
+                    },
                     asyncness: hir::IsAsync::NotAsync,
                 }
             }
diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs
index ac8b5f6834c..bc9fd35ecde 100644
--- a/src/tools/tidy/src/error_codes.rs
+++ b/src/tools/tidy/src/error_codes.rs
@@ -31,10 +31,8 @@ const IGNORE_DOCTEST_CHECK: &[&str] =
     &["E0208", "E0464", "E0570", "E0601", "E0602", "E0640", "E0717"];
 
 // Error codes that don't yet have a UI test. This list will eventually be removed.
-const IGNORE_UI_TEST_CHECK: &[&str] = &[
-    "E0461", "E0465", "E0476", "E0490", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729",
-    "E0789",
-];
+const IGNORE_UI_TEST_CHECK: &[&str] =
+    &["E0461", "E0465", "E0476", "E0514", "E0523", "E0554", "E0640", "E0717", "E0729", "E0789"];
 
 macro_rules! verbose_print {
     ($verbose:expr, $($fmt:tt)*) => {
diff --git a/tests/rustdoc/const-intrinsic.rs b/tests/rustdoc/const-intrinsic.rs
new file mode 100644
index 00000000000..2fc486d01da
--- /dev/null
+++ b/tests/rustdoc/const-intrinsic.rs
@@ -0,0 +1,25 @@
+#![feature(intrinsics)]
+#![feature(staged_api)]
+
+#![crate_name = "foo"]
+#![stable(since="1.0.0", feature="rust1")]
+
+extern "rust-intrinsic" {
+    // @has 'foo/fn.transmute.html'
+    // @has - '//pre[@class="rust fn"]' 'pub const unsafe extern "rust-intrinsic" fn transmute<T, U>(_: T) -> U'
+    #[stable(since="1.0.0", feature="rust1")]
+    #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
+    pub fn transmute<T, U>(_: T) -> U;
+
+    // @has 'foo/fn.unreachable.html'
+    // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
+    #[stable(since="1.0.0", feature="rust1")]
+    pub fn unreachable() -> !;
+}
+
+extern "C" {
+    // @has 'foo/fn.needs_drop.html'
+    // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "C" fn needs_drop() -> !'
+    #[stable(since="1.0.0", feature="rust1")]
+    pub fn needs_drop() -> !;
+}
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
index c19b639a8d5..65d9601e78a 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs
@@ -723,7 +723,6 @@ struct SubdiagnosticEagerLint {
 #[diag(compiletest_example)]
 struct SubdiagnosticEagerCorrect {
     #[subdiagnostic(eager)]
-    //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
     note: Note,
 }
 
@@ -744,7 +743,6 @@ pub(crate) struct SubdiagnosticWithSuggestion {
 #[diag(compiletest_example)]
 struct SubdiagnosticEagerSuggestion {
     #[subdiagnostic(eager)]
-    //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute
     sub: SubdiagnosticWithSuggestion,
 }
 
diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
index f39d32a221c..13e806a434f 100644
--- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
+++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr
@@ -539,7 +539,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute
 LL |     #[subdiagnostic(bad)]
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: `subdiagnostic` does not support nested attributes
+   = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic = ...]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:693:5
@@ -553,7 +553,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute
 LL |     #[subdiagnostic(bad, bad)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: `subdiagnostic` does not support nested attributes
+   = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:709:5
@@ -561,7 +561,7 @@ error: `#[subdiagnostic(...)]` is not a valid attribute
 LL |     #[subdiagnostic("bad")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: `subdiagnostic` does not support nested attributes
+   = help: `eager` is the only supported nested attribute for `subdiagnostic`
 
 error: `#[subdiagnostic(...)]` is not a valid attribute
   --> $DIR/diagnostic-derive.rs:717:5
@@ -569,38 +569,22 @@ error: `#[subdiagnostic(...)]` is not a valid attribute
 LL |     #[subdiagnostic(eager)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: `subdiagnostic` does not support nested attributes
-
-error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:725:5
-   |
-LL |     #[subdiagnostic(eager)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: `subdiagnostic` does not support nested attributes
-
-error: `#[subdiagnostic(...)]` is not a valid attribute
-  --> $DIR/diagnostic-derive.rs:746:5
-   |
-LL |     #[subdiagnostic(eager)]
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: `subdiagnostic` does not support nested attributes
+   = help: eager subdiagnostics are not supported on lints
 
 error: expected at least one string literal for `code(...)`
-  --> $DIR/diagnostic-derive.rs:777:18
+  --> $DIR/diagnostic-derive.rs:775:18
    |
 LL |     #[suggestion(code())]
    |                  ^^^^^^
 
 error: `code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:785:23
+  --> $DIR/diagnostic-derive.rs:783:23
    |
 LL |     #[suggestion(code(foo))]
    |                       ^^^
 
 error: `code = "..."`/`code(...)` must contain only string literals
-  --> $DIR/diagnostic-derive.rs:793:18
+  --> $DIR/diagnostic-derive.rs:791:18
    |
 LL |     #[suggestion(code = 3)]
    |                  ^^^^^^^^
@@ -676,7 +660,7 @@ note: required by a bound in `DiagnosticBuilder::<'a, G>::set_arg`
   --> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
    = note: this error originates in the derive macro `Diagnostic` which comes from the expansion of the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 85 previous errors
+error: aborting due to 83 previous errors
 
 Some errors have detailed explanations: E0277, E0425.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.rs b/tests/ui/consts/ct-var-in-collect_all_mismatches.rs
new file mode 100644
index 00000000000..5fb633de983
--- /dev/null
+++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.rs
@@ -0,0 +1,20 @@
+struct Foo<T, const N: usize> {
+    array: [T; N],
+}
+
+trait Bar<const N: usize> {}
+
+impl<T, const N: usize> Foo<T, N> {
+    fn trigger(self) {
+        self.unsatisfied()
+        //~^ ERROR the trait bound `T: Bar<N>` is not satisfied
+    }
+
+    fn unsatisfied(self)
+    where
+        T: Bar<N>,
+    {
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr
new file mode 100644
index 00000000000..43fba2573ff
--- /dev/null
+++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `T: Bar<N>` is not satisfied
+  --> $DIR/ct-var-in-collect_all_mismatches.rs:9:14
+   |
+LL |         self.unsatisfied()
+   |              ^^^^^^^^^^^ the trait `Bar<N>` is not implemented for `T`
+   |
+note: required by a bound in `Foo::<T, N>::unsatisfied`
+  --> $DIR/ct-var-in-collect_all_mismatches.rs:15:12
+   |
+LL |     fn unsatisfied(self)
+   |        ----------- required by a bound in this
+LL |     where
+LL |         T: Bar<N>,
+   |            ^^^^^^ required by this bound in `Foo::<T, N>::unsatisfied`
+help: consider restricting type parameter `T`
+   |
+LL | impl<T: Bar<N>, const N: usize> Foo<T, N> {
+   |       ++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs
new file mode 100644
index 00000000000..882a1d13954
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let x = Some(()).iter().map(|()| 1).sum::<f32>();
+    //~^ ERROR a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}`
+}
diff --git a/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
new file mode 100644
index 00000000000..3cb5e44c711
--- /dev/null
+++ b/tests/ui/iterators/invalid-iterator-chain-with-int-infer.stderr
@@ -0,0 +1,24 @@
+error[E0277]: a value of type `f32` cannot be made by summing an iterator over elements of type `{integer}`
+  --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:41
+   |
+LL |     let x = Some(()).iter().map(|()| 1).sum::<f32>();
+   |                                         ^^^ value of type `f32` cannot be made by summing a `std::iter::Iterator<Item={integer}>`
+   |
+   = help: the trait `Sum<{integer}>` is not implemented for `f32`
+   = help: the following other types implement trait `Sum<A>`:
+             <f32 as Sum<&'a f32>>
+             <f32 as Sum>
+note: the method call chain might not have had the expected associated types
+  --> $DIR/invalid-iterator-chain-with-int-infer.rs:2:29
+   |
+LL |     let x = Some(()).iter().map(|()| 1).sum::<f32>();
+   |             -------- ------ ^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
+   |             |        |
+   |             |        `Iterator::Item` is `&()` here
+   |             this expression has type `Option<()>`
+note: required by a bound in `std::iter::Iterator::sum`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/privacy/issue-75906.stderr b/tests/ui/privacy/issue-75906.stderr
index 4c6a68646ad..600dc7c876f 100644
--- a/tests/ui/privacy/issue-75906.stderr
+++ b/tests/ui/privacy/issue-75906.stderr
@@ -9,6 +9,10 @@ note: constructor is not visible here due to private fields
    |
 LL |     pub struct Bar(u8);
    |                    ^^ private field
+help: consider making the field publicly accessible
+   |
+LL |     pub struct Bar(pub u8);
+   |                    +++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/privacy/issue-75907.rs b/tests/ui/privacy/issue-75907.rs
index 6da99cf6435..3bed841d13e 100644
--- a/tests/ui/privacy/issue-75907.rs
+++ b/tests/ui/privacy/issue-75907.rs
@@ -2,7 +2,7 @@
 
 mod foo {
     pub(crate) struct Foo(u8);
-    pub(crate) struct Bar(pub u8, u8, Foo);
+    pub(crate) struct Bar(pub u8, pub(in crate::foo) u8, Foo);
 
     pub(crate) fn make_bar() -> Bar {
         Bar(1, 12, Foo(10))
diff --git a/tests/ui/privacy/issue-75907.stderr b/tests/ui/privacy/issue-75907.stderr
index 2f89e31a31a..f7cb874c2cc 100644
--- a/tests/ui/privacy/issue-75907.stderr
+++ b/tests/ui/privacy/issue-75907.stderr
@@ -11,6 +11,10 @@ LL |     let Bar(x, y, Foo(z)) = make_bar();
    |                ^  ^^^^^^ private field
    |                |
    |                private field
+help: consider making the fields publicly accessible
+   |
+LL |     pub(crate) struct Bar(pub u8, pub u8, pub Foo);
+   |                           ~~~     ~~~     +++
 
 error[E0532]: cannot match against a tuple struct which contains private fields
   --> $DIR/issue-75907.rs:15:19
@@ -23,6 +27,10 @@ note: constructor is not visible here due to private fields
    |
 LL |     let Bar(x, y, Foo(z)) = make_bar();
    |                       ^ private field
+help: consider making the field publicly accessible
+   |
+LL |     pub(crate) struct Foo(pub u8);
+   |                           +++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/privacy/privacy5.stderr b/tests/ui/privacy/privacy5.stderr
index 680161272ce..615b0af2762 100644
--- a/tests/ui/privacy/privacy5.stderr
+++ b/tests/ui/privacy/privacy5.stderr
@@ -12,6 +12,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:52:16
@@ -27,6 +31,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:53:16
@@ -42,6 +50,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:56:12
@@ -57,6 +69,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:57:12
@@ -72,6 +88,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:58:18
@@ -87,6 +107,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:59:18
@@ -102,6 +126,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:61:12
@@ -117,6 +145,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:62:12
@@ -132,6 +164,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:63:18
@@ -147,6 +183,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:64:18
@@ -162,6 +202,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:65:18
@@ -177,6 +221,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:65:32
@@ -192,6 +240,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:68:12
@@ -207,6 +259,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:69:12
@@ -222,6 +278,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:70:12
@@ -237,6 +297,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:71:12
@@ -252,6 +316,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:72:18
@@ -267,6 +335,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:73:18
@@ -282,6 +354,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:74:18
@@ -297,6 +373,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:75:18
@@ -312,6 +392,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:83:17
@@ -327,6 +411,10 @@ note: the tuple struct constructor `A` is defined here
    |
 LL |     pub struct A(());
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub ());
+   |                  +++
 
 error[E0603]: tuple struct constructor `B` is private
   --> $DIR/privacy5.rs:84:17
@@ -342,6 +430,10 @@ note: the tuple struct constructor `B` is defined here
    |
 LL |     pub struct B(isize);
    |     ^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct B(pub isize);
+   |                  +++
 
 error[E0603]: tuple struct constructor `C` is private
   --> $DIR/privacy5.rs:85:17
@@ -357,6 +449,10 @@ note: the tuple struct constructor `C` is defined here
    |
 LL |     pub struct C(pub isize, isize);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the fields publicly accessible
+   |
+LL |     pub struct C(pub isize, pub isize);
+   |                  ~~~        +++
 
 error[E0603]: tuple struct constructor `A` is private
   --> $DIR/privacy5.rs:90:20
diff --git a/tests/ui/privacy/suggest-making-field-public.fixed b/tests/ui/privacy/suggest-making-field-public.fixed
new file mode 100644
index 00000000000..78e335b3db1
--- /dev/null
+++ b/tests/ui/privacy/suggest-making-field-public.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+mod a {
+    pub struct A(pub String);
+}
+
+mod b {
+    use crate::a::A;
+    pub fn x() {
+        A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields
+    }
+}
+fn main() {
+    a::A("a".into()); //~ ERROR tuple struct constructor `A` is private
+    b::x();
+}
diff --git a/tests/ui/privacy/suggest-making-field-public.rs b/tests/ui/privacy/suggest-making-field-public.rs
new file mode 100644
index 00000000000..b65c801d10e
--- /dev/null
+++ b/tests/ui/privacy/suggest-making-field-public.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+mod a {
+    pub struct A(pub(self)String);
+}
+
+mod b {
+    use crate::a::A;
+    pub fn x() {
+        A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields
+    }
+}
+fn main() {
+    a::A("a".into()); //~ ERROR tuple struct constructor `A` is private
+    b::x();
+}
diff --git a/tests/ui/privacy/suggest-making-field-public.stderr b/tests/ui/privacy/suggest-making-field-public.stderr
new file mode 100644
index 00000000000..e92e9aae310
--- /dev/null
+++ b/tests/ui/privacy/suggest-making-field-public.stderr
@@ -0,0 +1,39 @@
+error[E0603]: tuple struct constructor `A` is private
+  --> $DIR/suggest-making-field-public.rs:13:8
+   |
+LL |     pub struct A(pub(self)String);
+   |                  --------------- a constructor is private if any of the fields is private
+...
+LL |     a::A("a".into());
+   |        ^ private tuple struct constructor
+   |
+note: the tuple struct constructor `A` is defined here
+  --> $DIR/suggest-making-field-public.rs:3:5
+   |
+LL |     pub struct A(pub(self)String);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub String);
+   |                  ~~~
+
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/suggest-making-field-public.rs:9:9
+   |
+LL |         A("".into());
+   |         ^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/suggest-making-field-public.rs:3:18
+   |
+LL |     pub struct A(pub(self)String);
+   |                  ^^^^^^^^^^^^^^^ private field
+help: consider making the field publicly accessible
+   |
+LL |     pub struct A(pub String);
+   |                  ~~~
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0423, E0603.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/tests/ui/resolve/issue-42944.rs b/tests/ui/resolve/issue-42944.rs
index a4404857a56..7e439c10b7b 100644
--- a/tests/ui/resolve/issue-42944.rs
+++ b/tests/ui/resolve/issue-42944.rs
@@ -1,5 +1,5 @@
 mod foo {
-    pub struct Bx(());
+    pub struct Bx(pub(in crate::foo) ());
 }
 
 mod bar {
diff --git a/tests/ui/resolve/issue-42944.stderr b/tests/ui/resolve/issue-42944.stderr
index 0ee9fd391fe..4ffa9402c66 100644
--- a/tests/ui/resolve/issue-42944.stderr
+++ b/tests/ui/resolve/issue-42944.stderr
@@ -7,8 +7,8 @@ LL |         Bx(());
 note: tuple struct `foo::Bx` exists but is inaccessible
   --> $DIR/issue-42944.rs:2:5
    |
-LL |     pub struct Bx(());
-   |     ^^^^^^^^^^^^^^^^^^ not accessible
+LL |     pub struct Bx(pub(in crate::foo) ());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible
 
 error[E0423]: cannot initialize a tuple struct which contains private fields
   --> $DIR/issue-42944.rs:9:9
@@ -19,8 +19,12 @@ LL |         Bx(());
 note: constructor is not visible here due to private fields
   --> $DIR/issue-42944.rs:2:19
    |
-LL |     pub struct Bx(());
-   |                   ^^ private field
+LL |     pub struct Bx(pub(in crate::foo) ());
+   |                   ^^^^^^^^^^^^^^^^^^^^^ private field
+help: consider making the field publicly accessible
+   |
+LL |     pub struct Bx(pub ());
+   |                   ~~~
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/privacy-struct-ctor.stderr b/tests/ui/resolve/privacy-struct-ctor.stderr
index 17a666a401c..c1fcaaf0573 100644
--- a/tests/ui/resolve/privacy-struct-ctor.stderr
+++ b/tests/ui/resolve/privacy-struct-ctor.stderr
@@ -53,6 +53,10 @@ note: the tuple struct constructor `Z` is defined here
    |
 LL |         pub(in m) struct Z(pub(in m::n) u8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |         pub(in m) struct Z(pub u8);
+   |                            ~~~
 
 error[E0603]: tuple struct constructor `S` is private
   --> $DIR/privacy-struct-ctor.rs:29:8
@@ -68,6 +72,10 @@ note: the tuple struct constructor `S` is defined here
    |
 LL |     pub struct S(u8);
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct S(pub u8);
+   |                  +++
 
 error[E0603]: tuple struct constructor `S` is private
   --> $DIR/privacy-struct-ctor.rs:31:19
@@ -83,6 +91,10 @@ note: the tuple struct constructor `S` is defined here
    |
 LL |     pub struct S(u8);
    |     ^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |     pub struct S(pub u8);
+   |                  +++
 
 error[E0603]: tuple struct constructor `Z` is private
   --> $DIR/privacy-struct-ctor.rs:35:11
@@ -98,6 +110,10 @@ note: the tuple struct constructor `Z` is defined here
    |
 LL |         pub(in m) struct Z(pub(in m::n) u8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider making the field publicly accessible
+   |
+LL |         pub(in m) struct Z(pub u8);
+   |                            ~~~
 
 error[E0603]: tuple struct constructor `S` is private
   --> $DIR/privacy-struct-ctor.rs:41:16
diff --git a/triagebot.toml b/triagebot.toml
index 1f1b1f1110d..a7b4925bc17 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -478,6 +478,7 @@ compiler-team-contributors = [
     "@jackh726",
     "@TaKO8Ki",
     "@Nilstrieb",
+    "@WaffleLapkin",
 ]
 compiler = [
     "compiler-team",