rustc_hir_typeck/
rvalue_scopes.rs
1use hir::Node;
2use hir::def_id::DefId;
3use rustc_hir as hir;
4use rustc_middle::bug;
5use rustc_middle::middle::region::{RvalueCandidate, Scope, ScopeTree};
6use rustc_middle::ty::RvalueScopes;
7use tracing::debug;
8
9use super::FnCtxt;
10
11fn record_rvalue_scope_rec(
29 rvalue_scopes: &mut RvalueScopes,
30 mut expr: &hir::Expr<'_>,
31 lifetime: Option<Scope>,
32) {
33 loop {
34 rvalue_scopes.record_rvalue_scope(expr.hir_id.local_id, lifetime);
41
42 match expr.kind {
43 hir::ExprKind::AddrOf(_, _, subexpr)
44 | hir::ExprKind::Unary(hir::UnOp::Deref, subexpr)
45 | hir::ExprKind::Field(subexpr, _)
46 | hir::ExprKind::Index(subexpr, _, _) => {
47 expr = subexpr;
48 }
49 _ => {
50 return;
51 }
52 }
53 }
54}
55fn record_rvalue_scope(
56 rvalue_scopes: &mut RvalueScopes,
57 expr: &hir::Expr<'_>,
58 candidate: &RvalueCandidate,
59) {
60 debug!("resolve_rvalue_scope(expr={expr:?}, candidate={candidate:?})");
61 record_rvalue_scope_rec(rvalue_scopes, expr, candidate.lifetime)
62 }
64
65pub(crate) fn resolve_rvalue_scopes<'a, 'tcx>(
66 fcx: &'a FnCtxt<'a, 'tcx>,
67 scope_tree: &'a ScopeTree,
68 def_id: DefId,
69) -> RvalueScopes {
70 let tcx = &fcx.tcx;
71 let mut rvalue_scopes = RvalueScopes::new();
72 debug!("start resolving rvalue scopes, def_id={def_id:?}");
73 debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
74 for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
75 let Node::Expr(expr) = tcx.hir_node(hir_id) else { bug!("hir node does not exist") };
76 record_rvalue_scope(&mut rvalue_scopes, expr, candidate);
77 }
78 rvalue_scopes
79}