Rollup merge of #80635 - sexxi-goose:use-place-instead-of-symbol, r=nikomatsakis`
Improve diagnostics when closure doesn't meet trait bound Improves the diagnostics when closure doesn't meet trait bound by modifying `TypeckResuts::closure_kind_origins` such that `hir::Place` is used instead of `Symbol`. Using `hir::Place` to describe which capture influenced the decision of selecting a trait a closure satisfies to (Fn/FnMut/FnOnce, Copy) allows us to show precise path in the diagnostics when `capture_disjoint_field` feature is enabled. Closes rust-lang/project-rfc-2229/issues/21 r? ```@nikomatsakis```
This commit is contained in:
commit
19f97802ca
16 changed files with 328 additions and 23 deletions
|
@ -176,7 +176,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.demand_eqtype(span, inferred_kind.to_ty(self.tcx), closure_kind_ty);
|
||||
|
||||
// If we have an origin, store it.
|
||||
if let Some(origin) = delegate.current_origin {
|
||||
if let Some(origin) = delegate.current_origin.clone() {
|
||||
let origin = if self.tcx.features().capture_disjoint_fields {
|
||||
origin
|
||||
} else {
|
||||
// FIXME(project-rfc-2229#26): Once rust-lang#80092 is merged, we should restrict the
|
||||
// precision of origin as well. Otherwise, this will cause issues when project-rfc-2229#26
|
||||
// is fixed as we might see Index projections in the origin, which we can't print because
|
||||
// we don't store enough information.
|
||||
(origin.0, Place { projections: vec![], ..origin.1 })
|
||||
};
|
||||
|
||||
self.typeck_results
|
||||
.borrow_mut()
|
||||
.closure_kind_origins_mut()
|
||||
|
@ -563,7 +573,7 @@ struct InferBorrowKind<'a, 'tcx> {
|
|||
|
||||
// If we modified `current_closure_kind`, this field contains a `Some()` with the
|
||||
// variable access that caused us to do so.
|
||||
current_origin: Option<(Span, Symbol)>,
|
||||
current_origin: Option<(Span, Place<'tcx>)>,
|
||||
|
||||
/// For each Place that is captured by the closure, we track the minimal kind of
|
||||
/// access we need (ref, ref mut, move, etc) and the expression that resulted in such access.
|
||||
|
@ -628,7 +638,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
upvar_id.closure_expr_id,
|
||||
ty::ClosureKind::FnOnce,
|
||||
usage_span,
|
||||
var_name(tcx, upvar_id.var_path.hir_id),
|
||||
place_with_id.place.clone(),
|
||||
);
|
||||
|
||||
let capture_info = ty::CaptureInfo {
|
||||
|
@ -720,7 +730,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
upvar_id.closure_expr_id,
|
||||
ty::ClosureKind::FnMut,
|
||||
tcx.hir().span(diag_expr_id),
|
||||
var_name(tcx, upvar_id.var_path.hir_id),
|
||||
place_with_id.place.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -765,11 +775,11 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
closure_id: LocalDefId,
|
||||
new_kind: ty::ClosureKind,
|
||||
upvar_span: Span,
|
||||
var_name: Symbol,
|
||||
place: Place<'tcx>,
|
||||
) {
|
||||
debug!(
|
||||
"adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, var_name={})",
|
||||
closure_id, new_kind, upvar_span, var_name
|
||||
"adjust_closure_kind(closure_id={:?}, new_kind={:?}, upvar_span={:?}, place={:?})",
|
||||
closure_id, new_kind, upvar_span, place
|
||||
);
|
||||
|
||||
// Is this the closure whose kind is currently being inferred?
|
||||
|
@ -797,7 +807,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
|
|||
| (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
|
||||
// new kind is stronger than the old kind
|
||||
self.current_closure_kind = new_kind;
|
||||
self.current_origin = Some((upvar_span, var_name));
|
||||
self.current_origin = Some((upvar_span, place));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -384,9 +384,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
||||
let common_hir_owner = fcx_typeck_results.hir_owner;
|
||||
|
||||
for (&id, &origin) in fcx_typeck_results.closure_kind_origins().iter() {
|
||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id: id };
|
||||
self.typeck_results.closure_kind_origins_mut().insert(hir_id, origin);
|
||||
for (id, origin) in fcx_typeck_results.closure_kind_origins().iter() {
|
||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id: *id };
|
||||
let place_span = origin.0;
|
||||
let place = self.resolve(origin.1.clone(), &place_span);
|
||||
self.typeck_results.closure_kind_origins_mut().insert(hir_id, (place_span, place));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue