2 use hir::def_id::DefId;
5 use rustc_middle::middle::region::{RvalueCandidateType, Scope, ScopeTree};
6 use rustc_middle::ty::RvalueScopes;
8 /// Applied to an expression `expr` if `expr` -- or something owned or partially owned by
9 /// `expr` -- is going to be indirectly referenced by a variable in a let statement. In that
10 /// case, the "temporary lifetime" or `expr` is extended to be the block enclosing the `let`
13 /// More formally, if `expr` matches the grammar `ET`, record the rvalue scope of the matching
14 /// `<rvalue>` as `blk_id`:
24 /// Note: ET is intended to match "rvalues or places based on rvalues".
25 fn record_rvalue_scope_rec(
26 rvalue_scopes: &mut RvalueScopes,
27 mut expr: &hir::Expr<'_>,
28 lifetime: Option<Scope>,
31 // Note: give all the expressions matching `ET` with the
32 // extended temporary lifetime, not just the innermost rvalue,
33 // because in codegen if we must compile e.g., `*rvalue()`
34 // into a temporary, we request the temporary scope of the
37 rvalue_scopes.record_rvalue_scope(expr.hir_id.local_id, lifetime);
40 hir::ExprKind::AddrOf(_, _, subexpr)
41 | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
42 | hir::ExprKind::Field(subexpr, _)
43 | hir::ExprKind::Index(subexpr, _) => {
52 fn record_rvalue_scope(
53 rvalue_scopes: &mut RvalueScopes,
55 candidate: &RvalueCandidateType,
57 debug!("resolve_rvalue_scope(expr={expr:?}, candidate={candidate:?})");
59 RvalueCandidateType::Borrow { lifetime, .. }
60 | RvalueCandidateType::Pattern { lifetime, .. } => {
61 record_rvalue_scope_rec(rvalue_scopes, expr, *lifetime)
62 } // FIXME(@dingxiangfei2009): handle the candidates in the function call arguments
66 pub fn resolve_rvalue_scopes<'a, 'tcx>(
67 fcx: &'a FnCtxt<'a, 'tcx>,
68 scope_tree: &'a ScopeTree,
72 let hir_map = tcx.hir();
73 let mut rvalue_scopes = RvalueScopes::new();
74 debug!("start resolving rvalue scopes, def_id={def_id:?}");
75 debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
76 for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
77 let Some(Node::Expr(expr)) = hir_map.find(hir_id) else {
78 bug!("hir node does not exist")
80 record_rvalue_scope(&mut rvalue_scopes, expr, candidate);