check accessibility before suggesting wrapping expressions

This commit is contained in:
Maybe Waffle 2022-07-19 01:16:25 +04:00
parent 7163e7ff65
commit da2752e00f
3 changed files with 93 additions and 8 deletions

View File

@ -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<String> = 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 =

View File

@ -0,0 +1,24 @@
mod inner {
pub struct Wrapper<T>(T);
}
fn needs_wrapper(t: inner::Wrapper<i32>) {}
fn needs_wrapping(t: std::num::Wrapping<i32>) {}
fn needs_ready(t: std::future::Ready<i32>) {}
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
}

View File

@ -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<i32>`
found type `{integer}`
note: function defined here
--> $DIR/wrap-suggestion-privacy.rs:5:4
|
LL | fn needs_wrapper(t: inner::Wrapper<i32>) {}
| ^^^^^^^^^^^^^ ----------------------
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<i32>`
found type `{integer}`
note: function defined here
--> $DIR/wrap-suggestion-privacy.rs:6:4
|
LL | fn needs_wrapping(t: std::num::Wrapping<i32>) {}
| ^^^^^^^^^^^^^^ --------------------------
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<i32>`
found enum `Option<{integer}>`
note: function defined here
--> $DIR/wrap-suggestion-privacy.rs:7:4
|
LL | fn needs_ready(t: std::future::Ready<i32>) {}
| ^^^^^^^^^^^ --------------------------
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.