about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-01-17 20:15:13 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-01-22 08:29:24 -0800
commit4121ddb041aaa20769c8b31bc6496906c6330170 (patch)
tree1e1b0a47a0bd43a8456ac885078888a561f0a3bd
parentfdc18b3067b5bad257ccbe7400e3c4fb617e9e18 (diff)
downloadrust-4121ddb041aaa20769c8b31bc6496906c6330170.tar.gz
rust-4121ddb041aaa20769c8b31bc6496906c6330170.zip
Do not suggest private traits that have missing method
When encountering a method call for an ADT that doesn't have any
implementation of it, we search for traits that could be implemented
that do have that method. Filter out private non-local traits that would
not be able to be implemented.

This doesn't account for public traits that are in a private scope, but
works as a first approximation and is a more correct behavior than the
current one.
-rw-r--r--src/librustc_typeck/check/method/suggest.rs9
-rw-r--r--src/librustc_typeck/lib.rs3
-rw-r--r--src/test/ui/impl-trait/no-method-suggested-traits.stderr12
-rw-r--r--src/test/ui/method-call-err-msg.stderr6
-rw-r--r--src/test/ui/suggestions/dont-suggest-private-trait-method.rs16
-rw-r--r--src/test/ui/suggestions/dont-suggest-private-trait-method.stderr11
6 files changed, 42 insertions, 15 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 3f8792aa637..4556b5a42b3 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -513,8 +513,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 // this isn't perfect (that is, there are cases when
                 // implementing a trait would be legal but is rejected
                 // here).
-                (type_is_local || info.def_id.is_local())
-                    && self.associated_item(info.def_id, item_name, Namespace::Value).is_some()
+                (type_is_local || info.def_id.is_local()) &&
+                    self.associated_item(info.def_id, item_name, Namespace::Value)
+                        .filter(|item| {
+                            // We only want to suggest public or local traits (#45781).
+                            item.vis == ty::Visibility::Public || info.def_id.is_local()
+                        })
+                        .is_some()
             })
             .collect::<Vec<_>>();
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 786a6783440..75a74e1069c 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -75,12 +75,13 @@ This API is completely unstable and subject to change.
 #![feature(advanced_slice_patterns)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(crate_visibility_modifier)]
 #![feature(conservative_impl_trait)]
 #![feature(copy_closures, clone_closures)]
+#![feature(crate_visibility_modifier)]
 #![feature(from_ref)]
 #![feature(match_default_bindings)]
 #![feature(never_type)]
+#![feature(option_filter)]
 #![feature(quote)]
 #![feature(refcell_replace_swap)]
 #![feature(rustc_diagnostic_macros)]
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index 4517f09d07c..882113b8176 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -95,10 +95,8 @@ error[E0599]: no method named `method` found for type `Foo` in the current scope
    = note: the following traits define an item `method`, perhaps you need to implement one of them:
            candidate #1: `foo::Bar`
            candidate #2: `no_method_suggested_traits::foo::PubPub`
-           candidate #3: `no_method_suggested_traits::bar::PubPriv`
-           candidate #4: `no_method_suggested_traits::qux::PrivPub`
-           candidate #5: `no_method_suggested_traits::quz::PrivPriv`
-           candidate #6: `no_method_suggested_traits::Reexported`
+           candidate #3: `no_method_suggested_traits::qux::PrivPub`
+           candidate #4: `no_method_suggested_traits::Reexported`
 
 error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:52:43
@@ -110,10 +108,8 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
    = note: the following traits define an item `method`, perhaps you need to implement one of them:
            candidate #1: `foo::Bar`
            candidate #2: `no_method_suggested_traits::foo::PubPub`
-           candidate #3: `no_method_suggested_traits::bar::PubPriv`
-           candidate #4: `no_method_suggested_traits::qux::PrivPub`
-           candidate #5: `no_method_suggested_traits::quz::PrivPriv`
-           candidate #6: `no_method_suggested_traits::Reexported`
+           candidate #3: `no_method_suggested_traits::qux::PrivPub`
+           candidate #4: `no_method_suggested_traits::Reexported`
 
 error[E0599]: no method named `method2` found for type `u64` in the current scope
   --> $DIR/no-method-suggested-traits.rs:55:10
diff --git a/src/test/ui/method-call-err-msg.stderr b/src/test/ui/method-call-err-msg.stderr
index 8685d0fc9c1..f9524696ed7 100644
--- a/src/test/ui/method-call-err-msg.stderr
+++ b/src/test/ui/method-call-err-msg.stderr
@@ -38,10 +38,8 @@ error[E0599]: no method named `take` found for type `Foo` in the current scope
            `&mut Foo : std::iter::Iterator`
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following traits define an item `take`, perhaps you need to implement one of them:
-           candidate #1: `std::collections::hash::Recover`
-           candidate #2: `std::io::Read`
-           candidate #3: `std::iter::Iterator`
-           candidate #4: `alloc::btree::Recover`
+           candidate #1: `std::io::Read`
+           candidate #2: `std::iter::Iterator`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/suggestions/dont-suggest-private-trait-method.rs b/src/test/ui/suggestions/dont-suggest-private-trait-method.rs
new file mode 100644
index 00000000000..99bee0d3c59
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-private-trait-method.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct T;
+
+fn main() {
+    T::new();
+    //~^ ERROR no function or associated item named `new` found for type `T` in the current scope
+}
diff --git a/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr b/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr
new file mode 100644
index 00000000000..97f424f9fbf
--- /dev/null
+++ b/src/test/ui/suggestions/dont-suggest-private-trait-method.stderr
@@ -0,0 +1,11 @@
+error[E0599]: no function or associated item named `new` found for type `T` in the current scope
+  --> $DIR/dont-suggest-private-trait-method.rs:14:5
+   |
+11 | struct T;
+   | --------- function or associated item `new` not found for this
+...
+14 |     T::new();
+   |     ^^^^^^ function or associated item not found in `T`
+
+error: aborting due to previous error
+