Auto merge of #88719 - estebank:point-at-arg-for-obligation, r=nagisa
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. Move the information about pointing at the call argument expression in an unmet obligation span from the `FulfillmentError` to a new `ObligationCauseCode`. When giving an error about an obligation introduced by a function call that an argument doesn't fulfill, and that argument is a block, add a span_label pointing at the innermost tail expression. Current output: ``` error[E0425]: cannot find value `x` in this scope --> f10.rs:4:14 | 4 | Some(x * 2) | ^ not found in this scope error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>` --> f10.rs:2:31 | 2 | let p = Some(45).and_then({ | ______________________--------_^ | | | | | required by a bound introduced by this call 3 | | |x| println!("doubling {}", x); 4 | | Some(x * 2) | | ----------- 5 | | }); | |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>` | = help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>` ``` Previous output: ``` error[E0425]: cannot find value `x` in this scope --> f10.rs:4:14 | 4 | Some(x * 2) | ^ not found in this scope error[E0277]: expected a `FnOnce<({integer},)>` closure, found `Option<_>` --> f10.rs:2:22 | 2 | let p = Some(45).and_then({ | ^^^^^^^^ expected an `FnOnce<({integer},)>` closure, found `Option<_>` | = help: the trait `FnOnce<({integer},)>` is not implemented for `Option<_>` ``` Partially address #27300. Will require rebasing on top of #88546.
This commit is contained in:
commit
e36621057d
108 changed files with 884 additions and 400 deletions
|
@ -29,7 +29,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
|
||||
_ => return None,
|
||||
};
|
||||
let (parent, impl_def_id) = match &cause.code {
|
||||
// If we added a "points at argument expression" obligation, we remove it here, we care
|
||||
// about the original obligation only.
|
||||
let code = match &cause.code {
|
||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => &*parent_code,
|
||||
_ => &cause.code,
|
||||
};
|
||||
let (parent, impl_def_id) = match code {
|
||||
ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
|
||||
_ => return None,
|
||||
};
|
||||
|
|
|
@ -66,10 +66,6 @@ pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;
|
|||
pub struct FulfillmentError<'tcx> {
|
||||
pub obligation: PredicateObligation<'tcx>,
|
||||
pub code: FulfillmentErrorCode<'tcx>,
|
||||
/// Diagnostics only: we opportunistically change the `code.span` when we encounter an
|
||||
/// obligation error caused by a call argument. When this is the case, we also signal that in
|
||||
/// this field to ensure accuracy of suggestions.
|
||||
pub points_at_arg_span: bool,
|
||||
/// Diagnostics only: the 'root' obligation which resulted in
|
||||
/// the failure to process `obligation`. This is the obligation
|
||||
/// that was initially passed to `register_predicate_obligation`
|
||||
|
@ -128,7 +124,7 @@ impl<'tcx> FulfillmentError<'tcx> {
|
|||
code: FulfillmentErrorCode<'tcx>,
|
||||
root_obligation: PredicateObligation<'tcx>,
|
||||
) -> FulfillmentError<'tcx> {
|
||||
FulfillmentError { obligation, code, points_at_arg_span: false, root_obligation }
|
||||
FulfillmentError { obligation, code, root_obligation }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue