mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Point at argument instead of call for their obligations
When an obligation is introduced by a specific `fn` argument, point at the argument instead of the `fn` call if the obligation fails to be fulfilled.
This commit is contained in:
parent
2b5ddf36fd
commit
284a8a9ce7
@ -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<traits::FulfillmentError<'tcx>>),
|
||||
) -> 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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
|
||||
...
|
||||
LL | |value: &mut usize| {
|
||||
| ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
|
||||
LL | task(annotate(
|
||||
| __________^
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | Annotate::<RefMutFamily<usize>>::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(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
|
||||
|
|
||||
note: required by a bound in `annotate`
|
||||
--> $DIR/issue-62529-1.rs:44:8
|
||||
|
@ -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
|
||||
|
@ -44,8 +44,6 @@ fn f9<X: ?Sized>(x1: Box<S<X>>) {
|
||||
fn f10<X: ?Sized>(x1: Box<S<X>>) {
|
||||
f5(&(32, *x1));
|
||||
//~^ ERROR the size for values of type
|
||||
//~| ERROR the size for values of type
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
pub fn main() {}
|
||||
|
@ -93,12 +93,12 @@ LL + fn f9<X>(x1: Box<S<X>>) {
|
||||
|
|
||||
|
||||
error[E0277]: the size for values of type `X` cannot be known at compilation time
|
||||
--> $DIR/unsized3.rs:45:9
|
||||
--> $DIR/unsized3.rs:45:8
|
||||
|
|
||||
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
|
||||
| - this type parameter needs to be `std::marker::Sized`
|
||||
LL | f5(&(32, *x1));
|
||||
| ^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required because it appears within the type `S<X>`
|
||||
--> $DIR/unsized3.rs:28:8
|
||||
@ -113,35 +113,6 @@ LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
|
||||
LL + fn f10<X>(x1: Box<S<X>>) {
|
||||
|
|
||||
|
||||
error[E0277]: the size for values of type `X` cannot be known at compilation time
|
||||
--> $DIR/unsized3.rs:45:8
|
||||
|
|
||||
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
|
||||
| - 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<X>`
|
||||
--> $DIR/unsized3.rs:28:8
|
||||
|
|
||||
LL | struct S<X: ?Sized> {
|
||||
| ^
|
||||
= note: required because it appears within the type `({integer}, S<X>)`
|
||||
note: required by a bound in `f5`
|
||||
--> $DIR/unsized3.rs:24:7
|
||||
|
|
||||
LL | fn f5<Y>(x: &Y) {}
|
||||
| ^ required by this bound in `f5`
|
||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||
|
|
||||
LL - fn f10<X: ?Sized>(x1: Box<S<X>>) {
|
||||
LL + fn f10<X>(x1: Box<S<X>>) {
|
||||
|
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | fn f5<Y: ?Sized>(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`.
|
||||
|
Loading…
Reference in New Issue
Block a user