Skip to content

Commit 943000f

Browse files
committed
Use can_eq to compare types for default assoc type error
This works correctly with inference variables.
1 parent b222f2e commit 943000f

File tree

7 files changed

+49
-17
lines changed

7 files changed

+49
-17
lines changed

Diff for: compiler/rustc_infer/src/infer/error_reporting/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
18501850

18511851
self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());
18521852

1853-
18541853
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
18551854
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
18561855
&& let Some(def_id) = def_id.as_local()

Diff for: compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,11 @@ fn foo(&tcx) -> Self::T { String::new() }
515515
// `expected` and point at it.
516516
let parent_id = tcx.hir().get_parent_item(hir_id);
517517
let item = tcx.hir().find_by_def_id(parent_id.def_id);
518+
518519
debug!("expected_projection parent item {:?}", item);
520+
521+
let param_env = tcx.param_env(body_owner_def_id);
522+
519523
match item {
520524
Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., items), .. })) => {
521525
// FIXME: account for `#![feature(specialization)]`
@@ -527,7 +531,8 @@ fn foo(&tcx) -> Self::T { String::new() }
527531
if let hir::Defaultness::Default { has_value: true } =
528532
tcx.impl_defaultness(item.id.owner_id)
529533
{
530-
if tcx.type_of(item.id.owner_id) == found {
534+
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
535+
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
531536
diag.span_label(
532537
item.span,
533538
"associated type defaults can't be assumed inside the \
@@ -547,7 +552,9 @@ fn foo(&tcx) -> Self::T { String::new() }
547552
})) => {
548553
for item in &items[..] {
549554
if let hir::AssocItemKind::Type = item.kind {
550-
if tcx.type_of(item.id.owner_id) == found {
555+
let assoc_ty = tcx.bound_type_of(item.id.owner_id).subst_identity();
556+
557+
if self.infcx.can_eq(param_env, assoc_ty, found).is_ok() {
551558
diag.span_label(item.span, "expected this associated type");
552559
return true;
553560
}

Diff for: compiler/rustc_middle/src/ty/query.rs

+8
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ impl<'tcx> TyCtxt<'tcx> {
441441
self.opt_def_kind(def_id)
442442
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
443443
}
444+
445+
pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
446+
ty::EarlyBinder(self.type_of(def_id))
447+
}
444448
}
445449

446450
impl<'tcx> TyCtxtAt<'tcx> {
@@ -449,4 +453,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
449453
self.opt_def_kind(def_id)
450454
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
451455
}
456+
457+
pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
458+
ty::EarlyBinder(self.type_of(def_id))
459+
}
452460
}

Diff for: compiler/rustc_middle/src/ty/util.rs

-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
44
use crate::mir;
55
use crate::ty::layout::IntegerExt;
6-
use crate::ty::query::TyCtxtAt;
76
use crate::ty::{
87
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
98
TypeVisitable,
@@ -637,10 +636,6 @@ impl<'tcx> TyCtxt<'tcx> {
637636
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
638637
}
639638

640-
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
641-
ty::EarlyBinder(self.type_of(def_id))
642-
}
643-
644639
pub fn bound_return_position_impl_trait_in_trait_tys(
645640
self,
646641
def_id: DefId,
@@ -738,12 +733,6 @@ impl<'tcx> TyCtxt<'tcx> {
738733
}
739734
}
740735

741-
impl<'tcx> TyCtxtAt<'tcx> {
742-
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
743-
ty::EarlyBinder(self.type_of(def_id))
744-
}
745-
}
746-
747736
struct OpaqueTypeExpander<'tcx> {
748737
// Contains the DefIds of the opaque types that are currently being
749738
// expanded. When we expand an opaque type we insert the DefId of

Diff for: tests/ui/associated-types/defaults-in-other-trait-items.rs

+14
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,18 @@ impl AssocConst for () {
4444
const C: Self::Ty = 0u8;
4545
}
4646

47+
pub trait Trait {
48+
type Res = isize; //~ NOTE associated type defaults can't be assumed inside the trait defining them
49+
50+
fn infer_me_correctly() -> Self::Res {
51+
//~^ NOTE expected `<Self as Trait>::Res` because of return type
52+
53+
// {integer} == isize
54+
2
55+
//~^ ERROR mismatched types
56+
//~| NOTE expected associated type, found integer
57+
//~| NOTE expected associated type `<Self as Trait>::Res`
58+
}
59+
}
60+
4761
fn main() {}

Diff for: tests/ui/associated-types/defaults-in-other-trait-items.stderr

+16-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ LL | const C: Self::Ty = 0u8;
2424
= note: expected associated type `<Self as AssocConst>::Ty`
2525
found type `u8`
2626

27-
error: aborting due to 2 previous errors
27+
error[E0308]: mismatched types
28+
--> $DIR/defaults-in-other-trait-items.rs:54:9
29+
|
30+
LL | type Res = isize;
31+
| ----------------- associated type defaults can't be assumed inside the trait defining them
32+
LL |
33+
LL | fn infer_me_correctly() -> Self::Res {
34+
| --------- expected `<Self as Trait>::Res` because of return type
35+
...
36+
LL | 2
37+
| ^ expected associated type, found integer
38+
|
39+
= note: expected associated type `<Self as Trait>::Res`
40+
found type `{integer}`
41+
42+
error: aborting due to 3 previous errors
2843

2944
For more information about this error, try `rustc --explain E0308`.

Diff for: tests/ui/associated-types/issue-26681.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-26681.rs:17:39
33
|
4+
LL | type Fv: Foo = u8;
5+
| ------------------ associated type defaults can't be assumed inside the trait defining them
46
LL | const C: <Self::Fv as Foo>::Bar = 6665;
57
| ^^^^ expected associated type, found integer
68
|
79
= note: expected associated type `<<Self as Baz>::Fv as Foo>::Bar`
810
found type `{integer}`
9-
= help: consider constraining the associated type `<<Self as Baz>::Fv as Foo>::Bar` to `{integer}`
10-
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
1111

1212
error: aborting due to previous error
1313

0 commit comments

Comments
 (0)