Skip to content

Commit 5558fe8

Browse files
committed
Suggest correct code when encountering an incorrect trait bound referencing the current trait
1 parent 87cbf0a commit 5558fe8

File tree

5 files changed

+40
-3
lines changed

5 files changed

+40
-3
lines changed

src/librustc_typeck/astconv.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ pub struct PathSeg(pub DefId, pub usize);
4343
pub trait AstConv<'tcx> {
4444
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
4545

46+
fn item_def_id(&self) -> Option<DefId>;
47+
4648
/// Returns predicates in scope of the form `X: Foo`, where `X` is
4749
/// a type parameter `X` with the given id `def_id`. This is a
4850
/// subset of the full set of predicates.
@@ -1759,17 +1761,31 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
17591761
-> Ty<'tcx>
17601762
{
17611763
let tcx = self.tcx();
1764+
17621765
let trait_def_id = tcx.parent(item_def_id).unwrap();
17631766

1767+
debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
1768+
17641769
self.prohibit_generics(slice::from_ref(item_segment));
17651770

17661771
let self_ty = if let Some(ty) = opt_self_ty {
17671772
ty
17681773
} else {
17691774
let path_str = tcx.def_path_str(trait_def_id);
1775+
1776+
// If the trait in segment is the same as the trait defining the item,
1777+
// use the `<Self as ..>` syntax in the error.
1778+
debug!("qpath_to_ty: self.item_def_id()={:?}", self.item_def_id());
1779+
1780+
let type_name = if self.item_def_id() == Some(trait_def_id) {
1781+
"Self"
1782+
} else {
1783+
"Type"
1784+
};
1785+
17701786
self.report_ambiguous_associated_type(
17711787
span,
1772-
"Type",
1788+
type_name,
17731789
&path_str,
17741790
item_segment.ident.name,
17751791
);

src/librustc_typeck/check/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,10 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
22792279
self.tcx
22802280
}
22812281

2282+
fn item_def_id(&self) -> Option<DefId> {
2283+
None
2284+
}
2285+
22822286
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
22832287
let tcx = self.tcx;
22842288
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();

src/librustc_typeck/collect.rs

+4
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
182182
self.tcx
183183
}
184184

185+
fn item_def_id(&self) -> Option<DefId> {
186+
Some(self.item_def_id)
187+
}
188+
185189
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
186190
self.tcx
187191
.at(span)

src/test/ui/associated-types/associated-types-in-ambiguous-context.rs

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ trait Grab {
1212
//~^ ERROR ambiguous associated type
1313
}
1414

15+
trait Bar {}
16+
17+
trait Foo where Foo::Assoc: Bar {
18+
//~^ ERROR ambiguous associated type
19+
type Assoc;
20+
}
21+
1522
type X = std::ops::Deref::Target;
1623
//~^ ERROR ambiguous associated type
1724

src/test/ui/associated-types/associated-types-in-ambiguous-context.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ LL | fn get<T:Get,U:Get>(x: T, y: U) -> Get::Value {}
55
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Get>::Value`
66

77
error[E0223]: ambiguous associated type
8-
--> $DIR/associated-types-in-ambiguous-context.rs:15:10
8+
--> $DIR/associated-types-in-ambiguous-context.rs:17:17
9+
|
10+
LL | trait Foo where Foo::Assoc: Bar {
11+
| ^^^^^^^^^^ help: use fully-qualified syntax: `<Self as Foo>::Assoc`
12+
13+
error[E0223]: ambiguous associated type
14+
--> $DIR/associated-types-in-ambiguous-context.rs:22:10
915
|
1016
LL | type X = std::ops::Deref::Target;
1117
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as std::ops::Deref>::Target`
@@ -16,6 +22,6 @@ error[E0223]: ambiguous associated type
1622
LL | fn grab(&self) -> Grab::Value;
1723
| ^^^^^^^^^^^ help: use fully-qualified syntax: `<Type as Grab>::Value`
1824

19-
error: aborting due to 3 previous errors
25+
error: aborting due to 4 previous errors
2026

2127
For more information about this error, try `rustc --explain E0223`.

0 commit comments

Comments
 (0)