diff options
| author | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2023-01-25 20:11:05 +0100 |
|---|---|---|
| committer | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2023-01-25 21:25:42 +0100 |
| commit | 943000fdcf9eac6c77b44923f551409aa06a46b5 (patch) | |
| tree | ba91fa9df8a942a3f8ad8dfcc671e2df4a4aab43 | |
| parent | b222f2e2660f8d81dc30061c918d774147fcf1a6 (diff) | |
| download | rust-943000fdcf9eac6c77b44923f551409aa06a46b5.tar.gz rust-943000fdcf9eac6c77b44923f551409aa06a46b5.zip | |
Use `can_eq` to compare types for default assoc type error
This works correctly with inference variables.
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 |
