Skip to content

Commit ac89e16

Browse files
committed
Auto merge of #115221 - compiler-errors:walk-path, r=estebank
Walk through full path in `point_at_path_if_possible` We already had sufficient information to point at the `[u8]` in `Option::<[u8]>::None` (the `fallback_param_to_point_at` parameter), we just were neither using it nor walking through hir paths sufficiently to encounter it. This should alleviate the need to add additional logic to extract params in a somewhat arbitrary manner of looking at the grandparent def path: #115219 (comment) r? `@estebank`
2 parents 734a0d0 + 13e8b13 commit ac89e16

17 files changed

+109
-54
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+60-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::FnCtxt;
22
use rustc_hir as hir;
3-
use rustc_hir::def::Res;
3+
use rustc_hir::def::{DefKind, Res};
44
use rustc_hir::def_id::DefId;
55
use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
66
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -133,15 +133,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
133133
}
134134
}
135135
}
136-
// Notably, we only point to params that are local to the
137-
// item we're checking, since those are the ones we are able
138-
// to look in the final `hir::PathSegment` for. Everything else
139-
// would require a deeper search into the `qpath` than I think
140-
// is worthwhile.
141-
if let Some(param_to_point_at) = param_to_point_at
142-
&& self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
136+
137+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
138+
.into_iter()
139+
.flatten()
143140
{
144-
return true;
141+
if self.point_at_path_if_possible(error, def_id, param, qpath) {
142+
return true;
143+
}
145144
}
146145
}
147146
hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
@@ -166,12 +165,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166165
{
167166
return true;
168167
}
168+
// Handle `Self` param specifically, since it's separated in
169+
// the method call representation
170+
if self_param_to_point_at.is_some() {
171+
error.obligation.cause.span = receiver
172+
.span
173+
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
174+
.unwrap_or(receiver.span);
175+
return true;
176+
}
169177
}
170178
hir::ExprKind::Struct(qpath, fields, ..) => {
171-
if let Res::Def(
172-
hir::def::DefKind::Struct | hir::def::DefKind::Variant,
173-
variant_def_id,
174-
) = self.typeck_results.borrow().qpath_res(qpath, hir_id)
179+
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
180+
self.typeck_results.borrow().qpath_res(qpath, hir_id)
175181
{
176182
for param in
177183
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
@@ -193,10 +199,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
193199
}
194200
}
195201
}
196-
if let Some(param_to_point_at) = param_to_point_at
197-
&& self.point_at_path_if_possible(error, def_id, param_to_point_at, qpath)
202+
203+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
204+
.into_iter()
205+
.flatten()
198206
{
199-
return true;
207+
if self.point_at_path_if_possible(error, def_id, param, qpath) {
208+
return true;
209+
}
200210
}
201211
}
202212
_ => {}
@@ -213,17 +223,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
213223
qpath: &hir::QPath<'tcx>,
214224
) -> bool {
215225
match qpath {
216-
hir::QPath::Resolved(_, path) => {
217-
if let Some(segment) = path.segments.last()
218-
&& self.point_at_generic_if_possible(error, def_id, param, segment)
226+
hir::QPath::Resolved(self_ty, path) => {
227+
for segment in path.segments.iter().rev() {
228+
if let Res::Def(kind, def_id) = segment.res
229+
&& !matches!(kind, DefKind::Mod | DefKind::ForeignMod)
230+
&& self.point_at_generic_if_possible(error, def_id, param, segment)
231+
{
232+
return true;
233+
}
234+
}
235+
// Handle `Self` param specifically, since it's separated in
236+
// the path representation
237+
if let Some(self_ty) = self_ty
238+
&& let ty::GenericArgKind::Type(ty) = param.unpack()
239+
&& ty == self.tcx.types.self_param
219240
{
241+
error.obligation.cause.span = self_ty
242+
.span
243+
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
244+
.unwrap_or(self_ty.span);
220245
return true;
221246
}
222247
}
223-
hir::QPath::TypeRelative(_, segment) => {
248+
hir::QPath::TypeRelative(self_ty, segment) => {
224249
if self.point_at_generic_if_possible(error, def_id, param, segment) {
225250
return true;
226251
}
252+
// Handle `Self` param specifically, since it's separated in
253+
// the path representation
254+
if let ty::GenericArgKind::Type(ty) = param.unpack()
255+
&& ty == self.tcx.types.self_param
256+
{
257+
error.obligation.cause.span = self_ty
258+
.span
259+
.find_ancestor_in_same_ctxt(error.obligation.cause.span)
260+
.unwrap_or(self_ty.span);
261+
return true;
262+
}
227263
}
228264
_ => {}
229265
}
@@ -618,14 +654,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
618654
};
619655

620656
let variant_def_id = match expr_struct_def_kind {
621-
hir::def::DefKind::Struct => {
657+
DefKind::Struct => {
622658
if in_ty_adt.did() != expr_struct_def_id {
623659
// FIXME: Deal with type aliases?
624660
return Err(expr);
625661
}
626662
expr_struct_def_id
627663
}
628-
hir::def::DefKind::Variant => {
664+
DefKind::Variant => {
629665
// If this is a variant, its parent is the type definition.
630666
if in_ty_adt.did() != self.tcx.parent(expr_struct_def_id) {
631667
// FIXME: Deal with type aliases?
@@ -727,14 +763,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
727763
};
728764

729765
let variant_def_id = match expr_struct_def_kind {
730-
hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
766+
DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
731767
if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
732768
// FIXME: Deal with type aliases?
733769
return Err(expr);
734770
}
735771
self.tcx.parent(expr_ctor_def_id)
736772
}
737-
hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
773+
DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
738774
// For a typical enum like
739775
// `enum Blah<T> { Variant(T) }`
740776
// we get the following resolutions:

tests/ui/associated-consts/associated-const-array-len.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `i32: Foo` is not satisfied
2-
--> $DIR/associated-const-array-len.rs:5:16
2+
--> $DIR/associated-const-array-len.rs:5:17
33
|
44
LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
5-
| ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
5+
| ^^^ the trait `Foo` is not implemented for `i32`
66

77
error: aborting due to previous error
88

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
2-
--> $DIR/issue-44153.rs:18:5
2+
--> $DIR/issue-44153.rs:18:6
33
|
44
LL | <() as Visit>::visit();
5-
| ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array>::Element == &()`
5+
| ^^ type mismatch resolving `<() as Array>::Element == &()`
66
|
77
note: expected this to be `&()`
88
--> $DIR/issue-44153.rs:10:20

tests/ui/associated-types/substs-ppaux.normal.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ LL | let x: () = foo::<'static>();
7171
| ++
7272

7373
error[E0277]: the size for values of type `str` cannot be known at compilation time
74-
--> $DIR/substs-ppaux.rs:49:5
74+
--> $DIR/substs-ppaux.rs:49:6
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
77+
| ^^^ doesn't have a size known at compile-time
7878
|
7979
= help: the trait `Sized` is not implemented for `str`
8080
note: required for `str` to implement `Foo<'_, '_, u8>`

tests/ui/associated-types/substs-ppaux.verbose.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ LL | let x: () = foo::<'static>();
7171
| ++
7272

7373
error[E0277]: the size for values of type `str` cannot be known at compilation time
74-
--> $DIR/substs-ppaux.rs:49:5
74+
--> $DIR/substs-ppaux.rs:49:6
7575
|
7676
LL | <str as Foo<u8>>::bar;
77-
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
77+
| ^^^ doesn't have a size known at compile-time
7878
|
7979
= help: the trait `Sized` is not implemented for `str`
8080
note: required for `str` to implement `Foo<'?0, '?1, u8>`

tests/ui/const-generics/dont-evaluate-array-len-on-err-1.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `[Adt; std::mem::size_of::<Self::Assoc>()]: Foo` is not satisfied
2-
--> $DIR/dont-evaluate-array-len-on-err-1.rs:15:9
2+
--> $DIR/dont-evaluate-array-len-on-err-1.rs:15:10
33
|
44
LL | <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; std::mem::size_of::<Self::Assoc>()]`
66

77
error: aborting due to previous error
88

tests/ui/const-generics/exhaustive-value.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `(): Foo<N>` is not satisfied
2-
--> $DIR/exhaustive-value.rs:262:5
2+
--> $DIR/exhaustive-value.rs:262:16
33
|
44
LL | <() as Foo<N>>::test()
5-
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
5+
| ^ the trait `Foo<N>` is not implemented for `()`
66
|
77
= help: the following other types implement trait `Foo<N>`:
88
<() as Foo<0>>

tests/ui/consts/missing-larger-array-impl.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `[X; 35]: Default` is not satisfied
2-
--> $DIR/missing-larger-array-impl.rs:7:5
2+
--> $DIR/missing-larger-array-impl.rs:7:6
33
|
44
LL | <[X; 35] as Default>::default();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
5+
| ^^^^^^^ the trait `Default` is not implemented for `[X; 35]`
66
|
77
= help: the following other types implement trait `Default`:
88
[T; 0]

tests/ui/generic-const-items/unsatisfied-bounds.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ LL | Infallible: From<T>;
2727
| ^^^^^^^ required by this bound in `K`
2828

2929
error[E0277]: the trait bound `Vec<u8>: Copy` is not satisfied
30-
--> $DIR/unsatisfied-bounds.rs:32:13
30+
--> $DIR/unsatisfied-bounds.rs:32:26
3131
|
3232
LL | let _ = <() as Trait<Vec<u8>>>::A;
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
33+
| ^^^^^^^ the trait `Copy` is not implemented for `Vec<u8>`
3434
|
3535
note: required by a bound in `Trait::A`
3636
--> $DIR/unsatisfied-bounds.rs:17:12

tests/ui/issues/issue-39970.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0271]: type mismatch resolving `<() as Array<'a>>::Element == ()`
2-
--> $DIR/issue-39970.rs:19:5
2+
--> $DIR/issue-39970.rs:19:6
33
|
44
LL | <() as Visit>::visit();
5-
| ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<() as Array<'a>>::Element == ()`
5+
| ^^ type mismatch resolving `<() as Array<'a>>::Element == ()`
66
|
77
note: expected this to be `()`
88
--> $DIR/issue-39970.rs:10:20

tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-fail.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
2-
--> $DIR/call-const-trait-method-fail.rs:25:7
2+
--> $DIR/call-const-trait-method-fail.rs:25:5
33
|
44
LL | a.plus(b)
5-
| ^^^^ the trait `Plus` is not implemented for `u32`
5+
| ^ the trait `Plus` is not implemented for `u32`
66
|
77
= help: the trait `Plus` is implemented for `u32`
88

tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause-const.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied
22
--> $DIR/trait-where-clause-const.rs:21:5
33
|
44
LL | T::b();
5-
| ^^^^ the trait `Bar` is not implemented for `T`
5+
| ^ the trait `Bar` is not implemented for `T`
66
|
77
note: required by a bound in `Foo::b`
88
--> $DIR/trait-where-clause-const.rs:15:24

tests/ui/rfcs/rfc-2632-const-trait-impl/trait-where-clause.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
22
--> $DIR/trait-where-clause.rs:14:5
33
|
44
LL | T::b();
5-
| ^^^^ the trait `Bar` is not implemented for `T`
5+
| ^ the trait `Bar` is not implemented for `T`
66
|
77
note: required by a bound in `Foo::b`
88
--> $DIR/trait-where-clause.rs:8:24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Regression test for one part of issue #105306.
2+
3+
fn main() {
4+
let _ = Option::<[u8]>::None;
5+
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2+
--> $DIR/enum-unit-variant-trait-bound.rs:4:22
3+
|
4+
LL | let _ = Option::<[u8]>::None;
5+
| ^^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `[u8]`
8+
note: required by a bound in `None`
9+
--> $SRC_DIR/core/src/option.rs:LL:COL
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

tests/ui/traits/suggest-where-clause.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,32 @@ LL + fn check<T: Iterator, U>() {
3838
|
3939

4040
error[E0277]: the trait bound `u64: From<T>` is not satisfied
41-
--> $DIR/suggest-where-clause.rs:15:5
41+
--> $DIR/suggest-where-clause.rs:15:18
4242
|
4343
LL | <u64 as From<T>>::from;
44-
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
44+
| ^ the trait `From<T>` is not implemented for `u64`
4545
|
4646
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
4747
|
4848
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
4949
| ++++++++++++++++++
5050

5151
error[E0277]: the trait bound `u64: From<<T as Iterator>::Item>` is not satisfied
52-
--> $DIR/suggest-where-clause.rs:18:5
52+
--> $DIR/suggest-where-clause.rs:18:18
5353
|
5454
LL | <u64 as From<<T as Iterator>::Item>>::from;
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
55+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
5656
|
5757
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
5858
|
5959
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
6060
| ++++++++++++++++++++++++++++++++++++++
6161

6262
error[E0277]: the trait bound `Misc<_>: From<T>` is not satisfied
63-
--> $DIR/suggest-where-clause.rs:23:5
63+
--> $DIR/suggest-where-clause.rs:23:22
6464
|
6565
LL | <Misc<_> as From<T>>::from;
66-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `Misc<_>`
66+
| ^ the trait `From<T>` is not implemented for `Misc<_>`
6767

6868
error[E0277]: the size for values of type `[T]` cannot be known at compilation time
6969
--> $DIR/suggest-where-clause.rs:28:20

tests/ui/unevaluated_fixed_size_array_len.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
2-
--> $DIR/unevaluated_fixed_size_array_len.rs:12:5
2+
--> $DIR/unevaluated_fixed_size_array_len.rs:12:6
33
|
44
LL | <[(); 0] as Foo>::foo()
5-
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
5+
| ^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
66
|
77
= help: the trait `Foo` is implemented for `[(); 1]`
88

0 commit comments

Comments
 (0)