From a3f30bbc2d28572f9fa429cf3b31d7f95d3b0dda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 May 2020 10:56:26 -0700 Subject: [PATCH] Don't `type_of` on trait assoc ty without default Fix #72076. --- src/librustc_middle/ty/error.rs | 13 +++---- src/test/ui/issues/issue-72076.rs | 6 +++ src/test/ui/issues/issue-72076.stderr | 14 +++++++ ...ith-missing-associated-type-restriction.rs | 1 + ...missing-associated-type-restriction.stderr | 37 ++++++++++++++----- 5 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/issues/issue-72076.rs create mode 100644 src/test/ui/issues/issue-72076.stderr diff --git a/src/librustc_middle/ty/error.rs b/src/librustc_middle/ty/error.rs index f3b6a53dfeb82..00be12f46fe21 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 0000000000000..1659044a64fe1 --- /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 0000000000000..b942cf75b06a7 --- /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 `::S` + found unit type `()` + = help: consider constraining the associated type `::S` to `()` or calling a method that returns `::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 7465049787f59..0d90e449523a3 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 { 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 5ae1d45c6b703..e629f8f970d32 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 `>::A` + found unit type `()` +help: a method is available that returns `>::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) { | ^^^^^^^^^^^ 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>(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) { | ^^^^^^^^^^^ 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 `>::A` found type `{integer}` -help: a method is available that returns `>::A` +help: some methods are available that return `>::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 `>::A` to `{integer}` | LL | fn bar2>(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>(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>(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 `::A` to `usize` LL | fn ban(x: T) where T: Trait { | ^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0308`.