about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/late.rs10
-rw-r--r--tests/ui/privacy/unresolved-trait-impl-item.rs15
-rw-r--r--tests/ui/privacy/unresolved-trait-impl-item.stderr22
3 files changed, 45 insertions, 2 deletions
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 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             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 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             | (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`.