Skip to content

Commit e877e2a

Browse files
committed
Auto merge of rust-lang#115219 - estebank:issue-105306, r=compiler-errors
Point at type parameter that introduced unmet bound instead of full HIR node ``` error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> $DIR/issue-87199.rs:18:15 | LL | ref_arg::<[i32]>(&[5]); | ^^^^^ doesn't have a size known at compile-time ``` instead of ``` error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> $DIR/issue-87199.rs:18:22 | LL | ref_arg::<[i32]>(&[5]); | ---------------- ^^^^ doesn't have a size known at compile-time | | | required by a bound introduced by this call ``` ------ ``` error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/own-bound-span.rs:14:24 | LL | let _: <S as D>::P<String>; | ^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `D::P` --> $DIR/own-bound-span.rs:4:15 | LL | type P<T: Copy>; | ^^^^ required by this bound in `D::P` ``` instead of ``` error[E0277]: the trait bound `String: Copy` is not satisfied --> $DIR/own-bound-span.rs:14:12 | LL | let _: <S as D>::P<String>; | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | note: required by a bound in `D::P` --> $DIR/own-bound-span.rs:4:15 | LL | type P<T: Copy>; | ^^^^ required by this bound in `D::P` ``` Fix rust-lang#105306.
2 parents 69e97df + 7411e25 commit e877e2a

File tree

46 files changed

+263
-203
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+263
-203
lines changed

Diff for: compiler/rustc_hir_typeck/src/closure.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
231231
let inferred_sig = self.normalize(
232232
span,
233233
self.deduce_sig_from_projection(
234-
Some(span),
234+
Some(span),
235235
bound_predicate.rebind(proj_predicate),
236236
),
237237
);

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+87-46
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2020
else {
2121
return false;
2222
};
23-
let hir = self.tcx.hir();
24-
let hir::Node::Expr(expr) = hir.get(hir_id) else {
25-
return false;
26-
};
2723

2824
let Some(unsubstituted_pred) = self
2925
.tcx
@@ -47,6 +43,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4743
_ => return false,
4844
};
4945

46+
let direct_param = if let ty::ClauseKind::Trait(pred) = unsubstituted_pred.kind().skip_binder()
47+
&& let ty = pred.trait_ref.self_ty()
48+
&& let ty::Param(_param) = ty.kind()
49+
&& let Some(arg) = predicate_args.get(0)
50+
&& let ty::GenericArgKind::Type(arg_ty) = arg.unpack()
51+
&& arg_ty == ty
52+
{
53+
Some(*arg)
54+
} else {
55+
None
56+
};
5057
let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| {
5158
predicate_args.iter().find_map(|arg| {
5259
arg.walk().find_map(|arg| {
@@ -96,54 +103,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
96103
self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
97104
}
98105

99-
if self.closure_span_overlaps_error(error, expr.span) {
100-
return false;
101-
}
106+
let hir = self.tcx.hir();
107+
let (expr, qpath) = match hir.get(hir_id) {
108+
hir::Node::Expr(expr) => {
109+
if self.closure_span_overlaps_error(error, expr.span) {
110+
return false;
111+
}
112+
let qpath =
113+
if let hir::ExprKind::Path(qpath) = expr.kind { Some(qpath) } else { None };
102114

103-
match &expr.kind {
104-
hir::ExprKind::Path(qpath) => {
105-
if let hir::Node::Expr(hir::Expr {
106-
kind: hir::ExprKind::Call(callee, args),
107-
hir_id: call_hir_id,
108-
span: call_span,
109-
..
110-
}) = hir.get_parent(expr.hir_id)
111-
&& callee.hir_id == expr.hir_id
112-
{
113-
if self.closure_span_overlaps_error(error, *call_span) {
114-
return false;
115-
}
115+
(Some(*expr), qpath)
116+
}
117+
hir::Node::Ty(hir::Ty { kind: hir::TyKind::Path(qpath), .. }) => (None, Some(*qpath)),
118+
_ => return false,
119+
};
116120

117-
for param in
118-
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
119-
.into_iter()
120-
.flatten()
121-
{
122-
if self.blame_specific_arg_if_possible(
123-
error,
124-
def_id,
125-
param,
126-
*call_hir_id,
127-
callee.span,
128-
None,
129-
args,
130-
)
131-
{
132-
return true;
133-
}
134-
}
121+
if let Some(qpath) = qpath {
122+
if let Some(param) = direct_param {
123+
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
124+
return true;
125+
}
126+
}
127+
if let hir::Node::Expr(hir::Expr {
128+
kind: hir::ExprKind::Call(callee, args),
129+
hir_id: call_hir_id,
130+
span: call_span,
131+
..
132+
}) = hir.get_parent(hir_id)
133+
&& callee.hir_id == hir_id
134+
{
135+
if self.closure_span_overlaps_error(error, *call_span) {
136+
return false;
135137
}
136138

137-
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
139+
for param in
140+
[param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
138141
.into_iter()
139142
.flatten()
140143
{
141-
if self.point_at_path_if_possible(error, def_id, param, qpath) {
144+
if self.blame_specific_arg_if_possible(
145+
error,
146+
def_id,
147+
param,
148+
*call_hir_id,
149+
callee.span,
150+
None,
151+
args,
152+
)
153+
{
142154
return true;
143155
}
144156
}
145157
}
146-
hir::ExprKind::MethodCall(segment, receiver, args, ..) => {
158+
159+
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
160+
.into_iter()
161+
.flatten()
162+
{
163+
if self.point_at_path_if_possible(error, def_id, param, &qpath) {
164+
return true;
165+
}
166+
}
167+
}
168+
169+
match expr.map(|e| e.kind) {
170+
Some(hir::ExprKind::MethodCall(segment, receiver, args, ..)) => {
171+
if let Some(param) = direct_param
172+
&& self.point_at_generic_if_possible(error, def_id, param, segment)
173+
{
174+
error.obligation.cause.map_code(|parent_code| {
175+
ObligationCauseCode::FunctionArgumentObligation {
176+
arg_hir_id: receiver.hir_id,
177+
call_hir_id: hir_id,
178+
parent_code,
179+
}
180+
});
181+
return true;
182+
}
147183
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
148184
.into_iter()
149185
.flatten()
@@ -175,7 +211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
175211
return true;
176212
}
177213
}
178-
hir::ExprKind::Struct(qpath, fields, ..) => {
214+
Some(hir::ExprKind::Struct(qpath, fields, ..)) => {
179215
if let Res::Def(DefKind::Struct | DefKind::Variant, variant_def_id) =
180216
self.typeck_results.borrow().qpath_res(qpath, hir_id)
181217
{
@@ -200,9 +236,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
200236
}
201237
}
202238

203-
for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
204-
.into_iter()
205-
.flatten()
239+
for param in [
240+
direct_param,
241+
param_to_point_at,
242+
fallback_param_to_point_at,
243+
self_param_to_point_at,
244+
]
245+
.into_iter()
246+
.flatten()
206247
{
207248
if self.point_at_path_if_possible(error, def_id, param, qpath) {
208249
return true;
@@ -434,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
434475
}
435476

436477
/**
437-
* Recursively searches for the most-specific blamable expression.
478+
* Recursively searches for the most-specific blameable expression.
438479
* For example, if you have a chain of constraints like:
439480
* - want `Vec<i32>: Copy`
440481
* - because `Option<Vec<i32>>: Copy` needs `Vec<i32>: Copy` because `impl <T: Copy> Copy for Option<T>`

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,18 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
317317

318318
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span) {
319319
// FIXME: normalization and escaping regions
320-
let ty = if !ty.has_escaping_bound_vars() { self.normalize(span, ty) } else { ty };
320+
let ty = if !ty.has_escaping_bound_vars() {
321+
if let ty::Alias(
322+
ty::AliasKind::Projection | ty::AliasKind::Weak,
323+
ty::AliasTy { args, def_id, .. },
324+
) = ty.kind()
325+
{
326+
self.add_required_obligations_for_hir(span, *def_id, args, hir_id);
327+
}
328+
self.normalize(span, ty)
329+
} else {
330+
ty
331+
};
321332
self.write_ty(hir_id, ty)
322333
}
323334

Diff for: tests/ui/argument-suggestions/issue-100154.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ LL | fn foo(i: impl std::fmt::Display) {}
1414
= note: `impl Trait` cannot be explicitly specified as a generic argument
1515

1616
error[E0277]: `()` doesn't implement `std::fmt::Display`
17-
--> $DIR/issue-100154.rs:4:15
17+
--> $DIR/issue-100154.rs:4:11
1818
|
1919
LL | foo::<()>(());
20-
| --------- ^^ `()` cannot be formatted with the default formatter
21-
| |
22-
| required by a bound introduced by this call
20+
| ^^ `()` cannot be formatted with the default formatter
2321
|
2422
= help: the trait `std::fmt::Display` is not implemented for `()`
2523
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead

Diff for: tests/ui/associated-types/associated-types-invalid-trait-ref-issue-18865.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `T: Foo<usize>` is not satisfied
2-
--> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:12
2+
--> $DIR/associated-types-invalid-trait-ref-issue-18865.rs:10:13
33
|
44
LL | let u: <T as Foo<usize>>::Bar = t.get_bar();
5-
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo<usize>` is not implemented for `T`
5+
| ^ the trait `Foo<usize>` is not implemented for `T`
66
|
77
help: consider further restricting this bound
88
|

Diff for: 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:16
2+
--> $DIR/exhaustive-value.rs:262:6
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>>

Diff for: tests/ui/function-pointer/unsized-ret.stderr

+4-8
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`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
trait Trait {
2+
type P<T: Copy, U: Copy>;
3+
}
4+
impl Trait for () {
5+
type P<T: Copy, U: Copy> = ();
6+
}
7+
fn main() {
8+
let _: <() as Trait>::P<String, String>;
9+
//~^ ERROR the trait bound `String: Copy` is not satisfied
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0277]: the trait bound `String: Copy` is not satisfied
2+
--> $DIR/multiple-type-params-with-unmet-bounds.rs:8:29
3+
|
4+
LL | let _: <() as Trait>::P<String, String>;
5+
| ^^^^^^ the trait `Copy` is not implemented for `String`
6+
|
7+
note: required by a bound in `Trait::P`
8+
--> $DIR/multiple-type-params-with-unmet-bounds.rs:2:15
9+
|
10+
LL | type P<T: Copy, U: Copy>;
11+
| ^^^^ required by this bound in `Trait::P`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0277`.

Diff for: tests/ui/generic-associated-types/own-bound-span.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the trait bound `String: Copy` is not satisfied
2-
--> $DIR/own-bound-span.rs:14:12
2+
--> $DIR/own-bound-span.rs:14:24
33
|
44
LL | let _: <S as D>::P<String>;
5-
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
5+
| ^^^^^^ the trait `Copy` is not implemented for `String`
66
|
77
note: required by a bound in `D::P`
88
--> $DIR/own-bound-span.rs:4:15

Diff for: tests/ui/inference/issue-72690.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0283]: type annotations needed
22
--> $DIR/issue-72690.rs:7:5
33
|
44
LL | String::from("x".as_ref());
5-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
5+
| ^^^^^^ cannot infer type for reference `&_`
66
|
77
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
88
- impl<> From<&String> for String;
@@ -71,7 +71,7 @@ error[E0283]: type annotations needed
7171
--> $DIR/issue-72690.rs:21:5
7272
|
7373
LL | String::from("x".as_ref());
74-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
74+
| ^^^^^^ cannot infer type for reference `&_`
7575
|
7676
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
7777
- impl<> From<&String> for String;
@@ -97,7 +97,7 @@ error[E0283]: type annotations needed
9797
--> $DIR/issue-72690.rs:28:5
9898
|
9999
LL | String::from("x".as_ref());
100-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
100+
| ^^^^^^ cannot infer type for reference `&_`
101101
|
102102
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
103103
- impl<> From<&String> for String;
@@ -123,7 +123,7 @@ error[E0283]: type annotations needed
123123
--> $DIR/issue-72690.rs:37:5
124124
|
125125
LL | String::from("x".as_ref());
126-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
126+
| ^^^^^^ cannot infer type for reference `&_`
127127
|
128128
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
129129
- impl<> From<&String> for String;
@@ -149,7 +149,7 @@ error[E0283]: type annotations needed
149149
--> $DIR/issue-72690.rs:46:5
150150
|
151151
LL | String::from("x".as_ref());
152-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
152+
| ^^^^^^ cannot infer type for reference `&_`
153153
|
154154
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
155155
- impl<> From<&String> for String;
@@ -175,7 +175,7 @@ error[E0283]: type annotations needed
175175
--> $DIR/issue-72690.rs:53:5
176176
|
177177
LL | String::from("x".as_ref());
178-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
178+
| ^^^^^^ cannot infer type for reference `&_`
179179
|
180180
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
181181
- impl<> From<&String> for String;
@@ -201,7 +201,7 @@ error[E0283]: type annotations needed
201201
--> $DIR/issue-72690.rs:62:5
202202
|
203203
LL | String::from("x".as_ref());
204-
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
204+
| ^^^^^^ cannot infer type for reference `&_`
205205
|
206206
= note: multiple `impl`s satisfying `String: From<&_>` found in the `alloc` crate:
207207
- impl<> From<&String> for String;

Diff for: tests/ui/issues/issue-29147.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0283]: type annotations needed
2-
--> $DIR/issue-29147.rs:22:13
2+
--> $DIR/issue-29147.rs:22:14
33
|
44
LL | let _ = <S5<_>>::xxx;
5-
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
5+
| ^^^^^ cannot infer type for struct `S5<_>`
66
|
77
note: multiple `impl`s satisfying `S5<_>: Foo` found
88
--> $DIR/issue-29147.rs:18:1

0 commit comments

Comments
 (0)