Account for method call chains split across multiple bindings
This commit is contained in:
parent
64bc975d27
commit
71db025cfa
5 changed files with 69 additions and 11 deletions
|
@ -2977,6 +2977,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
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()),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
|
||||||
|
&& let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
|
||||||
|
&& let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
|
||||||
|
&& let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
|
||||||
|
&& let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
|
||||||
|
&& let Some(binding_expr) = local.init
|
||||||
|
{
|
||||||
|
// We've reached the root of the method call chain and it is a
|
||||||
|
// binding. Get the binding creation and try to continue the chain.
|
||||||
|
expr = binding_expr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want the type before deref coercions, otherwise we talk about `&[_]`
|
// We want the type before deref coercions, otherwise we talk about `&[_]`
|
||||||
|
|
|
@ -25,11 +25,13 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece
|
||||||
note: the method call chain might not have had the expected associated types
|
note: the method call chain might not have had the expected associated types
|
||||||
--> $DIR/issue-34334.rs:5:36
|
--> $DIR/issue-34334.rs:5:36
|
||||||
|
|
|
|
||||||
|
LL | let sr: Vec<(u32, _, _) = vec![];
|
||||||
|
| ------ this expression has type `Vec<(_, _, _)>`
|
||||||
|
...
|
||||||
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` changed to `()` 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<(_, _, _)>`
|
|
||||||
note: required by a bound in `collect`
|
note: required by a bound in `collect`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
|
|
@ -11,10 +11,10 @@ LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
note: the method call chain might not have had the expected associated types
|
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 x1: &[f64] = &v;
|
||||||
|
| -- this expression has type `&Vec<f64>`
|
||||||
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
| -- ^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `&f64` here
|
| ^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `&f64` here
|
||||||
| |
|
|
||||||
| this expression has type `&[f64]`
|
|
||||||
note: required by a bound in `collect`
|
note: required by a bound in `collect`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
@ -34,10 +34,11 @@ LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
note: the method call chain might not have had the expected associated types
|
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 x1: &[f64] = &v;
|
||||||
|
| -- this expression has type `&Vec<f64>`
|
||||||
|
...
|
||||||
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
| -- ^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `&f64` here
|
| ^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `&f64` here
|
||||||
| |
|
|
||||||
| this expression has type `&[f64]`
|
|
||||||
note: required by a bound in `collect`
|
note: required by a bound in `collect`
|
||||||
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
|
||||||
|
|
|
@ -19,4 +19,13 @@ fn main() {
|
||||||
);
|
);
|
||||||
println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
|
println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
|
||||||
println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
|
println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
|
||||||
|
let a = vec![0];
|
||||||
|
let b = a.into_iter();
|
||||||
|
let c = b.map(|x| x + 1);
|
||||||
|
let d = c.filter(|x| *x > 10 );
|
||||||
|
let e = d.map(|x| {
|
||||||
|
x + 1;
|
||||||
|
});
|
||||||
|
let f = e.filter(|_| false);
|
||||||
|
let g: Vec<i32> = f.collect(); //~ ERROR E0277
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,40 @@ note: required by a bound in `std::iter::Iterator::sum`
|
||||||
LL | S: Sum<Self::Item>,
|
LL | S: Sum<Self::Item>,
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
|
| ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
|
||||||
|
--> $DIR/invalid-iterator-chain.rs:30:23
|
||||||
|
|
|
||||||
|
LL | let g: Vec<i32> = f.collect();
|
||||||
|
| ^ ------- required by a bound introduced by this call
|
||||||
|
| |
|
||||||
|
| value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
|
||||||
|
|
|
||||||
|
= help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
|
||||||
|
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
|
||||||
|
note: the method call chain might not have had the expected associated types
|
||||||
|
--> $DIR/invalid-iterator-chain.rs:23:15
|
||||||
|
|
|
||||||
|
LL | let a = vec![0];
|
||||||
|
| ------- this expression has type `Vec<{integer}>`
|
||||||
|
LL | let b = a.into_iter();
|
||||||
|
| ^^^^^^^^^^^ associated type `std::iter::Iterator::Item` is `{integer}` here
|
||||||
|
LL | let c = b.map(|x| x + 1);
|
||||||
|
| --------------
|
||||||
|
LL | let d = c.filter(|x| *x > 10 );
|
||||||
|
| --------------------
|
||||||
|
LL | let e = d.map(|x| {
|
||||||
|
| _______________^
|
||||||
|
LL | | x + 1;
|
||||||
|
LL | | });
|
||||||
|
| |______^ associated type `std::iter::Iterator::Item` changed to `()` here
|
||||||
|
LL | let f = e.filter(|_| false);
|
||||||
|
| -----------------
|
||||||
|
note: required by a bound in `collect`
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue