about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-01-25 20:11:05 +0100
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2023-01-25 21:25:42 +0100
commit943000fdcf9eac6c77b44923f551409aa06a46b5 (patch)
treeba91fa9df8a942a3f8ad8dfcc671e2df4a4aab43
parentb222f2e2660f8d81dc30061c918d774147fcf1a6 (diff)
downloadrust-943000fdcf9eac6c77b44923f551409aa06a46b5.tar.gz
rust-943000fdcf9eac6c77b44923f551409aa06a46b5.zip
Use `can_eq` to compare types for default assoc type error
This works correctly with inference variables.
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs11
-rw-r--r--compiler/rustc_middle/src/ty/query.rs8
-rw-r--r--compiler/rustc_middle/src/ty/util.rs11
-rw-r--r--tests/ui/associated-types/defaults-in-other-trait-items.rs14
-rw-r--r--tests/ui/associated-types/defaults-in-other-trait-items.stderr17
-rw-r--r--tests/ui/associated-types/issue-26681.stderr4
7 files changed, 49 insertions, 17 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index faba723acda..d19a0007f08 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1850,7 +1850,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
         self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
 
-
         if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
             && let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
             && let Some(def_id) = def_id.as_local()
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 6e781a041e0..425cde3302d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -515,7 +515,11 @@ fn foo(&tcx) -> Self::T { String::new() }
         // `expected` and point at it.
         let parent_id = tcx.hir().get_parent_item(hir_id);
         let item = tcx.hir().find_by_def_id(parent_id.def_id);
+
         debug!("expected_projection parent item {:?}", item);
+
+        let param_env = tcx.param_env(body_owner_def_id);
+
         match item {
             Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. })) => {
                 // FIXME: account for `#![feature(specialization)]`
@@ -527,7 +531,8 @@ fn foo(&tcx) -> Self::T { String::new() }
                             if let hir::Defaultness::Default { has_value: true } =
                                 tcx.impl_defaultness(item.id.owner_id)
                             {
-                                if tcx.type_of(item.id.owner_id) == found {
+                                let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
+                                if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
                                     diag.span_label(
                                         item.span,
                                         "associated type defaults can't be assumed inside the \
@@ -547,7 +552,9 @@ fn foo(&tcx) -> Self::T { String::new() }
             })) => {
                 for item in &items[..] {
                     if let hir::AssocItemKind::Type = item.kind {
-                        if tcx.type_of(item.id.owner_id) == found {
+                        let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
+
+                        if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
                             diag.span_label(item.span, "expected this associated type");
                             return true;
                         }
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 9d4ee22a727..28b9bdf5660 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -441,6 +441,10 @@ impl<'tcx> TyCtxt<'tcx> {
         self.opt_def_kind(def_id)
             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
     }
+
+    pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
+        ty::EarlyBinder(self.type_of(def_id))
+    }
 }
 
 impl<'tcx> TyCtxtAt<'tcx> {
@@ -449,4 +453,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
         self.opt_def_kind(def_id)
             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
     }
+
+    pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
+        ty::EarlyBinder(self.type_of(def_id))
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 60076c8cb5f..95abbb50380 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -3,7 +3,6 @@
 use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use crate::mir;
 use crate::ty::layout::IntegerExt;
-use crate::ty::query::TyCtxtAt;
 use crate::ty::{
     self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
     TypeVisitable,
@@ -637,10 +636,6 @@ impl<'tcx> TyCtxt<'tcx> {
         if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
     }
 
-    pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
-        ty::EarlyBinder(self.type_of(def_id))
-    }
-
     pub fn bound_return_position_impl_trait_in_trait_tys(
         self,
         def_id: DefId,
@@ -738,12 +733,6 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxtAt<'tcx> {
-    pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
-        ty::EarlyBinder(self.type_of(def_id))
-    }
-}
-
 struct OpaqueTypeExpander<'tcx> {
     // Contains the DefIds of the opaque types that are currently being
     // expanded. When we expand an opaque type we insert the DefId of
diff --git a/tests/ui/associated-types/defaults-in-other-trait-items.rs b/tests/ui/associated-types/defaults-in-other-trait-items.rs
index 505751969b6..f263809552f 100644
--- a/tests/ui/associated-types/defaults-in-other-trait-items.rs
+++ b/tests/ui/associated-types/defaults-in-other-trait-items.rs
@@ -44,4 +44,18 @@ impl AssocConst for () {
     const C: Self::Ty = 0u8;
 }
 
+pub trait Trait {
+    type Res = isize; //~ NOTE associated type defaults can't be assumed inside the trait defining them
+
+    fn infer_me_correctly() -> Self::Res {
+        //~^ NOTE expected `<Self as Trait>::Res` because of return type
+
+        // {integer} == isize
+        2
+        //~^ ERROR mismatched types
+        //~| NOTE expected associated type, found integer
+        //~| NOTE expected associated type `<Self as Trait>::Res`
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/associated-types/defaults-in-other-trait-items.stderr b/tests/ui/associated-types/defaults-in-other-trait-items.stderr
index 71d421926e7..bdcfadd3955 100644
--- a/tests/ui/associated-types/defaults-in-other-trait-items.stderr
+++ b/tests/ui/associated-types/defaults-in-other-trait-items.stderr
@@ -24,6 +24,21 @@ LL |     const C: Self::Ty = 0u8;
    = note: expected associated type `<Self as AssocConst>::Ty`
                          found type `u8`
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/defaults-in-other-trait-items.rs:54:9
+   |
+LL |     type Res = isize;
+   |     ----------------- associated type defaults can't be assumed inside the trait defining them
+LL |
+LL |     fn infer_me_correctly() -> Self::Res {
+   |                                --------- expected `<Self as Trait>::Res` because of return type
+...
+LL |         2
+   |         ^ expected associated type, found integer
+   |
+   = note: expected associated type `<Self as Trait>::Res`
+                         found type `{integer}`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-types/issue-26681.stderr b/tests/ui/associated-types/issue-26681.stderr
index 74411008c9d..977620d9052 100644
--- a/tests/ui/associated-types/issue-26681.stderr
+++ b/tests/ui/associated-types/issue-26681.stderr
@@ -1,13 +1,13 @@
 error[E0308]: mismatched types
   --> $DIR/issue-26681.rs:17:39
    |
+LL |     type Fv: Foo = u8;
+   |     ------------------ associated type defaults can't be assumed inside the trait defining them
 LL |     const C: <Self::Fv as Foo>::Bar = 6665;
    |                                       ^^^^ expected associated type, found integer
    |
    = note: expected associated type `<<Self as Baz>::Fv as Foo>::Bar`
                          found type `{integer}`
-   = help: consider constraining the associated type `<<Self as Baz>::Fv as Foo>::Bar` to `{integer}`
-   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to previous error