summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_build/src/build
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_build/src/build')
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs20
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_operand.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs15
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs12
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs11
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs196
11 files changed, 139 insertions, 141 deletions
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 0bca02589..dbba529ae 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -18,6 +18,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
@call("mir_storage_dead", args) => {
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
},
+ @call("mir_deinit", args) => {
+ Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
+ },
@call("mir_retag", args) => {
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
},
@@ -141,12 +144,29 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
parse_by_kind!(self, expr_id, _, "rvalue",
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
+ @call("mir_checked", args) => {
+ parse_by_kind!(self, args[0], _, "binary op",
+ ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
+ *op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
+ )),
+ )
+ },
+ @call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
ExprKind::Borrow { borrow_kind, arg } => Ok(
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
),
ExprKind::AddressOf { mutability, arg } => Ok(
Rvalue::AddressOf(*mutability, self.parse_place(*arg)?)
),
+ ExprKind::Binary { op, lhs, rhs } => Ok(
+ Rvalue::BinaryOp(*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?)))
+ ),
+ ExprKind::Unary { op, arg } => Ok(
+ Rvalue::UnaryOp(*op, self.parse_operand(*arg)?)
+ ),
+ ExprKind::Repeat { value, count } => Ok(
+ Rvalue::Repeat(self.parse_operand(*value)?, *count)
+ ),
_ => self.parse_operand(expr_id).map(Rvalue::Use),
)
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 1d96893c7..cfacb5ea3 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -55,7 +55,7 @@ pub fn as_constant_inner<'tcx>(
ConstantKind::Ty(tcx.const_error_with_guaranteed(ty, guar))
}
Err(LitToConstError::TypeError) => {
- bug!("encountered type error in `lit_to_mir_constant")
+ bug!("encountered type error in `lit_to_mir_constant`")
}
};
@@ -132,14 +132,14 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
let s = s.as_str();
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
- let allocation = tcx.intern_const_alloc(allocation);
+ let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: s.len() }
}
(ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _))
if matches!(inner_ty.kind(), ty::Slice(_)) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
- let allocation = tcx.intern_const_alloc(allocation);
+ let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: data.len() }
}
(ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
index c621efb3b..ff3198847 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs
@@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Return the operand *tmp0 to be used as the call argument
let place = Place {
local: operand,
- projection: tcx.intern_place_elems(&[PlaceElem::Deref]),
+ projection: tcx.mk_place_elems(&[PlaceElem::Deref]),
};
return block.and(Operand::Move(place));
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index e22fa6365..33200b80a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::AssertKind::BoundsCheck;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::AdtDef;
-use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance};
+use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance};
use rustc_span::Span;
use rustc_target::abi::VariantIdx;
@@ -183,7 +183,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
&projection,
) else {
let closure_span = cx.tcx.def_span(closure_def_id);
- if !enable_precise_capture(cx.tcx, closure_span) {
+ if !enable_precise_capture(closure_span) {
bug!(
"No associated capture found for {:?}[{:#?}] even though \
capture_disjoint_fields isn't enabled",
@@ -263,7 +263,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
let resolved = self.resolve_upvar(cx);
let builder = resolved.as_ref().unwrap_or(self);
let PlaceBase::Local(local) = builder.base else { return None };
- let projection = cx.tcx.intern_place_elems(&builder.projection);
+ let projection = cx.tcx.mk_place_elems(&builder.projection);
Some(Place { local, projection })
}
@@ -692,7 +692,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
let fake_borrow_temp =
self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span));
- let projection = tcx.intern_place_elems(&base_place.projection[..idx]);
+ let projection = tcx.mk_place_elems(&base_place.projection[..idx]);
self.cfg.push_assign(
block,
source_info,
@@ -745,8 +745,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
-/// Precise capture is enabled if the feature gate `capture_disjoint_fields` is enabled or if
-/// user is using Rust Edition 2021 or higher.
-fn enable_precise_capture(tcx: TyCtxt<'_>, closure_span: Span) -> bool {
- tcx.features().capture_disjoint_fields || closure_span.rust_2021()
+/// Precise capture is enabled if user is using Rust Edition 2021 or higher.
+fn enable_precise_capture(closure_span: Span) -> bool {
+ closure_span.rust_2021()
}
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index c7b3eb44d..a4e48c154 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -55,7 +55,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
})
}
ExprKind::Repeat { value, count } => {
- if Some(0) == count.try_eval_usize(this.tcx, this.param_env) {
+ if Some(0) == count.try_eval_target_usize(this.tcx, this.param_env) {
this.build_zero_repeat(block, value, scope, source_info)
} else {
let value_operand = unpack!(
@@ -439,10 +439,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// We implicitly set the discriminant to 0. See
// librustc_mir/transform/deaggregator.rs for details.
let movability = movability.unwrap();
- Box::new(AggregateKind::Generator(closure_id, substs, movability))
+ Box::new(AggregateKind::Generator(
+ closure_id.to_def_id(),
+ substs,
+ movability,
+ ))
}
UpvarSubsts::Closure(substs) => {
- Box::new(AggregateKind::Closure(closure_id, substs))
+ Box::new(AggregateKind::Closure(closure_id.to_def_id(), substs))
}
};
block.and(Rvalue::Aggregate(result, operands))
@@ -516,7 +520,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let source_info = self.source_info(span);
let bool_ty = self.tcx.types.bool;
if self.check_overflow && op.is_checkable() && ty.is_integral() {
- let result_tup = self.tcx.intern_tup(&[ty, bool_ty]);
+ let result_tup = self.tcx.mk_tup(&[ty, bool_ty]);
let result_value = self.temp(result_tup, span);
self.cfg.push_assign(
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index 0ca4e3745..3d3cf7555 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -44,7 +44,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let expr_ty = expr.ty;
let temp = {
let mut local_decl = LocalDecl::new(expr_ty, expr_span);
- if mutability == Mutability::Not {
+ if mutability.is_not() {
local_decl = local_decl.immutable();
}
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 38b1fa91d..dac9bf0a8 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -319,7 +319,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// See the notes for `ExprKind::Array` in `as_rvalue` and for
// `ExprKind::Borrow` above.
let is_union = adt_def.is_union();
- let active_field_index = if is_union { Some(fields[0].name.index()) } else { None };
+ let active_field_index = is_union.then(|| fields[0].name.index());
let scope = this.local_scope();
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 0961ce11e..de2851a1a 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -1206,7 +1206,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fake_borrows.insert(Place {
local: source.local,
- projection: self.tcx.intern_place_elems(proj_base),
+ projection: self.tcx.mk_place_elems(proj_base),
});
}
}
@@ -1743,12 +1743,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.map(|matched_place_ref| {
let matched_place = Place {
local: matched_place_ref.local,
- projection: tcx.intern_place_elems(matched_place_ref.projection),
+ projection: tcx.mk_place_elems(matched_place_ref.projection),
};
let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty;
let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
- let fake_borrow_temp =
- self.local_decls.push(LocalDecl::new(fake_borrow_ty, temp_span));
+ let mut fake_borrow_temp = LocalDecl::new(fake_borrow_ty, temp_span);
+ fake_borrow_temp.internal = self.local_decls[matched_place.local].internal;
+ fake_borrow_temp.local_info = Some(Box::new(LocalInfo::FakeBorrow));
+ let fake_borrow_temp = self.local_decls.push(fake_borrow_temp);
(matched_place, fake_borrow_temp)
})
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index ad7a568a2..2de89f67d 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -563,14 +563,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let not_contained =
self.values_not_contained_in_range(&*range, options).unwrap_or(false);
- if not_contained {
+ not_contained.then(|| {
// No switch values are contained in the pattern range,
// so the pattern can be matched only if this test fails.
- let otherwise = options.len();
- Some(otherwise)
- } else {
- None
- }
+ options.len()
+ })
}
(&TestKind::SwitchInt { .. }, _) => None,
@@ -835,7 +832,7 @@ fn trait_method<'tcx>(
tcx: TyCtxt<'tcx>,
trait_def_id: DefId,
method_name: Symbol,
- substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,
+ substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
) -> ConstantKind<'tcx> {
// The unhygienic comparison here is acceptable because this is only
// used on known traits.
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index cbd494862..c34105174 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -5,7 +5,7 @@ use crate::build::Builder;
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty;
-use rustc_middle::ty::TypeVisitable;
+use rustc_middle::ty::TypeVisitableExt;
use smallvec::SmallVec;
impl<'a, 'tcx> Builder<'a, 'tcx> {
@@ -35,7 +35,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let tcx = self.tcx;
let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) {
match place_resolved.ty(&self.local_decls, tcx).ty.kind() {
- ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
+ ty::Array(_, length) => (length.eval_target_usize(tcx, self.param_env), true),
_ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
}
} else {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 9daf68a15..b3f9d8282 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -20,7 +20,7 @@ use rustc_middle::mir::*;
use rustc_middle::thir::{
self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir,
};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_span::Symbol;
@@ -47,8 +47,6 @@ pub(crate) fn mir_built(
/// Construct the MIR for a given `DefId`.
fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> {
- let body_owner_kind = tcx.hir().body_owner_kind(def.did);
-
// Ensure unsafeck and abstract const building is ran before we steal the THIR.
// We can't use `ensure()` for `thir_abstract_const` as it doesn't compute the query
// if inputs are green. This can cause ICEs when calling `thir_abstract_const` after
@@ -65,16 +63,15 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_
}
let body = match tcx.thir_body(def) {
- Err(error_reported) => construct_error(tcx, def.did, body_owner_kind, error_reported),
+ Err(error_reported) => construct_error(tcx, def.did, error_reported),
Ok((thir, expr)) => {
// We ran all queries that depended on THIR at the beginning
// of `mir_build`, so now we can steal it
let thir = thir.steal();
- if body_owner_kind.is_fn_or_closure() {
- construct_fn(tcx, def, &thir, expr)
- } else {
- construct_const(tcx, def, &thir, expr)
+ match thir.body_type {
+ thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, &thir, expr, fn_sig),
+ thir::BodyTy::Const(ty) => construct_const(tcx, def, &thir, expr, ty),
}
}
};
@@ -158,13 +155,13 @@ struct BlockContext(Vec<BlockFrame>);
struct Builder<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
infcx: InferCtxt<'tcx>,
- typeck_results: &'tcx TypeckResults<'tcx>,
region_scope_tree: &'tcx region::ScopeTree,
param_env: ty::ParamEnv<'tcx>,
thir: &'a Thir<'tcx>,
cfg: CFG<'tcx>,
+ def: ty::WithOptConstParam<LocalDefId>,
def_id: DefId,
hir_id: hir::HirId,
parent_module: DefId,
@@ -434,11 +431,16 @@ fn construct_fn<'tcx>(
fn_def: ty::WithOptConstParam<LocalDefId>,
thir: &Thir<'tcx>,
expr: ExprId,
+ fn_sig: ty::FnSig<'tcx>,
) -> Body<'tcx> {
let span = tcx.def_span(fn_def.did);
let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did);
let generator_kind = tcx.generator_kind(fn_def.did);
+ // The representation of thir for `-Zunpretty=thir-tree` relies on
+ // the entry expression being the last element of `thir.exprs`.
+ assert_eq!(expr.as_usize(), thir.exprs.len() - 1);
+
// Figure out what primary body this item has.
let body_id = tcx.hir().body_owned_by(fn_def.did);
let span_with_body = tcx.hir().span_with_body(fn_id);
@@ -449,11 +451,6 @@ fn construct_fn<'tcx>(
.output
.span();
- // fetch the fully liberated fn signature (that is, all bound
- // types/lifetimes replaced)
- let typeck_results = tcx.typeck_opt_const_arg(fn_def);
- let fn_sig = typeck_results.liberated_fn_sigs()[fn_id];
-
let safety = match fn_sig.unsafety {
hir::Unsafety::Normal => Safety::Safe,
hir::Unsafety::Unsafe => Safety::FnUnsafe,
@@ -525,13 +522,7 @@ fn construct_fn<'tcx>(
let return_block =
unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| {
Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
- builder.args_and_body(
- START_BLOCK,
- fn_def.did,
- arguments,
- arg_scope,
- &thir[expr],
- )
+ builder.args_and_body(START_BLOCK, arguments, arg_scope, &thir[expr])
}))
}));
let source_info = builder.source_info(fn_end);
@@ -559,6 +550,7 @@ fn construct_const<'a, 'tcx>(
def: ty::WithOptConstParam<LocalDefId>,
thir: &'a Thir<'tcx>,
expr: ExprId,
+ const_ty: Ty<'tcx>,
) -> Body<'tcx> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
@@ -582,20 +574,6 @@ fn construct_const<'a, 'tcx>(
_ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did),
};
- // Get the revealed type of this const. This is *not* the adjusted
- // type of its body, which may be a subtype of this type. For
- // example:
- //
- // fn foo(_: &()) {}
- // static X: fn(&'static ()) = foo;
- //
- // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
- // is not the same as the type of X. We need the type of the return
- // place to be the type of the constant because NLL typeck will
- // equate them.
- let typeck_results = tcx.typeck_opt_const_arg(def);
- let const_ty = typeck_results.node_type(hir_id);
-
let infcx = tcx.infer_ctxt().build();
let mut builder = Builder::new(
thir,
@@ -625,21 +603,17 @@ fn construct_const<'a, 'tcx>(
///
/// This is required because we may still want to run MIR passes on an item
/// with type errors, but normal MIR construction can't handle that in general.
-fn construct_error(
- tcx: TyCtxt<'_>,
- def: LocalDefId,
- body_owner_kind: hir::BodyOwnerKind,
- err: ErrorGuaranteed,
-) -> Body<'_> {
+fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Body<'_> {
let span = tcx.def_span(def);
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
let generator_kind = tcx.generator_kind(def);
+ let body_owner_kind = tcx.hir().body_owner_kind(def);
- let ty = tcx.ty_error();
+ let ty = tcx.ty_error(err);
let num_params = match body_owner_kind {
- hir::BodyOwnerKind::Fn => tcx.fn_sig(def).inputs().skip_binder().len(),
+ hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(),
hir::BodyOwnerKind::Closure => {
- let ty = tcx.type_of(def);
+ let ty = tcx.type_of(def).subst_identity();
match ty.kind() {
ty::Closure(_, substs) => {
1 + substs.as_closure().sig().inputs().skip_binder().len()
@@ -724,9 +698,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
thir,
tcx,
infcx,
- typeck_results: tcx.typeck_opt_const_arg(def),
region_scope_tree: tcx.region_scope_tree(def.did),
param_env,
+ def,
def_id: def.did.to_def_id(),
hir_id,
parent_module: tcx.parent_module(hir_id).to_def_id(),
@@ -776,14 +750,78 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.var_debug_info,
self.fn_span,
self.generator_kind,
- self.typeck_results.tainted_by_errors,
+ None,
)
}
+ fn insert_upvar_arg(&mut self) {
+ let Some(closure_arg) = self.local_decls.get(ty::CAPTURE_STRUCT_LOCAL) else { return };
+
+ let mut closure_ty = closure_arg.ty;
+ let mut closure_env_projs = vec![];
+ if let ty::Ref(_, ty, _) = closure_ty.kind() {
+ closure_env_projs.push(ProjectionElem::Deref);
+ closure_ty = *ty;
+ }
+
+ let upvar_substs = match closure_ty.kind() {
+ ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
+ ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
+ _ => return,
+ };
+
+ // In analyze_closure() in upvar.rs we gathered a list of upvars used by an
+ // indexed closure and we stored in a map called closure_min_captures in TypeckResults
+ // with the closure's DefId. Here, we run through that vec of UpvarIds for
+ // the given closure and use the necessary information to create upvar
+ // debuginfo and to fill `self.upvars`.
+ let capture_tys = upvar_substs.upvar_tys();
+
+ let tcx = self.tcx;
+ self.upvars = tcx
+ .closure_captures(self.def.did)
+ .iter()
+ .zip(capture_tys)
+ .enumerate()
+ .map(|(i, (captured_place, ty))| {
+ let name = captured_place.to_symbol();
+
+ let capture = captured_place.info.capture_kind;
+ let var_id = match captured_place.place.base {
+ HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
+ _ => bug!("Expected an upvar"),
+ };
+
+ let mutability = captured_place.mutability;
+
+ let mut projs = closure_env_projs.clone();
+ projs.push(ProjectionElem::Field(Field::new(i), ty));
+ match capture {
+ ty::UpvarCapture::ByValue => {}
+ ty::UpvarCapture::ByRef(..) => {
+ projs.push(ProjectionElem::Deref);
+ }
+ };
+
+ let use_place = Place {
+ local: ty::CAPTURE_STRUCT_LOCAL,
+ projection: tcx.mk_place_elems(&projs),
+ };
+ self.var_debug_info.push(VarDebugInfo {
+ name,
+ source_info: SourceInfo::outermost(captured_place.var_ident.span),
+ value: VarDebugInfoContents::Place(use_place),
+ });
+
+ let capture = Capture { captured_place, use_place, mutability };
+ (var_id, capture)
+ })
+ .collect();
+ }
+
fn args_and_body(
&mut self,
mut block: BasicBlock,
- fn_def_id: LocalDefId,
arguments: &IndexVec<ParamId, Param<'tcx>>,
argument_scope: region::Scope,
expr: &Expr<'tcx>,
@@ -805,69 +843,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
- let tcx = self.tcx;
- let tcx_hir = tcx.hir();
- let hir_typeck_results = self.typeck_results;
-
- // In analyze_closure() in upvar.rs we gathered a list of upvars used by an
- // indexed closure and we stored in a map called closure_min_captures in TypeckResults
- // with the closure's DefId. Here, we run through that vec of UpvarIds for
- // the given closure and use the necessary information to create upvar
- // debuginfo and to fill `self.upvars`.
- if hir_typeck_results.closure_min_captures.get(&fn_def_id).is_some() {
- let mut closure_env_projs = vec![];
- let mut closure_ty = self.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
- if let ty::Ref(_, ty, _) = closure_ty.kind() {
- closure_env_projs.push(ProjectionElem::Deref);
- closure_ty = *ty;
- }
- let upvar_substs = match closure_ty.kind() {
- ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs),
- ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs),
- _ => span_bug!(self.fn_span, "upvars with non-closure env ty {:?}", closure_ty),
- };
- let def_id = self.def_id.as_local().unwrap();
- let capture_syms = tcx.symbols_for_closure_captures((def_id, fn_def_id));
- let capture_tys = upvar_substs.upvar_tys();
- let captures_with_tys = hir_typeck_results
- .closure_min_captures_flattened(fn_def_id)
- .zip(capture_tys.zip(capture_syms));
-
- self.upvars = captures_with_tys
- .enumerate()
- .map(|(i, (captured_place, (ty, sym)))| {
- let capture = captured_place.info.capture_kind;
- let var_id = match captured_place.place.base {
- HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id,
- _ => bug!("Expected an upvar"),
- };
-
- let mutability = captured_place.mutability;
-
- let mut projs = closure_env_projs.clone();
- projs.push(ProjectionElem::Field(Field::new(i), ty));
- match capture {
- ty::UpvarCapture::ByValue => {}
- ty::UpvarCapture::ByRef(..) => {
- projs.push(ProjectionElem::Deref);
- }
- };
-
- let use_place = Place {
- local: ty::CAPTURE_STRUCT_LOCAL,
- projection: tcx.intern_place_elems(&projs),
- };
- self.var_debug_info.push(VarDebugInfo {
- name: *sym,
- source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
- value: VarDebugInfoContents::Place(use_place),
- });
-
- let capture = Capture { captured_place, use_place, mutability };
- (var_id, capture)
- })
- .collect();
- }
+ self.insert_upvar_arg();
let mut scope = None;
// Bind the argument patterns