Skip to content

Commit 5bd88df

Browse files
committed
Add a note about privacy to wrapping suggestion
1 parent 2edad7d commit 5bd88df

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

compiler/rustc_typeck/src/check/demand.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
348348
}
349349
}
350350

351-
let compatible_variants: Vec<String> = expected_adt
351+
let compatible_variants: Vec<(String, Option<String>)> = expected_adt
352352
.variants()
353353
.iter()
354354
.filter(|variant| {
@@ -357,14 +357,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
357357
.filter_map(|variant| {
358358
let sole_field = &variant.fields[0];
359359

360-
if !sole_field.did.is_local()
361-
&& !sole_field
362-
.vis
363-
.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx)
364-
{
360+
let field_is_local = sole_field.did.is_local();
361+
let field_is_accessible =
362+
sole_field.vis.is_accessible_from(expr.hir_id.owner.to_def_id(), self.tcx);
363+
364+
if !field_is_local && !field_is_accessible {
365365
return None;
366366
}
367367

368+
let note_about_variant_field_privacy = (field_is_local && !field_is_accessible)
369+
.then(|| format!(" (its field is private, but it's local to this crate and its privacy can be changed)"));
370+
368371
let sole_field_ty = sole_field.ty(self.tcx, substs);
369372
if self.can_coerce(expr_ty, sole_field_ty) {
370373
let variant_path =
@@ -373,9 +376,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
373376
if let Some(path) = variant_path.strip_prefix("std::prelude::")
374377
&& let Some((_, path)) = path.split_once("::")
375378
{
376-
return Some(path.to_string());
379+
return Some((path.to_string(), note_about_variant_field_privacy));
377380
}
378-
Some(variant_path)
381+
Some((variant_path, note_about_variant_field_privacy))
379382
} else {
380383
None
381384
}
@@ -389,10 +392,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
389392

390393
match &compatible_variants[..] {
391394
[] => { /* No variants to format */ }
392-
[variant] => {
395+
[(variant, note)] => {
393396
// Just a single matching variant.
394397
err.multipart_suggestion_verbose(
395-
&format!("try wrapping the expression in `{variant}`"),
398+
&format!(
399+
"try wrapping the expression in `{variant}`{note}",
400+
note = note.as_deref().unwrap_or("")
401+
),
396402
vec![
397403
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
398404
(expr.span.shrink_to_hi(), ")".to_string()),
@@ -407,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
407413
"try wrapping the expression in a variant of `{}`",
408414
self.tcx.def_path_str(expected_adt.did())
409415
),
410-
compatible_variants.into_iter().map(|variant| {
416+
compatible_variants.into_iter().map(|(variant, _)| {
411417
vec![
412418
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
413419
(expr.span.shrink_to_hi(), ")".to_string()),

src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ note: function defined here
1313
|
1414
LL | fn needs_wrapper(t: inner::Wrapper<i32>) {}
1515
| ^^^^^^^^^^^^^ ----------------------
16-
help: try wrapping the expression in `inner::Wrapper`
16+
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)
1717
|
1818
LL | needs_wrapper(inner::Wrapper(0));
1919
| +++++++++++++++ +

0 commit comments

Comments
 (0)