about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-07-19 02:33:36 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-07-19 02:33:36 +0400
commit5bd88dfa8a0b5d5bcdd84d21e2f465719ce8c328 (patch)
tree0e23b2e8de0d6dc7b59f84bf91abce5e55f35ce8
parent2edad7d77c91145b594ac80c3dc7906998b7674a (diff)
downloadrust-5bd88dfa8a0b5d5bcdd84d21e2f465719ce8c328.tar.gz
rust-5bd88dfa8a0b5d5bcdd84d21e2f465719ce8c328.zip
Add a note about privacy to wrapping suggestion
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs28
-rw-r--r--src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr2
2 files changed, 18 insertions, 12 deletions
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index e5f8b6b5f1e..a2d8765289c 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -348,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
 
-            let compatible_variants: Vec<String> = expected_adt
+            let compatible_variants: Vec<(String, Option<String>)> = expected_adt
                 .variants()
                 .iter()
                 .filter(|variant| {
@@ -357,14 +357,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .filter_map(|variant| {
                     let sole_field = &variant.fields[0];
 
-                    if !sole_field.did.is_local()
-                        && !sole_field
-                            .vis
-                            .is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx)
-                    {
+                    let field_is_local = sole_field.did.is_local();
+                    let field_is_accessible =
+                        sole_field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx);
+
+                    if !field_is_local && !field_is_accessible {
                         return None;
                     }
 
+                    let note_about_variant_field_privacy = (field_is_local && !field_is_accessible)
+                        .then(|| format!(" (its field is private, but it's local to this crate and its privacy can be changed)"));
+
                     let sole_field_ty = sole_field.ty(self.tcx, substs);
                     if self.can_coerce(expr_ty, sole_field_ty) {
                         let variant_path =
@@ -373,9 +376,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(path) = variant_path.strip_prefix("std::prelude::")
                             && let Some((_, path)) = path.split_once("::")
                         {
-                            return Some(path.to_string());
+                            return Some((path.to_string(), note_about_variant_field_privacy));
                         }
-                        Some(variant_path)
+                        Some((variant_path, note_about_variant_field_privacy))
                     } else {
                         None
                     }
@@ -389,10 +392,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             match &compatible_variants[..] {
                 [] => { /* No variants to format */ }
-                [variant] => {
+                [(variant, note)] => {
                     // Just a single matching variant.
                     err.multipart_suggestion_verbose(
-                        &format!("try wrapping the expression in `{variant}`"),
+                        &format!(
+                            "try wrapping the expression in `{variant}`{note}",
+                            note = note.as_deref().unwrap_or("")
+                        ),
                         vec![
                             (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
                             (expr.span.shrink_to_hi(), ")".to_string()),
@@ -407,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             "try wrapping the expression in a variant of `{}`",
                             self.tcx.def_path_str(expected_adt.did())
                         ),
-                        compatible_variants.into_iter().map(|variant| {
+                        compatible_variants.into_iter().map(|(variant, _)| {
                             vec![
                                 (expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
                                 (expr.span.shrink_to_hi(), ")".to_string()),
diff --git a/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr b/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr
index 536638632de..e8eb8d263ec 100644
--- a/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr
+++ b/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr
@@ -13,7 +13,7 @@ note: function defined here
    |
 LL | fn needs_wrapper(t: inner::Wrapper<i32>) {}
    |    ^^^^^^^^^^^^^ ----------------------
-help: try wrapping the expression in `inner::Wrapper`
+help: try wrapping the expression in `inner::Wrapper` (its field is private, but it's local to this crate and its privacy can be changed)
    |
 LL |     needs_wrapper(inner::Wrapper(0));
    |                   +++++++++++++++ +