@@ -1315,6 +1315,54 @@ impl<'tcx> LateContext<'tcx> {
13151315 tcx. try_normalize_erasing_regions ( self . param_env , proj) . ok ( )
13161316 } )
13171317 }
1318+
1319+ /// If the given expression is a local binding, find the initializer expression.
1320+ /// If that initializer expression is another local or **outside** (`const`/`static`)
1321+ /// binding, find its initializer again.
1322+ ///
1323+ /// This process repeats as long as possible (but usually no more than once).
1324+ /// Type-check adjustments are not taken in account in this function.
1325+ ///
1326+ /// Examples:
1327+ /// ```
1328+ /// const ABC: i32 = 1;
1329+ /// // ^ output
1330+ /// let def = ABC;
1331+ /// dbg!(def);
1332+ /// // ^^^ input
1333+ ///
1334+ /// // or...
1335+ /// let abc = 1;
1336+ /// let def = abc + 2;
1337+ /// // ^^^^^^^ output
1338+ /// dbg!(def);
1339+ /// // ^^^ input
1340+ /// ```
1341+ pub fn expr_or_init < ' a > ( & self , mut expr : & ' a hir:: Expr < ' tcx > ) -> & ' a hir:: Expr < ' tcx > {
1342+ expr = expr. peel_blocks ( ) ;
1343+
1344+ while let hir:: ExprKind :: Path ( ref qpath) = expr. kind
1345+ && let Some ( parent_node) = match self . qpath_res ( qpath, expr. hir_id ) {
1346+ Res :: Local ( hir_id) => self . tcx . hir ( ) . find_parent ( hir_id) ,
1347+ Res :: Def ( _, def_id) => self . tcx . hir ( ) . get_if_local ( def_id) ,
1348+ _ => None ,
1349+ }
1350+ && let Some ( init) = match parent_node {
1351+ hir:: Node :: Expr ( expr) => Some ( expr) ,
1352+ hir:: Node :: Local ( hir:: Local { init, .. } ) => * init,
1353+ hir:: Node :: Item ( item) => match item. kind {
1354+ hir:: ItemKind :: Const ( .., body_id) | hir:: ItemKind :: Static ( .., body_id) => {
1355+ Some ( self . tcx . hir ( ) . body ( body_id) . value )
1356+ }
1357+ _ => None
1358+ }
1359+ _ => None
1360+ }
1361+ {
1362+ expr = init. peel_blocks ( ) ;
1363+ }
1364+ expr
1365+ }
13181366}
13191367
13201368impl < ' tcx > abi:: HasDataLayout for LateContext < ' tcx > {
0 commit comments