Skip to content

Commit c1ed439

Browse files
committed
review comments
1 parent 2fbd692 commit c1ed439

File tree

4 files changed

+33
-18
lines changed

4 files changed

+33
-18
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10141014
_ => "_".to_string(),
10151015
}).collect::<Vec<_>>().join(", "),
10161016
);
1017+
// When the obligation error has been ensured to have been caused by
1018+
// an argument, the `obligation.cause.span` points at the expression
1019+
// of the argument, so we can provide a suggestion. This is signaled
1020+
// by `points_at_arg`. Otherwise, we give a more general note.
10171021
if points_at_arg {
10181022
err.span_suggestion(
10191023
obligation.cause.span,

src/librustc/traits/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ EnumTypeFoldableImpl! {
485485
pub struct FulfillmentError<'tcx> {
486486
pub obligation: PredicateObligation<'tcx>,
487487
pub code: FulfillmentErrorCode<'tcx>,
488+
/// Diagnostics only: we opportunistically change the `code.span` when we encounter an
489+
/// obligation error caused by a call argument. When this is the case, we also signal that in
490+
/// this field to ensure accuracy of suggestions.
488491
pub points_at_arg_span: bool,
489492
}
490493

src/librustc_typeck/check/mod.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -885,12 +885,12 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
885885
};
886886

887887
// All type checking constraints were added, try to fallback unsolved variables.
888-
fcx.select_obligations_where_possible(false);
888+
fcx.select_obligations_where_possible(false, |_| {});
889889
let mut fallback_has_occurred = false;
890890
for ty in &fcx.unsolved_variables() {
891891
fallback_has_occurred |= fcx.fallback_if_possible(ty);
892892
}
893-
fcx.select_obligations_where_possible(fallback_has_occurred);
893+
fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
894894

895895
// Even though coercion casts provide type hints, we check casts after fallback for
896896
// backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
@@ -2356,7 +2356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23562356
// possible. This can help substantially when there are
23572357
// indirect dependencies that don't seem worth tracking
23582358
// precisely.
2359-
self.select_obligations_where_possible(false);
2359+
self.select_obligations_where_possible(false, |_| {});
23602360
ty = self.resolve_vars_if_possible(&ty);
23612361

23622362
debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
@@ -2807,7 +2807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28072807
fn resolve_generator_interiors(&self, def_id: DefId) {
28082808
let mut generators = self.deferred_generator_interiors.borrow_mut();
28092809
for (body_id, interior, kind) in generators.drain(..) {
2810-
self.select_obligations_where_possible(false);
2810+
self.select_obligations_where_possible(false, |_| {});
28112811
generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
28122812
}
28132813
}
@@ -2844,8 +2844,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
28442844
}
28452845

28462846
/// Select as many obligations as we can at present.
2847-
fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
2848-
if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2847+
fn select_obligations_where_possible(
2848+
&self,
2849+
fallback_has_occurred: bool,
2850+
f: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
2851+
) {
2852+
if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
2853+
f(&mut errors);
28492854
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
28502855
}
28512856
}
@@ -3267,20 +3272,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32673272
// an "opportunistic" vtable resolution of any trait bounds on
32683273
// the call. This helps coercions.
32693274
if check_closures {
3270-
// We don't use `select_obligations_where_possible` to try to figure out if the
3271-
// obligation is comming from a single fn call argument, and if it is, we point
3272-
// at the expression corresponding to that argument, instead of the call.
3273-
if let Err(
3274-
mut errors,
3275-
) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3275+
self.select_obligations_where_possible(false, |errors| {
32763276
self.point_at_arg_instead_of_call_if_possible(
3277-
&mut errors,
3277+
errors,
32783278
&final_arg_types[..],
32793279
sp,
32803280
&args,
32813281
);
3282-
self.report_fulfillment_errors(&errors, self.inh.body_id, false);
3283-
}
3282+
})
32843283
}
32853284

32863285
// For C-variadic functions, we don't have a declared type for all of
@@ -3394,8 +3393,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33943393
}
33953394
}
33963395
}
3397-
if referenced_in.len() == 1 {
3398-
error.obligation.cause.span = args[referenced_in[0]].span;
3396+
let mut referenced_in = final_arg_types.iter()
3397+
.flat_map(|(i, ty)| {
3398+
let ty = self.resolve_vars_if_possible(ty);
3399+
ty.walk()
3400+
.filter(|&ty| ty == predicate.skip_binder().self_ty())
3401+
.map(move |_| *i)
3402+
});
3403+
if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
3404+
// We make sure that only *one* argument matches the obligation failure
3405+
// and thet the obligation's span to its expression's.
3406+
error.obligation.cause.span = args[ref_in].span;
33993407
error.points_at_arg_span = true;
34003408
}
34013409
}

src/librustc_typeck/check/op.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
724724
match method {
725725
Some(ok) => {
726726
let method = self.register_infer_ok_obligations(ok);
727-
self.select_obligations_where_possible(false);
727+
self.select_obligations_where_possible(false, |_| {});
728728

729729
Ok(method)
730730
}

0 commit comments

Comments
 (0)