about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-12-30 21:15:40 -0800
committerEsteban Küber <esteban@kuber.com.ar>2020-01-08 09:41:51 -0800
commitac3d4cccea3225468a3c8ff8ea18b60166c84fb8 (patch)
tree5b35898d4c14ad08c286fadbd4212930f9657243 /src
parented6468da160bd67a2ce0573427f09a98daff8c07 (diff)
downloadrust-ac3d4cccea3225468a3c8ff8ea18b60166c84fb8.tar.gz
rust-ac3d4cccea3225468a3c8ff8ea18b60166c84fb8.zip
Explain that associated types and consts can't be accessed directly on the trait's path
Diffstat (limited to 'src')
-rw-r--r--src/librustc/traits/error_reporting.rs25
-rw-r--r--src/test/ui/associated-const/issue-63496.stderr12
-rw-r--r--src/test/ui/associated-item/issue-48027.stderr6
-rw-r--r--src/test/ui/issues/issue-58022.stderr6
4 files changed, 44 insertions, 5 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 00251d55706..a856d2fd960 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -2075,7 +2075,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
                 let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283);
                 err.note(&format!("cannot resolve `{}`", predicate));
-                if let (Ok(ref snippet), ObligationCauseCode::BindingObligation(ref def_id, _)) =
+                if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code {
+                    if let Some(assoc_item) = self.tcx.opt_associated_item(def_id) {
+                        if let ty::AssocKind::Const | ty::AssocKind::Type = assoc_item.kind {
+                            err.note(&format!(
+                                "{}s cannot be accessed directly on a `trait`, they can only be \
+                                 accessed through a specific `impl`",
+                                assoc_item.kind.suggestion_descr(),
+                            ));
+                            err.span_suggestion(
+                                span,
+                                "use the fully qualified path to an implementation",
+                                format!(
+                                    "<Type as {}>::{}",
+                                    self.tcx.def_path_str(trait_ref.def_id()),
+                                    assoc_item.ident
+                                ),
+                                Applicability::HasPlaceholders,
+                            );
+                        }
+                    }
+                } else if let (
+                    Ok(ref snippet),
+                    ObligationCauseCode::BindingObligation(ref def_id, _),
+                ) =
                     (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code)
                 {
                     let generics = self.tcx.generics_of(*def_id);
diff --git a/src/test/ui/associated-const/issue-63496.stderr b/src/test/ui/associated-const/issue-63496.stderr
index 23916a3ba44..3a70e7d43c2 100644
--- a/src/test/ui/associated-const/issue-63496.stderr
+++ b/src/test/ui/associated-const/issue-63496.stderr
@@ -5,9 +5,13 @@ LL |     const C: usize;
    |     --------------- required by `A::C`
 LL | 
 LL |     fn f() -> ([u8; A::C], [u8; A::C]);
-   |                     ^^^^ cannot infer type
+   |                     ^^^^
+   |                     |
+   |                     cannot infer type
+   |                     help: use the fully qualified path to an implementation: `<Type as A>::C`
    |
    = note: cannot resolve `_: A`
+   = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error[E0283]: type annotations needed
   --> $DIR/issue-63496.rs:4:33
@@ -16,9 +20,13 @@ LL |     const C: usize;
    |     --------------- required by `A::C`
 LL | 
 LL |     fn f() -> ([u8; A::C], [u8; A::C]);
-   |                                 ^^^^ cannot infer type
+   |                                 ^^^^
+   |                                 |
+   |                                 cannot infer type
+   |                                 help: use the fully qualified path to an implementation: `<Type as A>::C`
    |
    = note: cannot resolve `_: A`
+   = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr
index 9c825d593d3..ddabd552897 100644
--- a/src/test/ui/associated-item/issue-48027.stderr
+++ b/src/test/ui/associated-item/issue-48027.stderr
@@ -13,9 +13,13 @@ error[E0283]: type annotations needed
 LL |     const X: usize;
    |     --------------- required by `Bar::X`
 LL |     fn return_n(&self) -> [u8; Bar::X];
-   |                                ^^^^^^ cannot infer type
+   |                                ^^^^^^
+   |                                |
+   |                                cannot infer type
+   |                                help: use the fully qualified path to an implementation: `<Type as Bar>::X`
    |
    = note: cannot resolve `_: Bar`
+   = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-58022.stderr b/src/test/ui/issues/issue-58022.stderr
index ef0d66d7ad6..70a7c38b834 100644
--- a/src/test/ui/issues/issue-58022.stderr
+++ b/src/test/ui/issues/issue-58022.stderr
@@ -11,9 +11,13 @@ LL |     const SIZE: usize;
    |     ------------------ required by `Foo::SIZE`
 LL | 
 LL |     fn new(slice: &[u8; Foo::SIZE]) -> Self;
-   |                         ^^^^^^^^^ cannot infer type
+   |                         ^^^^^^^^^
+   |                         |
+   |                         cannot infer type
+   |                         help: use the fully qualified path to an implementation: `<Type as Foo>::SIZE`
    |
    = note: cannot resolve `_: Foo`
+   = note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
 
 error: aborting due to 2 previous errors