-use crate::thir::cx::to_ref::ToRef;
use crate::thir::cx::Cx;
use crate::thir::{self, *};
use rustc_index::vec::Idx;
-impl<'tcx> Mirror<'tcx> for &'tcx hir::Block<'tcx> {
- type Output = Block<'tcx>;
-
- fn make_mirror(self, cx: &mut Cx<'_, 'tcx>) -> Block<'tcx> {
+impl<'thir, 'tcx> Cx<'thir, 'tcx> {
+ crate fn mirror_block(&mut self, block: &'tcx hir::Block<'tcx>) -> Block<'thir, 'tcx> {
// We have to eagerly lower the "spine" of the statements
// in order to get the lexical scoping correctly.
- let stmts = mirror_stmts(cx, self.hir_id.local_id, &*self.stmts);
+ let stmts = self.mirror_stmts(block.hir_id.local_id, block.stmts);
let opt_destruction_scope =
- cx.region_scope_tree.opt_destruction_scope(self.hir_id.local_id);
+ self.region_scope_tree.opt_destruction_scope(block.hir_id.local_id);
Block {
- targeted_by_break: self.targeted_by_break,
- region_scope: region::Scope { id: self.hir_id.local_id, data: region::ScopeData::Node },
+ targeted_by_break: block.targeted_by_break,
+ region_scope: region::Scope {
+ id: block.hir_id.local_id,
+ data: region::ScopeData::Node,
+ },
opt_destruction_scope,
- span: self.span,
+ span: block.span,
stmts,
- expr: self.expr.to_ref(),
- safety_mode: match self.rules {
+ expr: block.expr.map(|expr| self.mirror_expr(expr)),
+ safety_mode: match block.rules {
hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe,
- hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(self.hir_id),
+ hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id),
hir::BlockCheckMode::PushUnsafeBlock(..) => BlockSafety::PushUnsafe,
hir::BlockCheckMode::PopUnsafeBlock(..) => BlockSafety::PopUnsafe,
},
}
}
-}
-fn mirror_stmts<'a, 'tcx>(
- cx: &mut Cx<'a, 'tcx>,
- block_id: hir::ItemLocalId,
- stmts: &'tcx [hir::Stmt<'tcx>],
-) -> Vec<StmtRef<'tcx>> {
- let mut result = vec![];
- for (index, stmt) in stmts.iter().enumerate() {
- let hir_id = stmt.hir_id;
- let opt_dxn_ext = cx.region_scope_tree.opt_destruction_scope(hir_id.local_id);
- match stmt.kind {
- hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => {
- result.push(StmtRef::Mirror(Box::new(Stmt {
+ fn mirror_stmts(
+ &mut self,
+ block_id: hir::ItemLocalId,
+ stmts: &'tcx [hir::Stmt<'tcx>],
+ ) -> &'thir [Stmt<'thir, 'tcx>] {
+ self.arena.alloc_from_iter(stmts.iter().enumerate().filter_map(|(index, stmt)| {
+ let hir_id = stmt.hir_id;
+ let opt_dxn_ext = self.region_scope_tree.opt_destruction_scope(hir_id.local_id);
+ match stmt.kind {
+ hir::StmtKind::Expr(ref expr) | hir::StmtKind::Semi(ref expr) => Some(Stmt {
kind: StmtKind::Expr {
scope: region::Scope { id: hir_id.local_id, data: region::ScopeData::Node },
- expr: expr.to_ref(),
+ expr: self.mirror_expr(expr),
},
opt_destruction_scope: opt_dxn_ext,
- })))
- }
- hir::StmtKind::Item(..) => {
- // ignore for purposes of the MIR
- }
- hir::StmtKind::Local(ref local) => {
- let remainder_scope = region::Scope {
- id: block_id,
- data: region::ScopeData::Remainder(region::FirstStatementIndex::new(index)),
- };
+ }),
+ hir::StmtKind::Item(..) => {
+ // ignore for purposes of the MIR
+ None
+ }
+ hir::StmtKind::Local(ref local) => {
+ let remainder_scope = region::Scope {
+ id: block_id,
+ data: region::ScopeData::Remainder(region::FirstStatementIndex::new(index)),
+ };
- let mut pattern = cx.pattern_from_hir(&local.pat);
+ let mut pattern = self.pattern_from_hir(local.pat);
- if let Some(ty) = &local.ty {
- if let Some(&user_ty) = cx.typeck_results.user_provided_types().get(ty.hir_id) {
- debug!("mirror_stmts: user_ty={:?}", user_ty);
- pattern = Pat {
- ty: pattern.ty,
- span: pattern.span,
- kind: Box::new(PatKind::AscribeUserType {
- ascription: thir::pattern::Ascription {
- user_ty: PatTyProj::from_user_type(user_ty),
- user_ty_span: ty.span,
- variance: ty::Variance::Covariant,
- },
- subpattern: pattern,
- }),
- };
+ if let Some(ty) = &local.ty {
+ if let Some(&user_ty) =
+ self.typeck_results.user_provided_types().get(ty.hir_id)
+ {
+ debug!("mirror_stmts: user_ty={:?}", user_ty);
+ pattern = Pat {
+ ty: pattern.ty,
+ span: pattern.span,
+ kind: Box::new(PatKind::AscribeUserType {
+ ascription: thir::pattern::Ascription {
+ user_ty: PatTyProj::from_user_type(user_ty),
+ user_ty_span: ty.span,
+ variance: ty::Variance::Covariant,
+ },
+ subpattern: pattern,
+ }),
+ };
+ }
}
- }
- result.push(StmtRef::Mirror(Box::new(Stmt {
- kind: StmtKind::Let {
- remainder_scope,
- init_scope: region::Scope {
- id: hir_id.local_id,
- data: region::ScopeData::Node,
+ Some(Stmt {
+ kind: StmtKind::Let {
+ remainder_scope,
+ init_scope: region::Scope {
+ id: hir_id.local_id,
+ data: region::ScopeData::Node,
+ },
+ pattern,
+ initializer: local.init.map(|init| self.mirror_expr(init)),
+ lint_level: LintLevel::Explicit(local.hir_id),
},
- pattern,
- initializer: local.init.to_ref(),
- lint_level: LintLevel::Explicit(local.hir_id),
- },
- opt_destruction_scope: opt_dxn_ext,
- })));
+ opt_destruction_scope: opt_dxn_ext,
+ })
+ }
}
- }
+ }))
}
- result
-}
-
-crate fn to_expr_ref<'a, 'tcx>(
- cx: &mut Cx<'a, 'tcx>,
- block: &'tcx hir::Block<'tcx>,
-) -> ExprRef<'tcx> {
- let block_ty = cx.typeck_results().node_type(block.hir_id);
- let temp_lifetime = cx.region_scope_tree.temporary_scope(block.hir_id.local_id);
- let expr = Expr {
- ty: block_ty,
- temp_lifetime,
- span: block.span,
- kind: ExprKind::Block { body: block },
- };
- expr.to_ref()
}