Skip to content

Commit 7dcc74e

Browse files
committed
Access upvars through a query.
1 parent d35dbbd commit 7dcc74e

File tree

9 files changed

+111
-111
lines changed

9 files changed

+111
-111
lines changed

compiler/rustc_borrowck/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,14 @@ fn do_mir_borrowck<'tcx>(
202202
let mut errors = error::BorrowckErrors::new(infcx.tcx);
203203

204204
// Gather the upvars of a closure, if any.
205-
let tables = tcx.typeck_opt_const_arg(def);
206-
if let Some(e) = tables.tainted_by_errors {
205+
if let Some(e) = input_body.tainted_by_errors {
207206
infcx.set_tainted_by_errors(e);
208207
errors.set_tainted_by_errors(e);
209208
}
210-
let upvars: Vec<_> = tables
211-
.closure_min_captures_flattened(def.did)
212-
.map(|captured_place| {
209+
let upvars: Vec<_> = tcx
210+
.closure_captures(def.did)
211+
.iter()
212+
.map(|&captured_place| {
213213
let capture = captured_place.info.capture_kind;
214214
let by_ref = match capture {
215215
ty::UpvarCapture::ByValue => false,

compiler/rustc_const_eval/src/interpret/validity.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
240240
// FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar
241241
// https://github.com/rust-lang/project-rfc-2229/issues/46
242242
if let Some(local_def_id) = def_id.as_local() {
243-
let tables = self.ecx.tcx.typeck(local_def_id);
244-
if let Some(captured_place) =
245-
tables.closure_min_captures_flattened(local_def_id).nth(field)
246-
{
243+
let captures = self.ecx.tcx.closure_captures(local_def_id);
244+
if let Some(captured_place) = captures.get(field) {
247245
// Sometimes the index is beyond the number of upvars (seen
248246
// for a generator).
249247
let var_hir_id = captured_place.get_root_variable();

compiler/rustc_hir_typeck/src/upvar.rs

+3
Original file line numberDiff line numberDiff line change
@@ -526,10 +526,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
526526
PlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
527527
base => bug!("Expected upvar, found={:?}", base),
528528
};
529+
let var_ident = self.tcx.hir().ident(var_hir_id);
529530

530531
let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else {
531532
let mutability = self.determine_capture_mutability(&typeck_results, &place);
532533
let min_cap_list = vec![ty::CapturedPlace {
534+
var_ident,
533535
place,
534536
info: capture_info,
535537
mutability,
@@ -628,6 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628630
if !ancestor_found {
629631
let mutability = self.determine_capture_mutability(&typeck_results, &place);
630632
let captured_place = ty::CapturedPlace {
633+
var_ident,
631634
place,
632635
info: updated_capture_info,
633636
mutability,

compiler/rustc_middle/src/hir/map/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,11 @@ impl<'hir> Map<'hir> {
902902
self.opt_ident(id).map(|ident| ident.span)
903903
}
904904

905+
#[inline]
906+
pub fn ident(self, id: HirId) -> Ident {
907+
self.opt_ident(id).unwrap()
908+
}
909+
905910
#[inline]
906911
pub fn opt_name(self, id: HirId) -> Option<Symbol> {
907912
self.opt_ident(id).map(|ident| ident.name)

compiler/rustc_middle/src/query/mod.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,10 @@ rustc_queries! {
475475
}
476476
}
477477

478-
query symbols_for_closure_captures(
479-
key: (LocalDefId, LocalDefId)
480-
) -> &'tcx Vec<rustc_span::Symbol> {
481-
arena_cache
478+
query closure_captures(key: LocalDefId) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
482479
desc {
483-
|tcx| "finding symbols for captures of closure `{}` in `{}`",
484-
tcx.def_path_str(key.1.to_def_id()),
485-
tcx.def_path_str(key.0.to_def_id())
480+
|tcx| "finding symbols for captures of closure `{}`",
481+
tcx.def_path_str(key.to_def_id())
486482
}
487483
}
488484

compiler/rustc_middle/src/ty/closure.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use crate::{mir, ty};
55

66
use std::fmt::Write;
77

8-
use hir::LangItem;
98
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
10-
use rustc_hir as hir;
9+
use rustc_hir::def::DefKind;
1110
use rustc_hir::def_id::{DefId, LocalDefId};
11+
use rustc_hir::{self as hir, LangItem};
12+
use rustc_span::symbol::Ident;
1213
use rustc_span::{Span, Symbol};
1314

1415
use super::{Ty, TyCtxt};
@@ -129,6 +130,9 @@ impl<'tcx> ClosureKind {
129130
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
130131
#[derive(TypeFoldable, TypeVisitable)]
131132
pub struct CapturedPlace<'tcx> {
133+
/// Name and span where the binding happens.
134+
pub var_ident: Ident,
135+
132136
/// The `Place` that is captured.
133137
pub place: HirPlace<'tcx>,
134138

@@ -148,12 +152,8 @@ impl<'tcx> CapturedPlace<'tcx> {
148152
}
149153

150154
/// Returns a symbol of the captured upvar, which looks like `name__field1__field2`.
151-
fn to_symbol(&self, tcx: TyCtxt<'tcx>) -> Symbol {
152-
let hir_id = match self.place.base {
153-
HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
154-
base => bug!("Expected an upvar, found {:?}", base),
155-
};
156-
let mut symbol = tcx.hir().name(hir_id).as_str().to_string();
155+
pub fn to_symbol(&self) -> Symbol {
156+
let mut symbol = self.var_ident.to_string();
157157

158158
let mut ty = self.place.base_ty;
159159
for proj in self.place.projections.iter() {
@@ -169,11 +169,7 @@ impl<'tcx> CapturedPlace<'tcx> {
169169
.unwrap();
170170
}
171171
ty => {
172-
span_bug!(
173-
self.get_capture_kind_span(tcx),
174-
"Unexpected type {:?} for `Field` projection",
175-
ty
176-
)
172+
bug!("Unexpected type {:?} for `Field` projection", ty)
177173
}
178174
},
179175

@@ -238,10 +234,14 @@ impl<'tcx> CapturedPlace<'tcx> {
238234
}
239235
}
240236

241-
fn symbols_for_closure_captures(tcx: TyCtxt<'_>, def_id: (LocalDefId, LocalDefId)) -> Vec<Symbol> {
242-
let typeck_results = tcx.typeck(def_id.0);
243-
let captures = typeck_results.closure_min_captures_flattened(def_id.1);
244-
captures.into_iter().map(|captured_place| captured_place.to_symbol(tcx)).collect()
237+
fn closure_captures<'tcx>(
238+
tcx: TyCtxt<'tcx>,
239+
def: LocalDefId,
240+
) -> &'tcx [&'tcx ty::CapturedPlace<'tcx>] {
241+
let (DefKind::Closure | DefKind::Generator) = tcx.def_kind(def) else { return &[] };
242+
let typeck_results = tcx.typeck(def);
243+
let captures = typeck_results.closure_min_captures_flattened(def);
244+
tcx.arena.alloc_from_iter(captures)
245245
}
246246

247247
/// Return true if the `proj_possible_ancestor` represents an ancestor path
@@ -434,5 +434,5 @@ impl BorrowKind {
434434
}
435435

436436
pub fn provide(providers: &mut ty::query::Providers) {
437-
*providers = ty::query::Providers { symbols_for_closure_captures, ..*providers }
437+
*providers = ty::query::Providers { closure_captures, ..*providers }
438438
}

compiler/rustc_middle/src/ty/structural_impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ TrivialTypeTraversalAndLiftImpls! {
263263
crate::ty::UniverseIndex,
264264
crate::ty::Variance,
265265
::rustc_span::Span,
266+
::rustc_span::symbol::Ident,
266267
::rustc_errors::ErrorGuaranteed,
267268
Field,
268269
interpret::Scalar,

compiler/rustc_mir_build/src/build/mod.rs

+71-75
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::mir::*;
2020
use rustc_middle::thir::{
2121
self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
2222
};
23-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
23+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
2424
use rustc_span::symbol::sym;
2525
use rustc_span::Span;
2626
use rustc_span::Symbol;
@@ -155,13 +155,13 @@ struct BlockContext(Vec<BlockFrame>);
155155
struct Builder<'a, 'tcx> {
156156
tcx: TyCtxt<'tcx>,
157157
infcx: InferCtxt<'tcx>,
158-
typeck_results: &'tcx TypeckResults<'tcx>,
159158
region_scope_tree: &'tcx region::ScopeTree,
160159
param_env: ty::ParamEnv<'tcx>,
161160

162161
thir: &'a Thir<'tcx>,
163162
cfg: CFG<'tcx>,
164163

164+
def: ty::WithOptConstParam<LocalDefId>,
165165
def_id: DefId,
166166
hir_id: hir::HirId,
167167
parent_module: DefId,
@@ -522,13 +522,7 @@ fn construct_fn<'tcx>(
522522
let return_block =
523523
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
524524
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
525-
builder.args_and_body(
526-
START_BLOCK,
527-
fn_def.did,
528-
arguments,
529-
arg_scope,
530-
&thir[expr],
531-
)
525+
builder.args_and_body(START_BLOCK, arguments, arg_scope, &thir[expr])
532526
}))
533527
}));
534528
let source_info = builder.source_info(fn_end);
@@ -704,9 +698,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
704698
thir,
705699
tcx,
706700
infcx,
707-
typeck_results: tcx.typeck_opt_const_arg(def),
708701
region_scope_tree: tcx.region_scope_tree(def.did),
709702
param_env,
703+
def,
710704
def_id: def.did.to_def_id(),
711705
hir_id,
712706
parent_module: tcx.parent_module(hir_id).to_def_id(),
@@ -756,14 +750,78 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
756750
self.var_debug_info,
757751
self.fn_span,
758752
self.generator_kind,
759-
self.typeck_results.tainted_by_errors,
753+
None,
760754
)
761755
}
762756

757+
fn insert_upvar_arg(&mut self) {
758+
let Some(closure_arg) = self.local_decls.get(ty::CAPTURE_STRUCT_LOCAL) else { return };
759+
760+
let mut closure_ty = closure_arg.ty;
761+
let mut closure_env_projs = vec![];
762+
if let ty::Ref(_, ty, _) = closure_ty.kind() {
763+
closure_env_projs.push(ProjectionElem::Deref);
764+
closure_ty = *ty;
765+
}
766+
767+
let upvar_substs = match closure_ty.kind() {
768+
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
769+
ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
770+
_ => return,
771+
};
772+
773+
// In analyze_closure() in upvar.rs we gathered a list of upvars used by an
774+
// indexed closure and we stored in a map called closure_min_captures in TypeckResults
775+
// with the closure's DefId. Here, we run through that vec of UpvarIds for
776+
// the given closure and use the necessary information to create upvar
777+
// debuginfo and to fill `self.upvars`.
778+
let capture_tys = upvar_substs.upvar_tys();
779+
780+
let tcx = self.tcx;
781+
self.upvars = tcx
782+
.closure_captures(self.def.did)
783+
.iter()
784+
.zip(capture_tys)
785+
.enumerate()
786+
.map(|(i, (captured_place, ty))| {
787+
let name = captured_place.to_symbol();
788+
789+
let capture = captured_place.info.capture_kind;
790+
let var_id = match captured_place.place.base {
791+
HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
792+
_ => bug!("Expected an upvar"),
793+
};
794+
795+
let mutability = captured_place.mutability;
796+
797+
let mut projs = closure_env_projs.clone();
798+
projs.push(ProjectionElem::Field(Field::new(i), ty));
799+
match capture {
800+
ty::UpvarCapture::ByValue => {}
801+
ty::UpvarCapture::ByRef(..) => {
802+
projs.push(ProjectionElem::Deref);
803+
}
804+
};
805+
806+
let use_place = Place {
807+
local: ty::CAPTURE_STRUCT_LOCAL,
808+
projection: tcx.mk_place_elems(&projs),
809+
};
810+
self.var_debug_info.push(VarDebugInfo {
811+
name,
812+
source_info: SourceInfo::outermost(captured_place.var_ident.span),
813+
value: VarDebugInfoContents::Place(use_place),
814+
});
815+
816+
let capture = Capture { captured_place, use_place, mutability };
817+
(var_id, capture)
818+
})
819+
.collect();
820+
}
821+
763822
fn args_and_body(
764823
&mut self,
765824
mut block: BasicBlock,
766-
fn_def_id: LocalDefId,
767825
arguments: &IndexVec<ParamId, Param<'tcx>>,
768826
argument_scope: region::Scope,
769827
expr: &Expr<'tcx>,
@@ -785,69 +843,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
785843
}
786844
}
787845

788-
let tcx = self.tcx;
789-
let tcx_hir = tcx.hir();
790-
let hir_typeck_results = self.typeck_results;
791-
792-
// In analyze_closure() in upvar.rs we gathered a list of upvars used by an
793-
// indexed closure and we stored in a map called closure_min_captures in TypeckResults
794-
// with the closure's DefId. Here, we run through that vec of UpvarIds for
795-
// the given closure and use the necessary information to create upvar
796-
// debuginfo and to fill `self.upvars`.
797-
if hir_typeck_results.closure_min_captures.get(&fn_def_id).is_some() {
798-
let mut closure_env_projs = vec![];
799-
let mut closure_ty = self.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
800-
if let ty::Ref(_, ty, _) = closure_ty.kind() {
801-
closure_env_projs.push(ProjectionElem::Deref);
802-
closure_ty = *ty;
803-
}
804-
let upvar_substs = match closure_ty.kind() {
805-
ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
806-
ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
807-
_ => span_bug!(self.fn_span, "upvars with non-closure env ty {:?}", closure_ty),
808-
};
809-
let def_id = self.def_id.as_local().unwrap();
810-
let capture_syms = tcx.symbols_for_closure_captures((def_id, fn_def_id));
811-
let capture_tys = upvar_substs.upvar_tys();
812-
let captures_with_tys = hir_typeck_results
813-
.closure_min_captures_flattened(fn_def_id)
814-
.zip(capture_tys.zip(capture_syms));
815-
816-
self.upvars = captures_with_tys
817-
.enumerate()
818-
.map(|(i, (captured_place, (ty, sym)))| {
819-
let capture = captured_place.info.capture_kind;
820-
let var_id = match captured_place.place.base {
821-
HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
822-
_ => bug!("Expected an upvar"),
823-
};
824-
825-
let mutability = captured_place.mutability;
826-
827-
let mut projs = closure_env_projs.clone();
828-
projs.push(ProjectionElem::Field(Field::new(i), ty));
829-
match capture {
830-
ty::UpvarCapture::ByValue => {}
831-
ty::UpvarCapture::ByRef(..) => {
832-
projs.push(ProjectionElem::Deref);
833-
}
834-
};
835-
836-
let use_place = Place {
837-
local: ty::CAPTURE_STRUCT_LOCAL,
838-
projection: tcx.mk_place_elems(&projs),
839-
};
840-
self.var_debug_info.push(VarDebugInfo {
841-
name: *sym,
842-
source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
843-
value: VarDebugInfoContents::Place(use_place),
844-
});
845-
846-
let capture = Capture { captured_place, use_place, mutability };
847-
(var_id, capture)
848-
})
849-
.collect();
850-
}
846+
self.insert_upvar_arg();
851847

852848
let mut scope = None;
853849
// Bind the argument patterns

compiler/rustc_mir_build/src/thir/cx/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,9 @@ impl<'tcx> Cx<'tcx> {
541541
let def_id = def_id.expect_local();
542542

543543
let upvars = self
544-
.typeck_results
545-
.closure_min_captures_flattened(def_id)
544+
.tcx
545+
.closure_captures(def_id)
546+
.iter()
546547
.zip(substs.upvar_tys())
547548
.map(|(captured_place, ty)| {
548549
let upvars = self.capture_upvar(expr, captured_place, ty);

0 commit comments

Comments
 (0)