Skip to content

Commit 0554528

Browse files
Walk through full path in point_at_path_if_possible
1 parent 296c7a6 commit 0554528

File tree

6 files changed

+57
-34
lines changed

6 files changed

+57
-34
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+28-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, ..) => {
@@ -168,10 +167,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
168167
}
169168
}
170169
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)
170+
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
171+
self.typeck_results.borrow().qpath_res(qpath, hir_id)
175172
{
176173
for param in
177174
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
@@ -193,10 +190,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
193190
}
194191
}
195192
}
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)
193+
194+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
195+
.into_iter()
196+
.flatten()
198197
{
199-
return true;
198+
if self.point_at_path_if_possible(error, def_id, param, qpath) {
199+
return true;
200+
}
200201
}
201202
}
202203
_ => {}
@@ -214,10 +215,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
214215
) -> bool {
215216
match qpath {
216217
hir::QPath::Resolved(_, path) => {
217-
if let Some(segment) = path.segments.last()
218-
&& self.point_at_generic_if_possible(error, def_id, param, segment)
219-
{
220-
return true;
218+
for segment in path.segments.iter().rev() {
219+
if let Res::Def(kind, def_id) = segment.res
220+
&& !matches!(kind, DefKind::Mod | DefKind::ForeignMod)
221+
&& self.point_at_generic_if_possible(error, def_id, param, segment)
222+
{
223+
return true;
224+
}
221225
}
222226
}
223227
hir::QPath::TypeRelative(_, segment) => {
@@ -618,14 +622,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
618622
};
619623

620624
let variant_def_id = match expr_struct_def_kind {
621-
hir::def::DefKind::Struct => {
625+
DefKind::Struct => {
622626
if in_ty_adt.did() != expr_struct_def_id {
623627
// FIXME: Deal with type aliases?
624628
return Err(expr);
625629
}
626630
expr_struct_def_id
627631
}
628-
hir::def::DefKind::Variant => {
632+
DefKind::Variant => {
629633
// If this is a variant, its parent is the type definition.
630634
if in_ty_adt.did() != self.tcx.parent(expr_struct_def_id) {
631635
// FIXME: Deal with type aliases?
@@ -727,14 +731,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
727731
};
728732

729733
let variant_def_id = match expr_struct_def_kind {
730-
hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
734+
DefKind::Ctor(hir::def::CtorOf::Struct, hir::def::CtorKind::Fn) => {
731735
if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
732736
// FIXME: Deal with type aliases?
733737
return Err(expr);
734738
}
735739
self.tcx.parent(expr_ctor_def_id)
736740
}
737-
hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
741+
DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
738742
// For a typical enum like
739743
// `enum Blah<T> { Variant(T) }`
740744
// we get the following resolutions:

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/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
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

0 commit comments

Comments
 (0)