From da2752e00f0139fb13282b2bd97aa0f8c665aee9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 19 Jul 2022 01:16:25 +0400 Subject: [PATCH] check accessibility before suggesting wrapping expressions --- compiler/rustc_typeck/src/check/demand.rs | 18 +++--- .../wrap-suggestion-privacy.rs | 24 ++++++++ .../wrap-suggestion-privacy.stderr | 59 +++++++++++++++++++ 3 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/mismatched_types/wrap-suggestion-privacy.rs create mode 100644 src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs index 31da5cfe7fa..30d7cc2e5fc 100644 --- a/compiler/rustc_typeck/src/check/demand.rs +++ b/compiler/rustc_typeck/src/check/demand.rs @@ -19,7 +19,6 @@ use rustc_span::{BytePos, Span}; use super::method::probe; use std::iter; -use std::ops::Bound; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn emit_coerce_suggestions( @@ -349,13 +348,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // Avoid suggesting wrapping in `NonZeroU64` and alike - if self.tcx.layout_scalar_valid_range(expected_adt.did()) - != (Bound::Unbounded, Bound::Unbounded) - { - return; - } - let compatible_variants: Vec = expected_adt .variants() .iter() @@ -364,6 +356,16 @@ 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( + self.tcx.parent_module(expr.hir_id).to_def_id(), + self.tcx, + ) + { + return None; + } + let sole_field_ty = sole_field.ty(self.tcx, substs); if self.can_coerce(expr_ty, sole_field_ty) { let variant_path = diff --git a/src/test/ui/mismatched_types/wrap-suggestion-privacy.rs b/src/test/ui/mismatched_types/wrap-suggestion-privacy.rs new file mode 100644 index 00000000000..63cb1a12991 --- /dev/null +++ b/src/test/ui/mismatched_types/wrap-suggestion-privacy.rs @@ -0,0 +1,24 @@ +mod inner { + pub struct Wrapper(T); +} + +fn needs_wrapper(t: inner::Wrapper) {} +fn needs_wrapping(t: std::num::Wrapping) {} +fn needs_ready(t: std::future::Ready) {} + +fn main() { + // Suggest wrapping expression because type is local + // and its privacy can be easily changed + needs_wrapper(0); + //~^ ERROR mismatched types + //~| HELP try wrapping the expression in `inner::Wrapper` + + // Suggest wrapping expression because field is accessible + needs_wrapping(0); + //~^ ERROR mismatched types + //~| HELP try wrapping the expression in `std::num::Wrapping` + + // Do not suggest wrapping expression + needs_ready(Some(0)); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr b/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr new file mode 100644 index 00000000000..536638632de --- /dev/null +++ b/src/test/ui/mismatched_types/wrap-suggestion-privacy.stderr @@ -0,0 +1,59 @@ +error[E0308]: mismatched types + --> $DIR/wrap-suggestion-privacy.rs:12:19 + | +LL | needs_wrapper(0); + | ------------- ^ expected struct `Wrapper`, found integer + | | + | arguments to this function are incorrect + | + = note: expected struct `Wrapper` + found type `{integer}` +note: function defined here + --> $DIR/wrap-suggestion-privacy.rs:5:4 + | +LL | fn needs_wrapper(t: inner::Wrapper) {} + | ^^^^^^^^^^^^^ ---------------------- +help: try wrapping the expression in `inner::Wrapper` + | +LL | needs_wrapper(inner::Wrapper(0)); + | +++++++++++++++ + + +error[E0308]: mismatched types + --> $DIR/wrap-suggestion-privacy.rs:17:20 + | +LL | needs_wrapping(0); + | -------------- ^ expected struct `Wrapping`, found integer + | | + | arguments to this function are incorrect + | + = note: expected struct `Wrapping` + found type `{integer}` +note: function defined here + --> $DIR/wrap-suggestion-privacy.rs:6:4 + | +LL | fn needs_wrapping(t: std::num::Wrapping) {} + | ^^^^^^^^^^^^^^ -------------------------- +help: try wrapping the expression in `std::num::Wrapping` + | +LL | needs_wrapping(std::num::Wrapping(0)); + | +++++++++++++++++++ + + +error[E0308]: mismatched types + --> $DIR/wrap-suggestion-privacy.rs:22:17 + | +LL | needs_ready(Some(0)); + | ----------- ^^^^^^^ expected struct `std::future::Ready`, found enum `Option` + | | + | arguments to this function are incorrect + | + = note: expected struct `std::future::Ready` + found enum `Option<{integer}>` +note: function defined here + --> $DIR/wrap-suggestion-privacy.rs:7:4 + | +LL | fn needs_ready(t: std::future::Ready) {} + | ^^^^^^^^^^^ -------------------------- + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`.