pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        def_id: DefId,
                                        substs: Option<&'tcx Substs<'tcx>>)
                                        -> Option<(&'tcx Expr,
                                                   Option<&'a ty::TypeckTables<'tcx>>,
                                                   Option<ty::Ty<'tcx>>)> {
    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
        match tcx.hir.find(node_id) {
            None => None,
            Some(hir_map::NodeItem(&hir::Item {
                node: hir::ItemConst(ref ty, body), ..
            })) |
            Some(hir_map::NodeImplItem(&hir::ImplItem {
                node: hir::ImplItemKind::Const(ref ty, body), ..
            })) => {
                Some((&tcx.hir.body(body).value,
                      tcx.tables.borrow().get(&def_id).cloned(),
                      tcx.ast_ty_to_prim_ty(ty)))
            }
            Some(hir_map::NodeTraitItem(ti)) => match ti.node {
                hir::TraitItemKind::Const(ref ty, default) => {
                    if let Some(substs) = substs {
                        // If we have a trait item and the substitutions for it,
                        // `resolve_trait_associated_const` will select an impl
                        // or the default.
                        let trait_id = tcx.hir.get_parent(node_id);
                        let trait_id = tcx.hir.local_def_id(trait_id);
                        let default_value = default.map(|body| {
                            (&tcx.hir.body(body).value,
                             tcx.tables.borrow().get(&def_id).cloned(),
                             tcx.ast_ty_to_prim_ty(ty))
                        });
                        resolve_trait_associated_const(tcx, def_id, default_value, trait_id, substs)
                    } else {
                        // Technically, without knowing anything about the
                        // expression that generates the obligation, we could
                        // still return the default if there is one. However,
                        // it's safer to return `None` than to return some value
                        // that may differ from what you would get from
                        // correctly selecting an impl.
                        None
                    }
                }
                _ => None
            },
            Some(_) => None
        }
    } else {
        let expr_tables_ty = tcx.sess.cstore.maybe_get_item_body(tcx, def_id).map(|body| {
            (&body.value, Some(tcx.item_tables(def_id)),
             Some(tcx.sess.cstore.item_type(tcx, def_id)))
        });
        match tcx.sess.cstore.describe_def(def_id) {
            Some(Def::AssociatedConst(_)) => {
                let trait_id = tcx.sess.cstore.trait_of_item(def_id);
                // As mentioned in the comments above for in-crate
                // constants, we only try to find the expression for a
                // trait-associated const if the caller gives us the
                // substitutions for the reference to it.
                if let Some(trait_id) = trait_id {
                    if let Some(substs) = substs {
                        resolve_trait_associated_const(tcx, def_id, expr_tables_ty,
                                                       trait_id, substs)
                    } else {
                        None
                    }
                } else {
                    expr_tables_ty
                }
            },
            Some(Def::Const(..)) => expr_tables_ty,
            _ => None
        }
    }
}
/// * `def_id` is the id of the constant.
/// * `substs` is the monomorphized substitutions for the expression.
///
/// `substs` is optional and is used for associated constants.
/// This generally happens in late/trans const evaluation.
`def_id` is the id of the constant.
`substs` is the monomorphized substitutions for the expression.

