about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-05-12 10:56:26 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-05-12 10:56:26 -0700
commita3f30bbc2d28572f9fa429cf3b31d7f95d3b0dda (patch)
treea2351c62ef4b8e951b03358a36a6e005e502d88c
parentd903a9def4c29846ec6215ccc7fa76d39428f577 (diff)
downloadrust-a3f30bbc2d28572f9fa429cf3b31d7f95d3b0dda.tar.gz
rust-a3f30bbc2d28572f9fa429cf3b31d7f95d3b0dda.zip
Don't `type_of` on trait assoc ty without default
Fix #72076.
-rw-r--r--src/librustc_middle/ty/error.rs13
-rw-r--r--src/test/ui/issues/issue-72076.rs6
-rw-r--r--src/test/ui/issues/issue-72076.stderr14
-rw-r--r--src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs1
-rw-r--r--src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr37
5 files changed, 54 insertions, 17 deletions
diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs
index f3b6a53dfeb..00be12f46fe 100644
--- a/src/librustc_middle/ty/error.rs
+++ b/src/librustc_middle/ty/error.rs
@@ -817,19 +817,18 @@ fn foo(&self) -> Self::T { String::new() }
                 for item in &items[..] {
                     match item.kind {
                         hir::AssocItemKind::Type | hir::AssocItemKind::OpaqueTy => {
-                            if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found {
-                                if let hir::Defaultness::Default { has_value: true } =
-                                    item.defaultness
-                                {
+                            // FIXME: account for returning some type in a trait fn impl that has
+                            // an assoc type as a return type (#72076).
+                            if let hir::Defaultness::Default { has_value: true } = item.defaultness
+                            {
+                                if self.type_of(self.hir().local_def_id(item.id.hir_id)) == found {
                                     db.span_label(
                                         item.span,
                                         "associated type defaults can't be assumed inside the \
                                             trait defining them",
                                     );
-                                } else {
-                                    db.span_label(item.span, "expected this associated type");
+                                    return true;
                                 }
-                                return true;
                             }
                         }
                         _ => {}
diff --git a/src/test/ui/issues/issue-72076.rs b/src/test/ui/issues/issue-72076.rs
new file mode 100644
index 00000000000..1659044a64f
--- /dev/null
+++ b/src/test/ui/issues/issue-72076.rs
@@ -0,0 +1,6 @@
+trait X {
+    type S;
+    fn f() -> Self::S {} //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-72076.stderr b/src/test/ui/issues/issue-72076.stderr
new file mode 100644
index 00000000000..b942cf75b06
--- /dev/null
+++ b/src/test/ui/issues/issue-72076.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-72076.rs:3:23
+   |
+LL |     fn f() -> Self::S {}
+   |                       ^^ expected associated type, found `()`
+   |
+   = note: expected associated type `<Self as X>::S`
+                    found unit type `()`
+   = help: consider constraining the associated type `<Self as X>::S` to `()` or calling a method that returns `<Self as X>::S`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs
index 7465049787f..0d90e449523 100644
--- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs
+++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.rs
@@ -7,6 +7,7 @@ trait Trait<T = Self> {
 
     fn func(&self) -> Self::A;
     fn funk(&self, _: Self::A);
+    fn funq(&self) -> Self::A {} //~ ERROR mismatched types
 }
 
 fn foo(_: impl Trait, x: impl Trait) {
diff --git a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
index 5ae1d45c6b7..e629f8f970d 100644
--- a/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
+++ b/src/test/ui/suggestions/trait-with-missing-associated-type-restriction.stderr
@@ -1,5 +1,19 @@
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:13:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:10:31
+   |
+LL |     fn funq(&self) -> Self::A {}
+   |                               ^^ expected associated type, found `()`
+   |
+   = note: expected associated type `<Self as Trait<T>>::A`
+                    found unit type `()`
+help: a method is available that returns `<Self as Trait<T>>::A`
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:8:5
+   |
+LL |     fn func(&self) -> Self::A;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::func`
+
+error[E0308]: mismatched types
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:14:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found associated type
@@ -12,7 +26,7 @@ LL | fn foo(_: impl Trait, x: impl Trait<A = usize>) {
    |                                    ^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:17:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:18:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found associated type
@@ -25,7 +39,7 @@ LL | fn bar<T: Trait<A = usize>>(x: T) {
    |                ^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:21:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:22:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found associated type
@@ -38,25 +52,28 @@ LL | fn foo2(x: impl Trait<i32, A = usize>) {
    |                          ^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:25:12
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:26:12
    |
 LL |     x.funk(3);
    |            ^ expected associated type, found integer
    |
    = note: expected associated type `<T as Trait<i32>>::A`
                          found type `{integer}`
-help: a method is available that returns `<T as Trait<i32>>::A`
+help: some methods are available that return `<T as Trait<i32>>::A`
   --> $DIR/trait-with-missing-associated-type-restriction.rs:8:5
    |
 LL |     fn func(&self) -> Self::A;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::func`
+LL |     fn funk(&self, _: Self::A);
+LL |     fn funq(&self) -> Self::A {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq`
 help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}`
    |
 LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) {
    |                     ^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:26:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:27:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found associated type
@@ -69,7 +86,7 @@ LL | fn bar2<T: Trait<i32, A = usize>>(x: T) {
    |                     ^^^^^^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:30:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:31:9
    |
 LL | fn baz<D: std::fmt::Debug, T: Trait<A = D>>(x: T) {
    |        - this type parameter
@@ -80,13 +97,13 @@ LL |     qux(x.func())
            found type parameter `D`
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:34:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:35:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found `()`
 
 error[E0308]: mismatched types
-  --> $DIR/trait-with-missing-associated-type-restriction.rs:38:9
+  --> $DIR/trait-with-missing-associated-type-restriction.rs:39:9
    |
 LL |     qux(x.func())
    |         ^^^^^^^^ expected `usize`, found associated type
@@ -98,6 +115,6 @@ help: consider constraining the associated type `<T as Trait>::A` to `usize`
 LL | fn ban<T>(x: T) where T: Trait<A = usize> {
    |                               ^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
 For more information about this error, try `rustc --explain E0308`.