diff options
| -rw-r--r-- | compiler/rustc_typeck/src/check/expr.rs | 63 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/method/suggest.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-31173.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-39175.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/mismatched_types/issue-36053-2.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/suggestions/import-trait-for-method-call.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr | 10 | ||||
| -rw-r--r-- | src/test/ui/suggestions/suggest-using-chars.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/unique-object-noncopyable.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/unique-pinned-nocopy.stderr | 8 |
10 files changed, 40 insertions, 80 deletions
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index a9358835136..523a10cc36a 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2535,15 +2535,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // try to add a suggestion in case the field is a nested field of a field of the Adt - if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) { - for candidate_field in fields.iter() { + let mod_id = self.tcx.parent_module(id).to_def_id(); + if let Some((fields, substs)) = + self.get_field_candidates_considering_privacy(span, expr_t, mod_id) + { + for candidate_field in fields { if let Some(mut field_path) = self.check_for_nested_field_satisfying( span, &|candidate_field, _| candidate_field.ident(self.tcx()) == field, candidate_field, substs, vec![], - self.tcx.parent_module(id).to_def_id(), + mod_id, ) { // field_path includes `field` that we're looking for, so pop it. field_path.pop(); @@ -2567,22 +2570,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err } - pub(crate) fn get_field_candidates( + pub(crate) fn get_field_candidates_considering_privacy( &self, span: Span, - base_t: Ty<'tcx>, - ) -> Option<(&[ty::FieldDef], SubstsRef<'tcx>)> { - debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_t); + base_ty: Ty<'tcx>, + mod_id: DefId, + ) -> Option<(impl Iterator<Item = &'tcx ty::FieldDef> + 'tcx, SubstsRef<'tcx>)> { + debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty); - for (base_t, _) in self.autoderef(span, base_t) { + for (base_t, _) in self.autoderef(span, base_ty) { match base_t.kind() { ty::Adt(base_def, substs) if !base_def.is_enum() => { - let fields = &base_def.non_enum_variant().fields; - // For compile-time reasons put a limit on number of fields we search - if fields.len() > 100 { - return None; - } - return Some((fields, substs)); + let tcx = self.tcx; + return Some(( + base_def + .non_enum_variant() + .fields + .iter() + .filter(move |field| field.vis.is_accessible_from(mod_id, tcx)) + // For compile-time reasons put a limit on number of fields we search + .take(100), + substs, + )); } _ => {} } @@ -2599,7 +2608,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { candidate_field: &ty::FieldDef, subst: SubstsRef<'tcx>, mut field_path: Vec<Ident>, - id: DefId, + mod_id: DefId, ) -> Option<Vec<Ident>> { debug!( "check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}", @@ -2615,20 +2624,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = candidate_field.ty(self.tcx, subst); if matches(candidate_field, field_ty) { return Some(field_path); - } else if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) { + } else if let Some((nested_fields, subst)) = + self.get_field_candidates_considering_privacy(span, field_ty, mod_id) + { // recursively search fields of `candidate_field` if it's a ty::Adt for field in nested_fields { - if field.vis.is_accessible_from(id, self.tcx) { - if let Some(field_path) = self.check_for_nested_field_satisfying( - span, - matches, - field, - subst, - field_path.clone(), - id, - ) { - return Some(field_path); - } + if let Some(field_path) = self.check_for_nested_field_satisfying( + span, + matches, + field, + subst, + field_path.clone(), + mod_id, + ) { + return Some(field_path); } } } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index c92b93cbc22..ee6fe8699e1 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1334,10 +1334,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name: Ident, ) { if let SelfSource::MethodCall(expr) = source - && let Some((fields, substs)) = self.get_field_candidates(span, actual) + && let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id() + && let Some((fields, substs)) = self.get_field_candidates_considering_privacy(span, actual, mod_id) { let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); - for candidate_field in fields.iter() { + for candidate_field in fields { if let Some(field_path) = self.check_for_nested_field_satisfying( span, &|_, field_ty| { @@ -1353,7 +1354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { candidate_field, substs, vec![], - self.tcx.parent_module(expr.hir_id).to_def_id(), + mod_id, ) { let field_path_str = field_path .iter() diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr index e8797ea7b5b..68337a715e1 100644 --- a/src/test/ui/issues/issue-31173.stderr +++ b/src/test/ui/issues/issue-31173.stderr @@ -33,10 +33,6 @@ LL | pub struct TakeWhile<I, P> { which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator` `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator` which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 6:43]>>: Iterator` -help: one of the expressions' fields has a method of the same name - | -LL | .it.collect(); - | +++ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-39175.stderr b/src/test/ui/issues/issue-39175.stderr index b19f58d2a38..afceae82e68 100644 --- a/src/test/ui/issues/issue-39175.stderr +++ b/src/test/ui/issues/issue-39175.stderr @@ -5,10 +5,6 @@ LL | Command::new("echo").arg("hello").exec(); | ^^^^ method not found in `&mut Command` | = help: items from traits can only be used if the trait is in scope -help: one of the expressions' fields has a method of the same name - | -LL | Command::new("echo").arg("hello").inner.exec(); - | ++++++ help: the following trait is implemented but not in scope; perhaps add a `use` for it: | LL | use std::os::unix::process::CommandExt; diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr index c3c8e5f272e..b11ea97d160 100644 --- a/src/test/ui/mismatched_types/issue-36053-2.stderr +++ b/src/test/ui/mismatched_types/issue-36053-2.stderr @@ -35,10 +35,6 @@ LL | pub struct Filter<I, P> { which is required by `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator` `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator` which is required by `&mut Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:48]>: Iterator` -help: one of the expressions' fields has a method of the same name - | -LL | once::<&str>("str").fuse().filter(|a: &str| true).iter.count(); - | +++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/import-trait-for-method-call.stderr b/src/test/ui/suggestions/import-trait-for-method-call.stderr index f220458f321..bac8de79872 100644 --- a/src/test/ui/suggestions/import-trait-for-method-call.stderr +++ b/src/test/ui/suggestions/import-trait-for-method-call.stderr @@ -10,10 +10,6 @@ LL | fn finish(&self) -> u64; | ------ the method is available for `DefaultHasher` here | = help: items from traits can only be used if the trait is in scope -help: one of the expressions' fields has a method of the same name - | -LL | h.0.finish() - | ++ help: the following trait is implemented but not in scope; perhaps add a `use` for it: | LL | use std::hash::Hasher; diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index e19bc5a1fd4..d121932c842 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -41,16 +41,6 @@ LL | pub struct BufWriter<W: Write> { `&dyn std::io::Write: std::io::Write` which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) -help: one of the expressions' fields has a method of the same name - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $dst.inner.write_fmt($crate::format_args_nl!($($arg)*)) - | ++++++ -help: one of the expressions' fields has a method of the same name - --> $SRC_DIR/core/src/macros/mod.rs:LL:COL - | -LL | $dst.buf.write_fmt($crate::format_args_nl!($($arg)*)) - | ++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/suggestions/suggest-using-chars.stderr b/src/test/ui/suggestions/suggest-using-chars.stderr index 1690309719f..99bcfb08a08 100644 --- a/src/test/ui/suggestions/suggest-using-chars.stderr +++ b/src/test/ui/suggestions/suggest-using-chars.stderr @@ -25,10 +25,6 @@ help: because of the in-memory representation of `&str`, to obtain an `Iterator` | LL | let _ = String::from("bar").chars(); | ~~~~~ -help: one of the expressions' fields has a method of the same name - | -LL | let _ = String::from("bar").vec.iter(); - | ++++ error[E0599]: no method named `iter` found for reference `&String` in the current scope --> $DIR/suggest-using-chars.rs:5:36 @@ -40,10 +36,6 @@ help: because of the in-memory representation of `&str`, to obtain an `Iterator` | LL | let _ = (&String::from("bar")).chars(); | ~~~~~ -help: one of the expressions' fields has a method of the same name - | -LL | let _ = (&String::from("bar")).vec.iter(); - | ++++ error[E0599]: no method named `iter` found for type `{integer}` in the current scope --> $DIR/suggest-using-chars.rs:6:15 diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index 12917d54114..98a9bd07ed2 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -23,14 +23,6 @@ LL | | >(Unique<T>, A); which is required by `Box<dyn Foo>: Clone` `dyn Foo: Clone` which is required by `Box<dyn Foo>: Clone` -help: one of the expressions' fields has a method of the same name - | -LL | let _z = y.0.clone(); - | ++ -help: one of the expressions' fields has a method of the same name - | -LL | let _z = y.1.clone(); - | ++ error: aborting due to previous error diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr index cc9bdd26e11..7af9c684b72 100644 --- a/src/test/ui/unique-pinned-nocopy.stderr +++ b/src/test/ui/unique-pinned-nocopy.stderr @@ -25,14 +25,6 @@ help: consider annotating `R` with `#[derive(Clone)]` | LL | #[derive(Clone)] | -help: one of the expressions' fields has a method of the same name - | -LL | let _j = i.0.clone(); - | ++ -help: one of the expressions' fields has a method of the same name - | -LL | let _j = i.1.clone(); - | ++ error: aborting due to previous error |
