Skip to content

Commit 120c24d

Browse files
committed
Point at appropriate type parameter in more trait bound errors
1 parent ac89e16 commit 120c24d

18 files changed

+85
-58
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6767
})
6868
};
6969

70+
// Account for enum variant constructors, where the type param corresponds to the enum
71+
// itself.
72+
let enum_def_id = if let hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _) =
73+
self.tcx.def_kind(def_id)
74+
{
75+
// `def_id` corresponds to a constructor, and its parent is the variant, and we want
76+
// the enum.
77+
Some(self.tcx.parent(self.tcx.parent(def_id)))
78+
} else {
79+
None
80+
};
81+
let variant_param_to_point_at = find_param_matching(&|param_term| {
82+
// FIXME: It would be nice to make this not use string manipulation,
83+
// but it's pretty hard to do this, since `ty::ParamTy` is missing
84+
// sufficient info to determine if it is synthetic, and we don't
85+
// always have a convenient way of getting `ty::Generics` at the call
86+
// sites we invoke `IsSuggestable::is_suggestable`.
87+
let include = match param_term {
88+
ty::ParamTerm::Ty(param_ty) => !param_ty.name.as_str().starts_with("impl "),
89+
_ => true,
90+
};
91+
// Account for enum variant constructors, where the type param corresponds to the enum
92+
// itself.
93+
let def_id = if let Some(def_id) = enum_def_id {
94+
def_id
95+
} else {
96+
def_id
97+
};
98+
self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id
99+
&& include
100+
});
70101
// Prefer generics that are local to the fn item, since these are likely
71102
// to be the cause of the unsatisfied predicate.
72103
let mut param_to_point_at = find_param_matching(&|param_term| {
@@ -102,6 +133,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
102133

103134
match &expr.kind {
104135
hir::ExprKind::Path(qpath) => {
136+
let def_id = if let Some(def_id) = enum_def_id {
137+
def_id
138+
} else {
139+
def_id
140+
};
141+
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind {
142+
for segment in path.segments {
143+
if let Some(param) = variant_param_to_point_at
144+
&& self.point_at_generic_if_possible(error, def_id, param, segment)
145+
{
146+
return true;
147+
}
148+
}
149+
}
105150
if let hir::Node::Expr(hir::Expr {
106151
kind: hir::ExprKind::Call(callee, args),
107152
hir_id: call_hir_id,

tests/ui/associated-types/associated-types-issue-20346.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
2-
--> $DIR/associated-types-issue-20346.rs:34:36
2+
--> $DIR/associated-types-issue-20346.rs:34:33
33
|
44
LL | fn test_adapter<T, I: Iterator<Item=Option<T>>>(it: I) {
55
| - this type parameter
66
...
77
LL | is_iterator_of::<Option<T>, _>(&adapter);
8-
| ------------------------------ ^^^^^^^^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
9-
| |
10-
| required by a bound introduced by this call
8+
| ^ type mismatch resolving `<Adapter<I> as Iterator>::Item == Option<T>`
119
|
1210
note: expected this to be `Option<T>`
1311
--> $DIR/associated-types-issue-20346.rs:23:17

tests/ui/function-pointer/unsized-ret.stderr

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
error[E0277]: the size for values of type `str` cannot be known at compilation time
2-
--> $DIR/unsized-ret.rs:10:27
2+
--> $DIR/unsized-ret.rs:10:11
33
|
44
LL | foo::<fn() -> str, _>(None, ());
5-
| --------------------- ^^^^ doesn't have a size known at compile-time
6-
| |
7-
| required by a bound introduced by this call
5+
| ^^^^^^^^^^^ doesn't have a size known at compile-time
86
|
97
= help: within `fn() -> str`, the trait `Sized` is not implemented for `str`
108
= note: required because it appears within the type `fn() -> str`
@@ -15,12 +13,10 @@ LL | fn foo<F: Fn<T>, T:std::marker::Tuple>(f: Option<F>, t: T) {
1513
| ^^^^^ required by this bound in `foo`
1614

1715
error[E0277]: the size for values of type `(dyn std::fmt::Display + 'a)` cannot be known at compilation time
18-
--> $DIR/unsized-ret.rs:13:66
16+
--> $DIR/unsized-ret.rs:13:11
1917
|
2018
LL | foo::<for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a), _>(None, (&(),));
21-
| ------------------------------------------------------------ ^^^^ doesn't have a size known at compile-time
22-
| |
23-
| required by a bound introduced by this call
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
2420
|
2521
= help: within `for<'a> fn(&'a ()) -> (dyn std::fmt::Display + 'a)`, the trait `for<'a> Sized` is not implemented for `(dyn std::fmt::Display + 'a)`
2622
= note: required because it appears within the type `fn(&()) -> dyn Display`

tests/ui/issues/issue-87199.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1818

1919
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
20-
--> $DIR/issue-87199.rs:18:22
20+
--> $DIR/issue-87199.rs:18:15
2121
|
2222
LL | ref_arg::<[i32]>(&[5]);
23-
| ---------------- ^^^^ doesn't have a size known at compile-time
24-
| |
25-
| required by a bound introduced by this call
23+
| ^^^^^ doesn't have a size known at compile-time
2624
|
2725
= help: the trait `Sized` is not implemented for `[i32]`
2826
note: required by a bound in `ref_arg`

tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
error[E0277]: the trait bound `for<'b> &'b S: Trait` is not satisfied
2-
--> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:14
2+
--> $DIR/imm-ref-trait-object-literal-bound-regions.rs:17:11
33
|
44
LL | foo::<S>(s);
5-
| -------- ^ the trait `for<'b> Trait` is not implemented for `&'b S`
6-
| |
7-
| required by a bound introduced by this call
5+
| ^ the trait `for<'b> Trait` is not implemented for `&'b S`
86
|
97
= help: the trait `Trait` is implemented for `&'a mut S`
108
= note: `for<'b> Trait` is implemented for `&'b mut S`, but not for `&'b S`

tests/ui/traits/new-solver/builtin-fn-must-return-sized.stderr

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
error[E0277]: expected a `Fn<_>` closure, found `fn() -> str`
2-
--> $DIR/builtin-fn-must-return-sized.rs:15:27
2+
--> $DIR/builtin-fn-must-return-sized.rs:15:11
33
|
44
LL | foo::<fn() -> str, _>(None, ());
5-
| --------------------- ^^^^ expected an `Fn<_>` closure, found `fn() -> str`
6-
| |
7-
| required by a bound introduced by this call
5+
| ^^^^^^^^^^^ expected an `Fn<_>` closure, found `fn() -> str`
86
|
97
= help: the trait `Fn<_>` is not implemented for `fn() -> str`
108
note: required by a bound in `foo`

tests/ui/traits/new-solver/cycles/coinduction/fixpoint-exponential-growth.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | impls::<W<_>>();
55
| ^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls`
66

77
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
8-
--> $DIR/fixpoint-exponential-growth.rs:29:5
8+
--> $DIR/fixpoint-exponential-growth.rs:29:13
99
|
1010
LL | impls::<W<_>>();
11-
| ^^^^^^^^^^^^^
11+
| ^^^^
1212
|
1313
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
1414
note: required by a bound in `impls`

tests/ui/traits/new-solver/cycles/double-cycle-inductive-coinductive.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0275]: overflow evaluating the requirement `(): Trait`
2-
--> $DIR/double-cycle-inductive-coinductive.rs:32:5
2+
--> $DIR/double-cycle-inductive-coinductive.rs:32:19
33
|
44
LL | impls_trait::<()>();
5-
| ^^^^^^^^^^^^^^^^^
5+
| ^^
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
88
note: required by a bound in `impls_trait`
@@ -12,10 +12,10 @@ LL | fn impls_trait<T: Trait>() {}
1212
| ^^^^^ required by this bound in `impls_trait`
1313

1414
error[E0275]: overflow evaluating the requirement `(): TraitRev`
15-
--> $DIR/double-cycle-inductive-coinductive.rs:35:5
15+
--> $DIR/double-cycle-inductive-coinductive.rs:35:23
1616
|
1717
LL | impls_trait_rev::<()>();
18-
| ^^^^^^^^^^^^^^^^^^^^^
18+
| ^^
1919
|
2020
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
2121
note: required by a bound in `impls_trait_rev`

tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0275]: overflow evaluating the requirement `(): AR`
2-
--> $DIR/inductive-not-on-stack.rs:44:5
2+
--> $DIR/inductive-not-on-stack.rs:44:16
33
|
44
LL | impls_ar::<()>();
5-
| ^^^^^^^^^^^^^^
5+
| ^^
66
|
77
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
88
note: required by a bound in `impls_ar`

tests/ui/traits/new-solver/dont-type_of-tait-in-defining-scope.not_send.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed: cannot satisfy `Foo: Send`
2-
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:5
2+
--> $DIR/dont-type_of-tait-in-defining-scope.rs:16:18
33
|
44
LL | needs_send::<Foo>();
5-
| ^^^^^^^^^^^^^^^^^
5+
| ^^^
66
|
77
= note: cannot satisfy `Foo: Send`
88
note: required by a bound in `needs_send`

0 commit comments

Comments
 (0)