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