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
|
@ -3,6 +3,7 @@
|
|||
use crate::arena::Arena;
|
||||
use crate::dep_graph::DepGraph;
|
||||
use crate::hir::exports::ExportMap;
|
||||
use crate::hir::place::Place as HirPlace;
|
||||
use crate::ich::{NodeIdHashingMode, StableHashingContext};
|
||||
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
|
||||
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
|
||||
|
@ -379,7 +380,7 @@ pub struct TypeckResults<'tcx> {
|
|||
|
||||
/// Records the reasons that we picked the kind of each closure;
|
||||
/// not all closures are present in the map.
|
||||
closure_kind_origins: ItemLocalMap<(Span, Symbol)>,
|
||||
closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
|
||||
|
||||
/// For each fn, records the "liberated" types of its arguments
|
||||
/// and return type. Liberated means that all bound regions
|
||||
|
@ -642,11 +643,13 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
self.upvar_capture_map[&upvar_id]
|
||||
}
|
||||
|
||||
pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, Symbol)> {
|
||||
pub fn closure_kind_origins(&self) -> LocalTableInContext<'_, (Span, HirPlace<'tcx>)> {
|
||||
LocalTableInContext { hir_owner: self.hir_owner, data: &self.closure_kind_origins }
|
||||
}
|
||||
|
||||
pub fn closure_kind_origins_mut(&mut self) -> LocalTableInContextMut<'_, (Span, Symbol)> {
|
||||
pub fn closure_kind_origins_mut(
|
||||
&mut self,
|
||||
) -> LocalTableInContextMut<'_, (Span, HirPlace<'tcx>)> {
|
||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.closure_kind_origins }
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ pub use self::IntVarValue::*;
|
|||
pub use self::Variance::*;
|
||||
|
||||
use crate::hir::exports::ExportMap;
|
||||
use crate::hir::place::Place as HirPlace;
|
||||
use crate::hir::place::{
|
||||
Place as HirPlace, PlaceBase as HirPlaceBase, ProjectionKind as HirProjectionKind,
|
||||
};
|
||||
use crate::ich::StableHashingContext;
|
||||
use crate::middle::cstore::CrateStoreDyn;
|
||||
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
|
||||
|
@ -734,6 +736,43 @@ pub struct CapturedPlace<'tcx> {
|
|||
pub info: CaptureInfo<'tcx>,
|
||||
}
|
||||
|
||||
pub fn place_to_string_for_capture(tcx: TyCtxt<'tcx>, place: &HirPlace<'tcx>) -> String {
|
||||
let name = match place.base {
|
||||
HirPlaceBase::Upvar(upvar_id) => tcx.hir().name(upvar_id.var_path.hir_id).to_string(),
|
||||
_ => bug!("Capture_information should only contain upvars"),
|
||||
};
|
||||
let mut curr_string = name;
|
||||
|
||||
for (i, proj) in place.projections.iter().enumerate() {
|
||||
match proj.kind {
|
||||
HirProjectionKind::Deref => {
|
||||
curr_string = format!("*{}", curr_string);
|
||||
}
|
||||
HirProjectionKind::Field(idx, variant) => match place.ty_before_projection(i).kind() {
|
||||
ty::Adt(def, ..) => {
|
||||
curr_string = format!(
|
||||
"{}.{}",
|
||||
curr_string,
|
||||
def.variants[variant].fields[idx as usize].ident.name.as_str()
|
||||
);
|
||||
}
|
||||
ty::Tuple(_) => {
|
||||
curr_string = format!("{}.{}", curr_string, idx);
|
||||
}
|
||||
_ => {
|
||||
bug!(
|
||||
"Field projection applied to a type other than Adt or Tuple: {:?}.",
|
||||
place.ty_before_projection(i).kind()
|
||||
)
|
||||
}
|
||||
},
|
||||
proj => bug!("{:?} unexpected because it isn't captured", proj),
|
||||
}
|
||||
}
|
||||
|
||||
curr_string.to_string()
|
||||
}
|
||||
|
||||
/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
|
||||
/// for a particular capture as well as identifying the part of the source code
|
||||
/// that triggered this capture to occur.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue