Mention only assoc types changes
This commit is contained in:
parent
49d5bef586
commit
64bc975d27
4 changed files with 92 additions and 52 deletions
|
@ -2865,11 +2865,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = expr.span;
|
let mut primary_spans = vec![];
|
||||||
let mut multi_span: MultiSpan = match expr.kind {
|
let mut span_labels = vec![];
|
||||||
hir::ExprKind::MethodCall(_, _, _, span) => span.into(),
|
|
||||||
_ => span.into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME: visit the ty to see if there's any closure involved, and if there is,
|
// FIXME: visit the ty to see if there's any closure involved, and if there is,
|
||||||
// check whether its evaluated return type is the same as the one corresponding
|
// check whether its evaluated return type is the same as the one corresponding
|
||||||
|
@ -2897,12 +2894,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let point_at_chain = |expr: &hir::Expr<'_>| {
|
let point_at_chain = |expr: &hir::Expr<'_>| {
|
||||||
|
let mut assocs = vec![];
|
||||||
|
// We still want to point at the different methods even if there hasn't
|
||||||
|
// been a change of assoc type.
|
||||||
|
let mut call_spans = vec![];
|
||||||
let mut expr = expr;
|
let mut expr = expr;
|
||||||
let mut prev_ty = self.resolve_vars_if_possible(
|
let mut prev_ty = self.resolve_vars_if_possible(
|
||||||
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
||||||
);
|
);
|
||||||
let outer_ty = prev_ty;
|
|
||||||
let mut assoc_seen = 0;
|
|
||||||
while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) =
|
while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) =
|
||||||
expr.kind
|
expr.kind
|
||||||
{
|
{
|
||||||
|
@ -2910,12 +2909,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
||||||
// ^^^^^^ ^^^^^^^^^^^
|
// ^^^^^^ ^^^^^^^^^^^
|
||||||
expr = rcvr_expr;
|
expr = rcvr_expr;
|
||||||
|
let mut assocs_in_this_method = Vec::with_capacity(type_diffs.len());
|
||||||
|
call_spans.push(span);
|
||||||
|
|
||||||
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
|
let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
|
||||||
for diff in &type_diffs {
|
for diff in &type_diffs {
|
||||||
let Sorts(expected_found) = diff else { continue; };
|
let Sorts(expected_found) = diff else { continue; };
|
||||||
let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
|
let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
|
||||||
assoc_seen += 1;
|
|
||||||
|
|
||||||
let origin = TypeVariableOrigin {
|
let origin = TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::TypeInference,
|
kind: TypeVariableOriginKind::TypeInference,
|
||||||
|
@ -2963,23 +2963,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
if ocx.select_where_possible().is_empty() {
|
if ocx.select_where_possible().is_empty() {
|
||||||
// `ty_var` now holds the type that `Item` is for `ExprTy`.
|
// `ty_var` now holds the type that `Item` is for `ExprTy`.
|
||||||
let assoc = self.tcx.def_path_str(proj.item_def_id);
|
let assoc = self.tcx.def_path_str(proj.item_def_id);
|
||||||
multi_span.push_span_label(
|
let ty_var = self.resolve_vars_if_possible(ty_var);
|
||||||
span,
|
assocs_in_this_method.push(Some((span, (assoc, ty_var))));
|
||||||
&format!(
|
|
||||||
"associated type `{assoc}` is `{}` here",
|
|
||||||
self.resolve_vars_if_possible(ty_var),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// `<ExprTy as Iterator>` didn't select, so likely we've
|
// `<ExprTy as Iterator>` didn't select, so likely we've
|
||||||
// reached the end of the iterator chain, like the originating
|
// reached the end of the iterator chain, like the originating
|
||||||
// `Vec<_>`.
|
// `Vec<_>`.
|
||||||
multi_span.push_span_label(
|
// Keep the space consistent for later zipping.
|
||||||
span,
|
assocs_in_this_method.push(None);
|
||||||
format!("this call has type `{prev_ty}`"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assocs.push(assocs_in_this_method);
|
||||||
prev_ty = self.resolve_vars_if_possible(
|
prev_ty = self.resolve_vars_if_possible(
|
||||||
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
|
||||||
);
|
);
|
||||||
|
@ -2992,17 +2986,65 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
// Point at the root expression
|
// Point at the root expression
|
||||||
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
// vec![1, 2, 3].iter().map(mapper).sum<i32>()
|
||||||
// ^^^^^^^^^^^^^
|
// ^^^^^^^^^^^^^
|
||||||
multi_span.push_span_label(
|
span_labels
|
||||||
expr.span,
|
.push((expr.span, format!("this expression has type `{ty}`")));
|
||||||
format!("this expression has type `{ty}`"),
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
if assoc_seen > 0 {
|
// Only show this if it is not a "trivial" expression (not a method
|
||||||
// Only show this if it is not a "trivial" expression (not a method
|
// chain) and there are associated types to talk about.
|
||||||
// chain) and there are associated types to talk about.
|
let mut assocs = assocs.into_iter().peekable();
|
||||||
|
while let Some(assocs_in_method) = assocs.next() {
|
||||||
|
let Some(prev_assoc_in_method) = assocs.peek() else {
|
||||||
|
for entry in assocs_in_method {
|
||||||
|
let Some((span, (assoc, ty))) = entry else { continue; };
|
||||||
|
primary_spans.push(span);
|
||||||
|
span_labels.push((
|
||||||
|
span,
|
||||||
|
format!("associated type `{assoc}` is `{ty}` here"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
for (entry, prev_entry) in
|
||||||
|
assocs_in_method.into_iter().zip(prev_assoc_in_method.into_iter())
|
||||||
|
{
|
||||||
|
match (entry, prev_entry) {
|
||||||
|
(Some((span, (assoc, ty))), Some((_, (_, prev_ty)))) => {
|
||||||
|
if ty != *prev_ty {
|
||||||
|
primary_spans.push(span);
|
||||||
|
span_labels.push((
|
||||||
|
span,
|
||||||
|
format!("associated type `{assoc}` changed to `{ty}` here"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Some((span, (assoc, ty))), None) => {
|
||||||
|
span_labels.push((
|
||||||
|
span,
|
||||||
|
format!("associated type `{assoc}` is `{ty}` here"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
(None, Some(_)) | (None, None) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for span in call_spans {
|
||||||
|
if span_labels.iter().find(|(s, _)| *s == span).is_none() {
|
||||||
|
// Ensure we are showing the entire chain, even if the assoc types
|
||||||
|
// haven't changed.
|
||||||
|
span_labels.push((span, String::new()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !primary_spans.is_empty() {
|
||||||
|
let mut multi_span: MultiSpan = primary_spans.into();
|
||||||
|
for (span, label) in span_labels {
|
||||||
|
multi_span.push_span_label(span, label);
|
||||||
|
}
|
||||||
err.span_note(
|
err.span_note(
|
||||||
multi_span,
|
multi_span,
|
||||||
format!("the expression is of type `{outer_ty}`"),
|
format!(
|
||||||
|
"the method call chain might not have had the expected \
|
||||||
|
associated types",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,11 +22,11 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece
|
||||||
|
|
|
|
||||||
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
|
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
|
||||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||||
note: the expression is of type `Map<std::slice::Iter<'_, (_, _, _)>, [closure@$DIR/issue-34334.rs:5:47: 5:82]>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/issue-34334.rs:5:43
|
--> $DIR/issue-34334.rs:5:36
|
||||||
|
|
|
|
||||||
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
|
||||||
| -- ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `()` here
|
| -- ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `()` here
|
||||||
| | |
|
| | |
|
||||||
| | associated type `std::iter::Iterator::Item` is `&(_, _, _)` here
|
| | associated type `std::iter::Iterator::Item` is `&(_, _, _)` here
|
||||||
| this expression has type `Vec<(_, _, _)>`
|
| this expression has type `Vec<(_, _, _)>`
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
|
|
|
|
||||||
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
||||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||||
note: the expression is of type `std::slice::Iter<'_, f64>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
|
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
|
||||||
|
|
|
|
||||||
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
|
@ -31,7 +31,7 @@ LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
|
|
|
|
||||||
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
|
||||||
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||||
note: the expression is of type `std::slice::Iter<'_, f64>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
|
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
|
||||||
|
|
|
|
||||||
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
|
|
|
@ -9,20 +9,18 @@ LL | println!("{}", scores.sum::<i32>());
|
||||||
= help: the following other types implement trait `Sum<A>`:
|
= help: the following other types implement trait `Sum<A>`:
|
||||||
<i32 as Sum<&'a i32>>
|
<i32 as Sum<&'a i32>>
|
||||||
<i32 as Sum>
|
<i32 as Sum>
|
||||||
note: the expression is of type `Map<std::slice::Iter<'_, ({integer}, {integer})>, [closure@$DIR/invalid-iterator-chain.rs:4:14: 4:22]>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/invalid-iterator-chain.rs:7:20
|
--> $DIR/invalid-iterator-chain.rs:3:10
|
||||||
|
|
|
|
||||||
LL | let scores = vec![(0, 0)]
|
LL | let scores = vec![(0, 0)]
|
||||||
| ------------ this expression has type `Vec<({integer}, {integer})>`
|
| ------------ this expression has type `Vec<({integer}, {integer})>`
|
||||||
LL | .iter()
|
LL | .iter()
|
||||||
| ------ associated type `std::iter::Iterator::Item` is `&({integer}, {integer})` here
|
| ^^^^^^ associated type `std::iter::Iterator::Item` is `&({integer}, {integer})` here
|
||||||
LL | .map(|(a, b)| {
|
LL | .map(|(a, b)| {
|
||||||
| __________-
|
| __________^
|
||||||
LL | | a + b;
|
LL | | a + b;
|
||||||
LL | | });
|
LL | | });
|
||||||
| |__________- associated type `std::iter::Iterator::Item` is `()` here
|
| |__________^ associated type `std::iter::Iterator::Item` changed to `()` here
|
||||||
LL | println!("{}", scores.sum::<i32>());
|
|
||||||
| ^^^^^^
|
|
||||||
note: required by a bound in `std::iter::Iterator::sum`
|
note: required by a bound in `std::iter::Iterator::sum`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
@ -46,25 +44,25 @@ LL | .sum::<i32>(),
|
||||||
= help: the following other types implement trait `Sum<A>`:
|
= help: the following other types implement trait `Sum<A>`:
|
||||||
<i32 as Sum<&'a i32>>
|
<i32 as Sum<&'a i32>>
|
||||||
<i32 as Sum>
|
<i32 as Sum>
|
||||||
note: the expression is of type `Map<Map<Filter<Map<Map<Map<std::slice::Iter<'_, {integer}>, [closure@$DIR/invalid-iterator-chain.rs:12:18: 12:21]>, [closure@$DIR/invalid-iterator-chain.rs:13:18: 13:21]>, [closure@$DIR/invalid-iterator-chain.rs:14:18: 14:21]>, [closure@$DIR/invalid-iterator-chain.rs:15:21: 15:24]>, [closure@$DIR/invalid-iterator-chain.rs:16:18: 16:21]>, [closure@$DIR/invalid-iterator-chain.rs:17:18: 17:21]>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/invalid-iterator-chain.rs:17:14
|
--> $DIR/invalid-iterator-chain.rs:11:14
|
||||||
|
|
|
|
||||||
LL | vec![0, 1]
|
LL | vec![0, 1]
|
||||||
| ---------- this expression has type `Vec<{integer}>`
|
| ---------- this expression has type `Vec<{integer}>`
|
||||||
LL | .iter()
|
LL | .iter()
|
||||||
| ------ associated type `std::iter::Iterator::Item` is `&{integer}` here
|
| ^^^^^^ associated type `std::iter::Iterator::Item` is `&{integer}` here
|
||||||
LL | .map(|x| x * 2)
|
LL | .map(|x| x * 2)
|
||||||
| -------------- associated type `std::iter::Iterator::Item` is `{integer}` here
|
| ^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `{integer}` here
|
||||||
LL | .map(|x| x as f64)
|
LL | .map(|x| x as f64)
|
||||||
| ----------------- associated type `std::iter::Iterator::Item` is `f64` here
|
| ^^^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `f64` here
|
||||||
LL | .map(|x| x as i64)
|
LL | .map(|x| x as i64)
|
||||||
| ----------------- associated type `std::iter::Iterator::Item` is `i64` here
|
| ^^^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `i64` here
|
||||||
LL | .filter(|x| *x > 0)
|
LL | .filter(|x| *x > 0)
|
||||||
| ------------------ associated type `std::iter::Iterator::Item` is `i64` here
|
| ------------------
|
||||||
LL | .map(|x| { x + 1 })
|
LL | .map(|x| { x + 1 })
|
||||||
| ------------------ associated type `std::iter::Iterator::Item` is `i64` here
|
| ------------------
|
||||||
LL | .map(|x| { x; })
|
LL | .map(|x| { x; })
|
||||||
| ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `()` here
|
| ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `()` here
|
||||||
note: required by a bound in `std::iter::Iterator::sum`
|
note: required by a bound in `std::iter::Iterator::sum`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
@ -82,11 +80,11 @@ LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
||||||
= help: the following other types implement trait `Sum<A>`:
|
= help: the following other types implement trait `Sum<A>`:
|
||||||
<i32 as Sum<&'a i32>>
|
<i32 as Sum<&'a i32>>
|
||||||
<i32 as Sum>
|
<i32 as Sum>
|
||||||
note: the expression is of type `Map<std::slice::Iter<'_, {integer}>, [closure@$DIR/invalid-iterator-chain.rs:20:42: 20:45]>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/invalid-iterator-chain.rs:20:38
|
--> $DIR/invalid-iterator-chain.rs:20:31
|
||||||
|
|
|
|
||||||
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
|
||||||
| ---------- ------ ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `()` here
|
| ---------- ^^^^^^ ^^^^^^^^^^^^^^^ associated type `std::iter::Iterator::Item` changed to `()` here
|
||||||
| | |
|
| | |
|
||||||
| | associated type `std::iter::Iterator::Item` is `&{integer}` here
|
| | associated type `std::iter::Iterator::Item` is `&{integer}` here
|
||||||
| this expression has type `Vec<{integer}>`
|
| this expression has type `Vec<{integer}>`
|
||||||
|
@ -107,7 +105,7 @@ LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
||||||
= help: the following other types implement trait `Sum<A>`:
|
= help: the following other types implement trait `Sum<A>`:
|
||||||
<i32 as Sum<&'a i32>>
|
<i32 as Sum<&'a i32>>
|
||||||
<i32 as Sum>
|
<i32 as Sum>
|
||||||
note: the expression is of type `std::slice::Iter<'_, ()>`
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/invalid-iterator-chain.rs:21:33
|
--> $DIR/invalid-iterator-chain.rs:21:33
|
||||||
|
|
|
|
||||||
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue