Auto merge of #82951 - sexxi-goose:wr-mir-replace-methods2, r=nikomatsakis
Replace closures_captures and upvar_capture with closure_min_captures Removed all uses of closures_captures and upvar_capture and refactored code to work with closure_min_captures. This also involved removing functions that were no longer needed like the bridge. Closes https://github.com/rust-lang/project-rfc-2229/issues/18 r? `@nikomatsakis`
This commit is contained in:
commit
cebc8fef5f
14 changed files with 478 additions and 242 deletions
|
@ -388,10 +388,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// so it's safe to call `expect_local`.
|
||||
//
|
||||
// We know the field exists so it's safe to call operator[] and `unwrap` here.
|
||||
let (&var_id, _) =
|
||||
self.infcx.tcx.typeck(def_id.expect_local()).closure_captures[&def_id]
|
||||
.get_index(field.index())
|
||||
.unwrap();
|
||||
let var_id = self
|
||||
.infcx
|
||||
.tcx
|
||||
.typeck(def_id.expect_local())
|
||||
.closure_min_captures_flattened(def_id)
|
||||
.nth(field.index())
|
||||
.unwrap()
|
||||
.get_root_variable();
|
||||
|
||||
self.infcx.tcx.hir().name(var_id).to_string()
|
||||
}
|
||||
|
@ -966,12 +970,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let expr = &self.infcx.tcx.hir().expect_expr(hir_id).kind;
|
||||
debug!("closure_span: hir_id={:?} expr={:?}", hir_id, expr);
|
||||
if let hir::ExprKind::Closure(.., body_id, args_span, _) = expr {
|
||||
for (upvar_hir_id, place) in
|
||||
self.infcx.tcx.typeck(def_id.expect_local()).closure_captures[&def_id]
|
||||
.keys()
|
||||
.zip(places)
|
||||
for (captured_place, place) in self
|
||||
.infcx
|
||||
.tcx
|
||||
.typeck(def_id.expect_local())
|
||||
.closure_min_captures_flattened(def_id)
|
||||
.zip(places)
|
||||
{
|
||||
let span = self.infcx.tcx.upvars_mentioned(local_did)?[upvar_hir_id].span;
|
||||
let upvar_hir_id = captured_place.get_root_variable();
|
||||
//FIXME(project-rfc-2229#8): Use better span from captured_place
|
||||
let span = self.infcx.tcx.upvars_mentioned(local_did)?[&upvar_hir_id].span;
|
||||
match place {
|
||||
Operand::Copy(place) | Operand::Move(place)
|
||||
if target_place == place.as_ref() =>
|
||||
|
@ -979,10 +987,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
debug!("closure_span: found captured local {:?}", place);
|
||||
let body = self.infcx.tcx.hir().body(*body_id);
|
||||
let generator_kind = body.generator_kind();
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath { hir_id: *upvar_hir_id },
|
||||
closure_expr_id: local_did,
|
||||
};
|
||||
|
||||
// If we have a more specific span available, point to that.
|
||||
// We do this even though this span might be part of a borrow error
|
||||
|
@ -990,11 +994,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
// to a span that shows why the upvar is used in the closure,
|
||||
// so a move-related span is as good as any (and potentially better,
|
||||
// if the overall error is due to a move of the upvar).
|
||||
let usage_span =
|
||||
match self.infcx.tcx.typeck(local_did).upvar_capture(upvar_id) {
|
||||
ty::UpvarCapture::ByValue(Some(span)) => span,
|
||||
_ => span,
|
||||
};
|
||||
|
||||
let usage_span = match captured_place.info.capture_kind {
|
||||
ty::UpvarCapture::ByValue(Some(span)) => span,
|
||||
_ => span,
|
||||
};
|
||||
return Some((*args_span, generator_kind, usage_span));
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -510,24 +510,54 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
the_place_err: PlaceRef<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
) {
|
||||
let id = id.expect_local();
|
||||
let tables = tcx.typeck(id);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(id);
|
||||
if let Some((span, place)) = tables.closure_kind_origins().get(hir_id) {
|
||||
let reason = if let PlaceBase::Upvar(upvar_id) = place.base {
|
||||
let upvar = ty::place_to_string_for_capture(tcx, place);
|
||||
match tables.upvar_capture(upvar_id) {
|
||||
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
|
||||
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
|
||||
..
|
||||
}) => {
|
||||
format!("mutable borrow of `{}`", upvar)
|
||||
let closure_local_def_id = id.expect_local();
|
||||
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)) =
|
||||
&tables.closure_kind_origins().get(closure_hir_id)
|
||||
{
|
||||
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 root_hir_id = upvar_id.var_path.hir_id;
|
||||
// we have a origin for this closure kind starting at this root variable so it's safe to unwrap here
|
||||
let captured_places = tables.closure_min_captures[id].get(&root_hir_id).unwrap();
|
||||
|
||||
let origin_projection = closure_kind_origin
|
||||
.projections
|
||||
.iter()
|
||||
.map(|proj| proj.kind)
|
||||
.collect::<Vec<_>>();
|
||||
let mut capture_reason = String::new();
|
||||
for captured_place in captured_places {
|
||||
let captured_place_kinds = captured_place
|
||||
.place
|
||||
.projections
|
||||
.iter()
|
||||
.map(|proj| proj.kind)
|
||||
.collect::<Vec<_>>();
|
||||
if rustc_middle::ty::is_ancestor_or_same_capture(
|
||||
&captured_place_kinds,
|
||||
&origin_projection,
|
||||
) {
|
||||
match captured_place.info.capture_kind {
|
||||
ty::UpvarCapture::ByRef(ty::UpvarBorrow {
|
||||
kind: ty::BorrowKind::MutBorrow | ty::BorrowKind::UniqueImmBorrow,
|
||||
..
|
||||
}) => {
|
||||
capture_reason = format!("mutable borrow of `{}`", upvar);
|
||||
}
|
||||
ty::UpvarCapture::ByValue(_) => {
|
||||
capture_reason = format!("possible mutation of `{}`", upvar);
|
||||
}
|
||||
_ => bug!("upvar `{}` borrowed, but not mutably", upvar),
|
||||
}
|
||||
break;
|
||||
}
|
||||
ty::UpvarCapture::ByValue(_) => {
|
||||
format!("possible mutation of `{}`", upvar)
|
||||
}
|
||||
val => bug!("upvar `{}` borrowed, but not mutably: {:?}", upvar, val),
|
||||
}
|
||||
if capture_reason.is_empty() {
|
||||
bug!("upvar `{}` borrowed, but cannot find reason", upvar);
|
||||
}
|
||||
capture_reason
|
||||
} else {
|
||||
bug!("not an upvar")
|
||||
};
|
||||
|
|
|
@ -77,7 +77,7 @@ macro_rules! throw_validation_failure {
|
|||
///
|
||||
macro_rules! try_validation {
|
||||
($e:expr, $where:expr,
|
||||
$( $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)?
|
||||
$( $( $p:pat )|+ => { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )? ),+ $(,)?
|
||||
) => {{
|
||||
match $e {
|
||||
Ok(x) => x,
|
||||
|
@ -244,17 +244,20 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
// generators and closures.
|
||||
ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
|
||||
let mut name = None;
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
let tables = self.ecx.tcx.typeck(def_id);
|
||||
if let Some(upvars) = tables.closure_captures.get(&def_id.to_def_id()) {
|
||||
// FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar
|
||||
// https://github.com/rust-lang/project-rfc-2229/issues/46
|
||||
if let Some(local_def_id) = def_id.as_local() {
|
||||
let tables = self.ecx.tcx.typeck(local_def_id);
|
||||
if let Some(captured_place) =
|
||||
tables.closure_min_captures_flattened(*def_id).nth(field)
|
||||
{
|
||||
// Sometimes the index is beyond the number of upvars (seen
|
||||
// for a generator).
|
||||
if let Some((&var_hir_id, _)) = upvars.get_index(field) {
|
||||
let node = self.ecx.tcx.hir().get(var_hir_id);
|
||||
if let hir::Node::Binding(pat) = node {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
|
||||
name = Some(ident.name);
|
||||
}
|
||||
let var_hir_id = captured_place.get_root_variable();
|
||||
let node = self.ecx.tcx.hir().get(var_hir_id);
|
||||
if let hir::Node::Binding(pat) = node {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
|
||||
name = Some(ident.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue