Rollup merge of #67354 - VirrageS:blame-wrong-line, r=estebank
Fix pointing at arg when cause is outside of call Follow up after: #66933 Closes: #66923 r? @estebank
This commit is contained in:
commit
5a8083c665
|
@ -3880,36 +3880,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
call_sp: Span,
|
call_sp: Span,
|
||||||
args: &'tcx [hir::Expr],
|
args: &'tcx [hir::Expr],
|
||||||
) {
|
) {
|
||||||
if !call_sp.desugaring_kind().is_some() {
|
// We *do not* do this for desugared call spans to keep good diagnostics when involving
|
||||||
// We *do not* do this for desugared call spans to keep good diagnostics when involving
|
// the `?` operator.
|
||||||
// the `?` operator.
|
if call_sp.desugaring_kind().is_some() {
|
||||||
for error in errors {
|
return
|
||||||
if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
|
}
|
||||||
// Collect the argument position for all arguments that could have caused this
|
|
||||||
// `FulfillmentError`.
|
|
||||||
let mut referenced_in = final_arg_types.iter()
|
|
||||||
.map(|(i, checked_ty, _)| (i, checked_ty))
|
|
||||||
.chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty)))
|
|
||||||
.flat_map(|(i, ty)| {
|
|
||||||
let ty = self.resolve_vars_if_possible(ty);
|
|
||||||
// We walk the argument type because the argument's type could have
|
|
||||||
// been `Option<T>`, but the `FulfillmentError` references `T`.
|
|
||||||
ty.walk()
|
|
||||||
.filter(|&ty| ty == predicate.skip_binder().self_ty())
|
|
||||||
.map(move |_| *i)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Both checked and coerced types could have matched, thus we need to remove
|
for error in errors {
|
||||||
// duplicates.
|
// Only if the cause is somewhere inside the expression we want try to point at arg.
|
||||||
referenced_in.dedup();
|
// Otherwise, it means that the cause is somewhere else and we should not change
|
||||||
|
// anything because we can break the correct span.
|
||||||
|
if !call_sp.contains(error.obligation.cause.span) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
|
if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
|
||||||
// We make sure that only *one* argument matches the obligation failure
|
// Collect the argument position for all arguments that could have caused this
|
||||||
// and we assign the obligation's span to its expression's.
|
// `FulfillmentError`.
|
||||||
error.obligation.cause.span = args[ref_in].span;
|
let mut referenced_in = final_arg_types.iter()
|
||||||
error.points_at_arg_span = true;
|
.map(|(i, checked_ty, _)| (i, checked_ty))
|
||||||
}
|
.chain(final_arg_types.iter().map(|(i, _, coerced_ty)| (i, coerced_ty)))
|
||||||
|
.flat_map(|(i, ty)| {
|
||||||
|
let ty = self.resolve_vars_if_possible(ty);
|
||||||
|
// We walk the argument type because the argument's type could have
|
||||||
|
// been `Option<T>`, but the `FulfillmentError` references `T`.
|
||||||
|
ty.walk()
|
||||||
|
.filter(|&ty| ty == predicate.skip_binder().self_ty())
|
||||||
|
.map(move |_| *i)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Both checked and coerced types could have matched, thus we need to remove
|
||||||
|
// duplicates.
|
||||||
|
referenced_in.dedup();
|
||||||
|
|
||||||
|
if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
|
||||||
|
// We make sure that only *one* argument matches the obligation failure
|
||||||
|
// and we assign the obligation's span to its expression's.
|
||||||
|
error.obligation.cause.span = args[ref_in].span;
|
||||||
|
error.points_at_arg_span = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ pub fn no_debug() {
|
||||||
pub fn no_hash() {
|
pub fn no_hash() {
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
let mut set = HashSet::new();
|
let mut set = HashSet::new();
|
||||||
|
//~^ ERROR arrays only have std trait implementations for lengths 0..=32
|
||||||
set.insert([0_usize; 33]);
|
set.insert([0_usize; 33]);
|
||||||
//~^ ERROR arrays only have std trait implementations for lengths 0..=32
|
//~^ ERROR arrays only have std trait implementations for lengths 0..=32
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,15 +8,24 @@ LL | println!("{:?}", [0_usize; 33]);
|
||||||
= note: required by `std::fmt::Debug::fmt`
|
= note: required by `std::fmt::Debug::fmt`
|
||||||
|
|
||||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||||
--> $DIR/core-traits-no-impls-length-33.rs:9:16
|
--> $DIR/core-traits-no-impls-length-33.rs:10:16
|
||||||
|
|
|
|
||||||
LL | set.insert([0_usize; 33]);
|
LL | set.insert([0_usize; 33]);
|
||||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
|
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
|
||||||
|
|
|
|
||||||
= note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
|
= note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
|
||||||
|
|
||||||
|
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||||
|
--> $DIR/core-traits-no-impls-length-33.rs:8:19
|
||||||
|
|
|
||||||
|
LL | let mut set = HashSet::new();
|
||||||
|
| ^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
|
||||||
|
= note: required by `std::collections::HashSet::<T>::new`
|
||||||
|
|
||||||
error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]`
|
error[E0369]: binary operation `==` cannot be applied to type `[usize; 33]`
|
||||||
--> $DIR/core-traits-no-impls-length-33.rs:14:19
|
--> $DIR/core-traits-no-impls-length-33.rs:15:19
|
||||||
|
|
|
|
||||||
LL | [0_usize; 33] == [1_usize; 33]
|
LL | [0_usize; 33] == [1_usize; 33]
|
||||||
| ------------- ^^ ------------- [usize; 33]
|
| ------------- ^^ ------------- [usize; 33]
|
||||||
|
@ -26,7 +35,7 @@ LL | [0_usize; 33] == [1_usize; 33]
|
||||||
= note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]`
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `[usize; 33]`
|
||||||
|
|
||||||
error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]`
|
error[E0369]: binary operation `<` cannot be applied to type `[usize; 33]`
|
||||||
--> $DIR/core-traits-no-impls-length-33.rs:19:19
|
--> $DIR/core-traits-no-impls-length-33.rs:20:19
|
||||||
|
|
|
|
||||||
LL | [0_usize; 33] < [1_usize; 33]
|
LL | [0_usize; 33] < [1_usize; 33]
|
||||||
| ------------- ^ ------------- [usize; 33]
|
| ------------- ^ ------------- [usize; 33]
|
||||||
|
@ -36,7 +45,7 @@ LL | [0_usize; 33] < [1_usize; 33]
|
||||||
= note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]`
|
= note: an implementation of `std::cmp::PartialOrd` might be missing for `[usize; 33]`
|
||||||
|
|
||||||
error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied
|
error[E0277]: the trait bound `&[usize; 33]: std::iter::IntoIterator` is not satisfied
|
||||||
--> $DIR/core-traits-no-impls-length-33.rs:24:14
|
--> $DIR/core-traits-no-impls-length-33.rs:25:14
|
||||||
|
|
|
|
||||||
LL | for _ in &[0_usize; 33] {
|
LL | for _ in &[0_usize; 33] {
|
||||||
| ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]`
|
| ^^^^^^^^^^^^^^ the trait `std::iter::IntoIterator` is not implemented for `&[usize; 33]`
|
||||||
|
@ -48,7 +57,7 @@ LL | for _ in &[0_usize; 33] {
|
||||||
<&'a mut [T] as std::iter::IntoIterator>
|
<&'a mut [T] as std::iter::IntoIterator>
|
||||||
= note: required by `std::iter::IntoIterator::into_iter`
|
= note: required by `std::iter::IntoIterator::into_iter`
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0369.
|
Some errors have detailed explanations: E0277, E0369.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
For more information about an error, try `rustc --explain E0277`.
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// This test checks that errors are showed for lines with `collect` rather than `push` method.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = vec![1_f64, 2.2_f64];
|
||||||
|
let mut fft: Vec<Vec<f64>> = vec![];
|
||||||
|
|
||||||
|
let x1: &[f64] = &v;
|
||||||
|
let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
|
//~^ ERROR a value of type
|
||||||
|
fft.push(x2);
|
||||||
|
|
||||||
|
let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
|
//~^ ERROR a value of type
|
||||||
|
fft.push(x3);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0277]: a value of type `std::vec::Vec<f64>` cannot be built from an iterator over elements of type `&f64`
|
||||||
|
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:39
|
||||||
|
|
|
||||||
|
LL | let x2: Vec<f64> = x1.into_iter().collect();
|
||||||
|
| ^^^^^^^ value of type `std::vec::Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||||
|
|
|
||||||
|
= help: the trait `std::iter::FromIterator<&f64>` is not implemented for `std::vec::Vec<f64>`
|
||||||
|
|
||||||
|
error[E0277]: a value of type `std::vec::Vec<f64>` cannot be built from an iterator over elements of type `&f64`
|
||||||
|
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:29
|
||||||
|
|
|
||||||
|
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
||||||
|
| ^^^^^^^ value of type `std::vec::Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
||||||
|
|
|
||||||
|
= help: the trait `std::iter::FromIterator<&f64>` is not implemented for `std::vec::Vec<f64>`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue