From 7571f6f685d1d4f021ebfd0047ffb2531663652a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 19 Dec 2023 17:28:20 +0300 Subject: [PATCH] resolve: Feed visibilities for unresolved trait impl items --- compiler/rustc_resolve/src/late.rs | 10 +++++++-- .../ui/privacy/unresolved-trait-impl-item.rs | 15 +++++++++++++ .../privacy/unresolved-trait-impl-item.stderr | 22 +++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tests/ui/privacy/unresolved-trait-impl-item.rs create mode 100644 tests/ui/privacy/unresolved-trait-impl-item.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 037179350f0..cf50f630bf2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3078,17 +3078,25 @@ fn check_trait_item( binding = self.r.resolution(module, key).try_borrow().ok().and_then(|r| r.binding); debug!(?binding); } + + let feed_visibility = |this: &mut Self, def_id| { + let vis = this.r.tcx.visibility(def_id).expect_local(); + this.r.feed_visibility(this.r.local_def_id(id), vis); + }; + let Some(binding) = binding else { // We could not find the method: report an error. let candidate = self.find_similarly_named_assoc_item(ident.name, kind); let path = &self.current_trait_ref.as_ref().unwrap().1.path; let path_names = path_names_to_string(path); self.report_error(span, err(ident, path_names, candidate)); + feed_visibility(self, module.def_id()); return; }; let res = binding.res(); let Res::Def(def_kind, id_in_trait) = res else { bug!() }; + feed_visibility(self, id_in_trait); match seen_trait_items.entry(id_in_trait) { Entry::Occupied(entry) => { @@ -3112,8 +3120,6 @@ fn check_trait_item( | (DefKind::AssocFn, AssocItemKind::Fn(..)) | (DefKind::AssocConst, AssocItemKind::Const(..)) => { self.r.record_partial_res(id, PartialRes::new(res)); - let vis = self.r.tcx.visibility(id_in_trait).expect_local(); - self.r.feed_visibility(self.r.local_def_id(id), vis); return; } _ => {} diff --git a/tests/ui/privacy/unresolved-trait-impl-item.rs b/tests/ui/privacy/unresolved-trait-impl-item.rs new file mode 100644 index 00000000000..fea7c462a8e --- /dev/null +++ b/tests/ui/privacy/unresolved-trait-impl-item.rs @@ -0,0 +1,15 @@ +// edition:2018 + +trait MyTrait { + async fn resolved(&self); + const RESOLVED_WRONG: u8 = 0; +} + +impl MyTrait for i32 { + async fn resolved(&self) {} + + async fn unresolved(&self) {} //~ ERROR method `unresolved` is not a member of trait `MyTrait` + async fn RESOLVED_WRONG() {} //~ ERROR doesn't match its trait `MyTrait` +} + +fn main() {} diff --git a/tests/ui/privacy/unresolved-trait-impl-item.stderr b/tests/ui/privacy/unresolved-trait-impl-item.stderr new file mode 100644 index 00000000000..588e47c26bc --- /dev/null +++ b/tests/ui/privacy/unresolved-trait-impl-item.stderr @@ -0,0 +1,22 @@ +error[E0407]: method `unresolved` is not a member of trait `MyTrait` + --> $DIR/unresolved-trait-impl-item.rs:11:5 + | +LL | async fn unresolved(&self) {} + | ^^^^^^^^^----------^^^^^^^^^^ + | | | + | | help: there is an associated function with a similar name: `resolved` + | not a member of trait `MyTrait` + +error[E0324]: item `RESOLVED_WRONG` is an associated method, which doesn't match its trait `MyTrait` + --> $DIR/unresolved-trait-impl-item.rs:12:5 + | +LL | const RESOLVED_WRONG: u8 = 0; + | ----------------------------- item in trait +... +LL | async fn RESOLVED_WRONG() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ does not match trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0324, E0407. +For more information about an error, try `rustc --explain E0324`.