Wrap more into into closure_typeinfo query.
This commit is contained in:
parent
7dcc74eee5
commit
0915d55d87
9 changed files with 49 additions and 56 deletions
|
@ -6,7 +6,7 @@ use rustc_errors::{
|
||||||
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
||||||
};
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
|
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
|
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
|
@ -236,10 +236,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
|
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
|
||||||
let needs_note = match ty.kind() {
|
let needs_note = match ty.kind() {
|
||||||
ty::Closure(id, _) => {
|
ty::Closure(id, _) => {
|
||||||
let tables = self.infcx.tcx.typeck(id.expect_local());
|
self.infcx.tcx.closure_kind_origin(id.expect_local()).is_none()
|
||||||
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(id.expect_local());
|
|
||||||
|
|
||||||
tables.closure_kind_origins().get(hir_id).is_none()
|
|
||||||
}
|
}
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
|
@ -1670,7 +1667,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
format!("`{}` would have to be valid for `{}`...", name, region_name),
|
format!("`{}` would have to be valid for `{}`...", name, region_name),
|
||||||
);
|
);
|
||||||
|
|
||||||
let fn_hir_id = self.mir_hir_id();
|
|
||||||
err.span_label(
|
err.span_label(
|
||||||
drop_span,
|
drop_span,
|
||||||
format!(
|
format!(
|
||||||
|
@ -1678,19 +1674,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
name,
|
name,
|
||||||
self.infcx
|
self.infcx
|
||||||
.tcx
|
.tcx
|
||||||
.hir()
|
.opt_item_name(self.mir_def_id().to_def_id())
|
||||||
.opt_name(fn_hir_id)
|
|
||||||
.map(|name| format!("function `{}`", name))
|
.map(|name| format!("function `{}`", name))
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
match &self
|
match &self.infcx.tcx.def_kind(self.mir_def_id()) {
|
||||||
.infcx
|
DefKind::Closure => "enclosing closure",
|
||||||
.tcx
|
DefKind::Generator => "enclosing generator",
|
||||||
.typeck(self.mir_def_id())
|
|
||||||
.node_type(fn_hir_id)
|
|
||||||
.kind()
|
|
||||||
{
|
|
||||||
ty::Closure(..) => "enclosing closure",
|
|
||||||
ty::Generator(..) => "enclosing generator",
|
|
||||||
kind => bug!("expected closure or generator, found {:?}", kind),
|
kind => bug!("expected closure or generator, found {:?}", kind),
|
||||||
}
|
}
|
||||||
.to_string()
|
.to_string()
|
||||||
|
|
|
@ -115,11 +115,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
|
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
|
||||||
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() {
|
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() {
|
||||||
let did = did.expect_local();
|
let did = did.expect_local();
|
||||||
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(did);
|
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||||
|
|
||||||
if let Some((span, hir_place)) =
|
|
||||||
self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id)
|
|
||||||
{
|
|
||||||
diag.span_note(
|
diag.span_note(
|
||||||
*span,
|
*span,
|
||||||
&format!(
|
&format!(
|
||||||
|
@ -139,11 +135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() {
|
if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() {
|
||||||
let did = did.expect_local();
|
let did = did.expect_local();
|
||||||
let hir_id = self.infcx.tcx.hir().local_def_id_to_hir_id(did);
|
if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) {
|
||||||
|
|
||||||
if let Some((span, hir_place)) =
|
|
||||||
self.infcx.tcx.typeck(did).closure_kind_origins().get(hir_id)
|
|
||||||
{
|
|
||||||
diag.span_note(
|
diag.span_note(
|
||||||
*span,
|
*span,
|
||||||
&format!(
|
&format!(
|
||||||
|
@ -373,14 +365,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
//
|
//
|
||||||
// We know the field exists so it's safe to call operator[] and `unwrap` here.
|
// We know the field exists so it's safe to call operator[] and `unwrap` here.
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
let var_id = self
|
let var_id =
|
||||||
.infcx
|
self.infcx.tcx.closure_captures(def_id)[field.index()].get_root_variable();
|
||||||
.tcx
|
|
||||||
.typeck(def_id)
|
|
||||||
.closure_min_captures_flattened(def_id)
|
|
||||||
.nth(field.index())
|
|
||||||
.unwrap()
|
|
||||||
.get_root_variable();
|
|
||||||
|
|
||||||
Some(self.infcx.tcx.hir().name(var_id).to_string())
|
Some(self.infcx.tcx.hir().name(var_id).to_string())
|
||||||
}
|
}
|
||||||
|
@ -987,7 +973,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
|
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
|
||||||
if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = expr {
|
if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = expr {
|
||||||
for (captured_place, place) in
|
for (captured_place, place) in
|
||||||
self.infcx.tcx.typeck(def_id).closure_min_captures_flattened(def_id).zip(places)
|
self.infcx.tcx.closure_captures(def_id).iter().zip(places)
|
||||||
{
|
{
|
||||||
match place {
|
match place {
|
||||||
Operand::Copy(place) | Operand::Move(place)
|
Operand::Copy(place) | Operand::Move(place)
|
||||||
|
|
|
@ -901,10 +901,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
) {
|
) {
|
||||||
let tables = tcx.typeck(closure_local_def_id);
|
let tables = tcx.typeck(closure_local_def_id);
|
||||||
let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_local_def_id);
|
if let Some((span, closure_kind_origin)) = tcx.closure_kind_origin(closure_local_def_id) {
|
||||||
if let Some((span, closure_kind_origin)) =
|
|
||||||
&tables.closure_kind_origins().get(closure_hir_id)
|
|
||||||
{
|
|
||||||
let reason = if let PlaceBase::Upvar(upvar_id) = closure_kind_origin.base {
|
let reason = if let PlaceBase::Upvar(upvar_id) = closure_kind_origin.base {
|
||||||
let upvar = ty::place_to_string_for_capture(tcx, closure_kind_origin);
|
let upvar = ty::place_to_string_for_capture(tcx, closure_kind_origin);
|
||||||
let root_hir_id = upvar_id.var_path.hir_id;
|
let root_hir_id = upvar_id.var_path.hir_id;
|
||||||
|
|
|
@ -26,11 +26,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
if !self.tcx().is_closure(mir_def_id.to_def_id()) {
|
if !self.tcx().is_closure(mir_def_id.to_def_id()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(user_provided_poly_sig) =
|
let user_provided_poly_sig = self.tcx().closure_user_provided_sig(mir_def_id);
|
||||||
self.tcx().typeck(mir_def_id).user_provided_sigs.get(&mir_def_id)
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instantiate the canonicalized variables from user-provided signature
|
// Instantiate the canonicalized variables from user-provided signature
|
||||||
// (e.g., the `_` in the code above) with fresh variables.
|
// (e.g., the `_` in the code above) with fresh variables.
|
||||||
|
|
|
@ -116,6 +116,7 @@ macro_rules! arena_types {
|
||||||
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
|
[] bit_set_u32: rustc_index::bit_set::BitSet<u32>,
|
||||||
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
|
||||||
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
|
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
|
||||||
|
[] closure_kind_origin: (rustc_span::Span, rustc_middle::hir::place::Place<'tcx>),
|
||||||
]);
|
]);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,7 +475,7 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
query closure_captures(key: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
|
query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> {
|
||||||
desc {
|
desc {
|
||||||
|tcx| "finding symbols for captures of closure `{}`",
|
|tcx| "finding symbols for captures of closure `{}`",
|
||||||
tcx.def_path_str(key.to_def_id())
|
tcx.def_path_str(key.to_def_id())
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::{mir, ty};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||||
use rustc_hir::def::DefKind;
|
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
use rustc_hir::{self as hir, LangItem};
|
use rustc_hir::{self as hir, LangItem};
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
@ -234,14 +233,39 @@ impl<'tcx> CapturedPlace<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_captures<'tcx>(
|
#[derive(Copy, Clone, Debug, HashStable)]
|
||||||
tcx: TyCtxt<'tcx>,
|
pub struct ClosureTypeInfo<'tcx> {
|
||||||
def: LocalDefId,
|
user_provided_sig: ty::CanonicalPolyFnSig<'tcx>,
|
||||||
) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
|
captures: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
|
||||||
let (DefKind::Closure | DefKind::Generator) = tcx.def_kind(def) else { return &[] };
|
kind_origin: Option<&'tcx (Span, HirPlace<'tcx>)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo<'tcx> {
|
||||||
|
debug_assert!(tcx.is_closure(def.to_def_id()));
|
||||||
let typeck_results = tcx.typeck(def);
|
let typeck_results = tcx.typeck(def);
|
||||||
|
let user_provided_sig = typeck_results.user_provided_sigs[&def];
|
||||||
let captures = typeck_results.closure_min_captures_flattened(def);
|
let captures = typeck_results.closure_min_captures_flattened(def);
|
||||||
tcx.arena.alloc_from_iter(captures)
|
let captures = tcx.arena.alloc_from_iter(captures);
|
||||||
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||||
|
let kind_origin = typeck_results.closure_kind_origins().get(hir_id);
|
||||||
|
ClosureTypeInfo { user_provided_sig, captures, kind_origin }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
pub fn closure_kind_origin(self, def_id: LocalDefId) -> Option<&'tcx (Span, HirPlace<'tcx>)> {
|
||||||
|
self.closure_typeinfo(def_id).kind_origin
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn closure_user_provided_sig(self, def_id: LocalDefId) -> ty::CanonicalPolyFnSig<'tcx> {
|
||||||
|
self.closure_typeinfo(def_id).user_provided_sig
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn closure_captures(self, def_id: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
|
||||||
|
if !self.is_closure(def_id.to_def_id()) {
|
||||||
|
return &[];
|
||||||
|
};
|
||||||
|
self.closure_typeinfo(def_id).captures
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if the `proj_possible_ancestor` represents an ancestor path
|
/// Return true if the `proj_possible_ancestor` represents an ancestor path
|
||||||
|
@ -434,5 +458,5 @@ impl BorrowKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
*providers = ty::query::Providers { closure_captures, ..*providers }
|
*providers = ty::query::Providers { closure_typeinfo, ..*providers }
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub use self::binding::BindingMode;
|
||||||
pub use self::binding::BindingMode::*;
|
pub use self::binding::BindingMode::*;
|
||||||
pub use self::closure::{
|
pub use self::closure::{
|
||||||
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
|
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
|
||||||
CapturedPlace, ClosureKind, MinCaptureInformationMap, MinCaptureList,
|
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
|
||||||
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath,
|
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath,
|
||||||
CAPTURE_STRUCT_LOCAL,
|
CAPTURE_STRUCT_LOCAL,
|
||||||
};
|
};
|
||||||
|
|
|
@ -569,7 +569,7 @@ impl<'a, V> LocalTableInContext<'a, V> {
|
||||||
self.data.contains_key(&id.local_id)
|
self.data.contains_key(&id.local_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, id: hir::HirId) -> Option<&V> {
|
pub fn get(&self, id: hir::HirId) -> Option<&'a V> {
|
||||||
validate_hir_id_for_typeck_results(self.hir_owner, id);
|
validate_hir_id_for_typeck_results(self.hir_owner, id);
|
||||||
self.data.get(&id.local_id)
|
self.data.get(&id.local_id)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue