diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 9748c0835bf12..ed01dae59f672 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -83,7 +83,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// version (resolve_vars_if_possible), this version will /// also select obligations if it seems useful, in an effort /// to get more type information. - pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> { + pub(in super::super) fn resolve_vars_with_obligations(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.resolve_vars_with_obligations_and_mutate_fulfillment(ty, |_| {}) + } + + pub(in super::super) fn resolve_vars_with_obligations_and_mutate_fulfillment( + &self, + mut ty: Ty<'tcx>, + mutate_fulfillment_errors: impl Fn(&mut Vec>), + ) -> Ty<'tcx> { debug!("resolve_vars_with_obligations(ty={:?})", ty); // No Infer()? Nothing needs doing. @@ -103,7 +111,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // possible. This can help substantially when there are // indirect dependencies that don't seem worth tracking // precisely. - self.select_obligations_where_possible(false, |_| {}); + self.select_obligations_where_possible(false, mutate_fulfillment_errors); ty = self.resolve_vars_if_possible(ty); debug!("resolve_vars_with_obligations: ty={:?}", ty); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 9efb52a08b7e1..f5f1dd4265254 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -354,8 +354,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - debug!("checking the argument"); let formal_ty = formal_tys[i]; + debug!("checking argument {}: {:?} = {:?}", i, arg, formal_ty); // The special-cased logic below has three functions: // 1. Provide as good of an expected type as possible. @@ -367,6 +367,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to, which is `expected_ty` if `rvalue_hint` returns an // `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise. let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty); + + // Cause selection errors caused by resolving a single argument to point at the + // argument and not the call. This is otherwise redundant with the `demand_coerce` + // call immediately after, but it lets us customize the span pointed to in the + // fulfillment error to be more accurate. + let _ = self.resolve_vars_with_obligations_and_mutate_fulfillment( + coerce_ty, + |errors| { + // This is not coming from a macro or a `derive`. + if sp.desugaring_kind().is_none() + && !arg.span.from_expansion() + // Do not change the spans of `async fn`s. + && !matches!( + expr.kind, + hir::ExprKind::Call( + hir::Expr { + kind: hir::ExprKind::Path(hir::QPath::LangItem(_, _)), + .. + }, + _ + ) + ) { + for error in errors { + error.obligation.cause.make_mut().span = arg.span; + error.points_at_arg_span = true; + } + } + }, + ); + // We're processing function arguments so we definitely want to use // two-phase borrows. self.demand_coerce(&arg, checked_ty, coerce_ty, None, AllowTwoPhase::Yes); diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 8d919190532cf..ac4ac4cc99c1d 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -10,10 +10,10 @@ LL | f1(2i32, 4u32); | ~~~ error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:29:5 + --> $DIR/associated-types-path-2.rs:29:14 | LL | f1(2u32, 4u32); - | ^^ the trait `Foo` is not implemented for `u32` + | ^^^^ the trait `Foo` is not implemented for `u32` | note: required by a bound in `f1` --> $DIR/associated-types-path-2.rs:13:14 @@ -25,13 +25,13 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied --> $DIR/associated-types-path-2.rs:29:5 | LL | f1(2u32, 4u32); - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32` + | ^^ the trait `Foo` is not implemented for `u32` error[E0277]: the trait bound `u32: Foo` is not satisfied - --> $DIR/associated-types-path-2.rs:35:5 + --> $DIR/associated-types-path-2.rs:35:14 | LL | f1(2u32, 4i32); - | ^^ the trait `Foo` is not implemented for `u32` + | ^^^^ the trait `Foo` is not implemented for `u32` | note: required by a bound in `f1` --> $DIR/associated-types-path-2.rs:13:14 @@ -43,7 +43,7 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied --> $DIR/associated-types-path-2.rs:35:5 | LL | f1(2u32, 4i32); - | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `u32` + | ^^ the trait `Foo` is not implemented for `u32` error[E0308]: mismatched types --> $DIR/associated-types-path-2.rs:41:18 diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr index 8311c147ee3bd..c1ad986099e3e 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr @@ -1,11 +1,17 @@ error[E0631]: type mismatch in closure arguments --> $DIR/issue-62529-1.rs:80:10 | -LL | task(annotate( - | ^^^^^^^^ expected signature of `for<'r> fn( as FamilyLt<'r>>::Out) -> _` -... -LL | |value: &mut usize| { - | ------------------- found signature of `for<'r> fn(&'r mut usize) -> _` +LL | task(annotate( + | __________^ +LL | | +LL | | +LL | | Annotate::>::new(), +LL | | |value: &mut usize| { + | | ------------------- found signature of `for<'r> fn(&'r mut usize) -> _` +LL | | *value = 2; +LL | | } +LL | | )); + | |_____^ expected signature of `for<'r> fn( as FamilyLt<'r>>::Out) -> _` | note: required by a bound in `annotate` --> $DIR/issue-62529-1.rs:44:8 diff --git a/src/test/ui/issues/issue-60218.stderr b/src/test/ui/issues/issue-60218.stderr index ac33cfd040243..7f01f7fa8c686 100644 --- a/src/test/ui/issues/issue-60218.stderr +++ b/src/test/ui/issues/issue-60218.stderr @@ -1,8 +1,8 @@ error[E0277]: the trait bound `&u32: Foo` is not satisfied - --> $DIR/issue-60218.rs:18:5 + --> $DIR/issue-60218.rs:18:27 | LL | trigger_error(vec![], |x: &u32| x) - | ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32` + | ^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32` | note: required by a bound in `trigger_error` --> $DIR/issue-60218.rs:13:72 diff --git a/src/test/ui/unsized/unsized3.rs b/src/test/ui/unsized/unsized3.rs index f5b5d02593155..39b6583bc4ec4 100644 --- a/src/test/ui/unsized/unsized3.rs +++ b/src/test/ui/unsized/unsized3.rs @@ -44,8 +44,6 @@ fn f9(x1: Box>) { fn f10(x1: Box>) { f5(&(32, *x1)); //~^ ERROR the size for values of type - //~| ERROR the size for values of type } -pub fn main() { -} +pub fn main() {} diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr index f7bb6c9c78c65..e8d346a8b2963 100644 --- a/src/test/ui/unsized/unsized3.stderr +++ b/src/test/ui/unsized/unsized3.stderr @@ -92,27 +92,6 @@ LL - fn f9(x1: Box>) { LL + fn f9(x1: Box>) { | -error[E0277]: the size for values of type `X` cannot be known at compilation time - --> $DIR/unsized3.rs:45:9 - | -LL | fn f10(x1: Box>) { - | - this type parameter needs to be `std::marker::Sized` -LL | f5(&(32, *x1)); - | ^^^^^^^^^ doesn't have a size known at compile-time - | -note: required because it appears within the type `S` - --> $DIR/unsized3.rs:28:8 - | -LL | struct S { - | ^ - = note: required because it appears within the type `({integer}, S)` - = note: tuples must have a statically known size to be initialized -help: consider removing the `?Sized` bound to make the type parameter `Sized` - | -LL - fn f10(x1: Box>) { -LL + fn f10(x1: Box>) { - | - error[E0277]: the size for values of type `X` cannot be known at compilation time --> $DIR/unsized3.rs:45:8 | @@ -127,21 +106,13 @@ note: required because it appears within the type `S` LL | struct S { | ^ = note: required because it appears within the type `({integer}, S)` -note: required by a bound in `f5` - --> $DIR/unsized3.rs:24:7 - | -LL | fn f5(x: &Y) {} - | ^ required by this bound in `f5` + = note: tuples must have a statically known size to be initialized help: consider removing the `?Sized` bound to make the type parameter `Sized` | LL - fn f10(x1: Box>) { LL + fn f10(x1: Box>) { | -help: consider relaxing the implicit `Sized` restriction - | -LL | fn f5(x: &Y) {} - | ++++++++ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`.