`substs` is optional and is used for associated constants.
This generally happens in late/trans const evaluation.
` def_id ` is the id of the constant . ` substs ` is the monomorphized substitutions for the expression . ` substs ` is optional and is used for associated constants . This generally happens in late / trans const evaluation .
pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        def_id: DefId,
                                        substs: Option<&'tcx Substs<'tcx>>)
                                        -> Option<(&'tcx Expr,
                                                   Option<&'a ty::TypeckTables<'tcx>>,
                                                   Option<ty::Ty<'tcx>>)> {
    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
        match tcx.hir.find(node_id) {
            None => None,
            Some(hir_map::NodeItem(&hir::Item {
                node: hir::ItemConst(ref ty, body), ..
            })) |
            Some(hir_map::NodeImplItem(&hir::ImplItem {
                node: hir::ImplItemKind::Const(ref ty, body), ..
            })) => {
                Some((&tcx.hir.body(body).value,
                      tcx.tables.borrow().get(&def_id).cloned(),
                      tcx.ast_ty_to_prim_ty(ty)))
            }
            Some(hir_map::NodeTraitItem(ti)) => match ti.node {
                hir::TraitItemKind::Const(ref ty, default) => {
                    if let Some(substs) = substs {
                        // If we have a trait item and the substitutions for it,
                        // `resolve_trait_associated_const` will select an impl
                        // or the default.
                        let trait_id = tcx.hir.get_parent(node_id);
                        let trait_id = tcx.hir.local_def_id(trait_id);
                        let default_value = default.map(|body| {
                            (&tcx.hir.body(body).value,
                             tcx.tables.borrow().get(&def_id).cloned(),
                             tcx.ast_ty_to_prim_ty(ty))
                        });
                        resolve_trait_associated_const(tcx, def_id, default_value, trait_id, substs)
                    } else {
                        // Technically, without knowing anything about the
                        // expression that generates the obligation, we could
                        // still return the default if there is one. However,
                        // it's safer to return `None` than to return some value
                        // that may differ from what you would get from
                        // correctly selecting an impl.
                        None
                    }
                }
                _ => None
            },
            Some(_) => None
        }
    } else {
        let expr_tables_ty = tcx.sess.cstore.maybe_get_item_body(tcx, def_id).map(|body| {
            (&body.value, Some(tcx.item_tables(def_id)),
             Some(tcx.sess.cstore.item_type(tcx, def_id)))
        });
        match tcx.sess.cstore.describe_def(def_id) {
            Some(Def::AssociatedConst(_)) => {
                let trait_id = tcx.sess.cstore.trait_of_item(def_id);
                // As mentioned in the comments above for in-crate
                // constants, we only try to find the expression for a
                // trait-associated const if the caller gives us the
                // substitutions for the reference to it.
                if let Some(trait_id) = trait_id {
                    if let Some(substs) = substs {
                        resolve_trait_associated_const(tcx, def_id, expr_tables_ty,
                                                       trait_id, substs)
                    } else {
                        None
                    }
                } else {
                    expr_tables_ty
                }
            },
            Some(Def::Const(..)) => expr_tables_ty,
            _ => None
        }
    }
}
pub fn lookup_const_by_id < ' a , ' tcx : ' a > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId , substs : Option < & ' tcx Substs < ' tcx > > ) -> Option < ( & ' tcx Expr , Option < & ' a ty :: TypeckTables < ' tcx > > , Option < ty :: Ty < ' tcx > > ) > { if let Some ( node_id ) = tcx . hir . as_local_node_id ( def_id ) { match tcx . hir . find ( node_id ) { None => None , Some ( hir_map :: NodeItem ( & hir :: Item { node : hir :: ItemConst ( ref ty , body ) , .. } ) ) | Some ( hir_map :: NodeImplItem ( & hir :: ImplItem { node : hir :: ImplItemKind :: Const ( ref ty , body ) , .. } ) ) => { Some ( ( & tcx . hir . body ( body ) . value , tcx . tables . borrow ( ) . get ( & def_id ) . cloned ( ) , tcx . ast_ty_to_prim_ty ( ty ) ) ) } Some ( hir_map :: NodeTraitItem ( ti ) ) => match ti . node { hir :: TraitItemKind :: Const ( ref ty , default ) => { if let Some ( substs ) = substs { // If we have a trait item and the substitutions for it, // `resolve_trait_associated_const` will select an impl // or the default. let trait_id = tcx . hir . get_parent ( node_id ) ; let trait_id = tcx . hir . local_def_id ( trait_id ) ; let default_value = default . map ( | body | { ( & tcx . hir . body ( body ) . value , tcx . tables . borrow ( ) . get ( & def_id ) . cloned ( ) , tcx . ast_ty_to_prim_ty ( ty ) ) } ) ; resolve_trait_associated_const ( tcx , def_id , default_value , trait_id , substs ) } else { // Technically, without knowing anything about the // expression that generates the obligation, we could // still return the default if there is one. However, // it's safer to return `None` than to return some value // that may differ from what you would get from // correctly selecting an impl. None } } _ => None } , Some ( _ ) => None } } else { let expr_tables_ty = tcx . sess . cstore . maybe_get_item_body ( tcx , def_id ) . map ( | body | { ( & body . value , Some ( tcx . item_tables ( def_id ) ) , Some ( tcx . sess . cstore . item_type ( tcx , def_id ) ) ) } ) ; match tcx . sess . cstore . describe_def ( def_id ) { Some ( Def :: AssociatedConst ( _ ) ) => { let trait_id = tcx . sess . cstore . trait_of_item ( def_id ) ; // As mentioned in the comments above for in-crate // constants, we only try to find the expression for a // trait-associated const if the caller gives us the // substitutions for the reference to it. if let Some ( trait_id ) = trait_id { if let Some ( substs ) = substs { resolve_trait_associated_const ( tcx , def_id , expr_tables_ty , trait_id , substs ) } else { None } } else { expr_tables_ty } } , Some ( Def :: Const ( .. ) ) => expr_tables_ty , _ => None } } }
`def_id` is the id of the constant.
` def_id ` is the id of the constant .
tcx
TyCtxt<'a, 'tcx, 'tcx>
def_id
DefId
substs
Option<&'tcx Substs<'tcx>>