]> git.lizzy.rs Git - rust.git/commitdiff
const_eval: Take just one set of substitutions in lookup_const_by_id.
authorEduard Burtescu <edy.burt@gmail.com>
Thu, 10 Mar 2016 00:04:55 +0000 (02:04 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Thu, 17 Mar 2016 20:48:07 +0000 (22:48 +0200)
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc_mir/hair/cx/expr.rs
src/librustc_mir/hair/cx/pattern.rs
src/librustc_passes/consts.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/mir/constant.rs
src/librustdoc/clean/inline.rs

index 89b57e0d90a007031169310e143c2d72d4c0bc6b..16e0a334440ff0f3570e2bde57c64eb69aebbe4b 100644 (file)
@@ -475,9 +475,9 @@ fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
                 let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
                 match def {
                     Some(Def::AssociatedConst(did)) |
-                    Some(Def::Const(did)) => match lookup_const_by_id(self.tcx, did,
-                                                                    Some(pat.id), None) {
-                        Some((const_expr, _const_ty)) => {
+                    Some(Def::Const(did)) => {
+                        let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
+                        if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
                             const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
 
                                 if let Some(ref mut renaming_map) = self.renaming_map {
@@ -487,14 +487,13 @@ fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
 
                                 new_pat
                             })
-                        }
-                        None => {
+                        } else {
                             self.failed = true;
                             span_err!(self.tcx.sess, pat.span, E0158,
                                 "statics cannot be referenced in patterns");
                             pat
                         }
-                    },
+                    }
                     _ => noop_fold_pat(pat, self)
                 }
             }
index 5d4226fe4ceaf43be30373a75a03a30e3bcb7482..47b6c49fddb6d69d5b0ad87876aea789d0c8f767 100644 (file)
@@ -19,7 +19,6 @@
 use middle::cstore::{self, CrateStore, InlinedItem};
 use middle::{infer, subst, traits};
 use middle::def::Def;
-use middle::subst::Subst;
 use middle::def_id::DefId;
 use middle::pat_util::def_to_path;
 use middle::ty::{self, Ty, TyCtxt};
@@ -89,16 +88,13 @@ fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId)
 }
 
 /// * `def_id` is the id of the constant.
-/// * `maybe_ref_id` is the id of the expr referencing the constant.
-/// * `param_substs` is the monomorphization substitution for the expression.
+/// * `substs` is the monomorphized substitutions for the expression.
 ///
-/// `maybe_ref_id` and `param_substs` are optional and are used for
-/// finding substitutions in associated constants. This generally
-/// happens in late/trans const evaluation.
+/// `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: &'a TyCtxt<'tcx>,
                                         def_id: DefId,
-                                        maybe_ref_id: Option<ast::NodeId>,
-                                        param_substs: Option<&'tcx subst::Substs<'tcx>>)
+                                        substs: Option<subst::Substs<'tcx>>)
                                         -> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)> {
     if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
         match tcx.map.find(node_id) {
@@ -111,28 +107,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
             },
             Some(ast_map::NodeTraitItem(ti)) => match ti.node {
                 hir::ConstTraitItem(_, _) => {
-                    match maybe_ref_id {
-                        // If we have a trait item, and we know the expression
-                        // that's the source of the obligation to resolve it,
+                    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.
-                        Some(ref_id) => {
-                            let trait_id = tcx.trait_of_item(def_id)
-                                              .unwrap();
-                            let mut substs = tcx.node_id_item_substs(ref_id)
-                                                .substs;
-                            if let Some(param_substs) = param_substs {
-                                substs = substs.subst(tcx, param_substs);
-                            }
-                            resolve_trait_associated_const(tcx, ti, trait_id, substs)
-                        }
+                        let trait_id = tcx.trait_of_item(def_id).unwrap();
+                        resolve_trait_associated_const(tcx, ti, 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
+                        None
                     }
                 }
                 _ => None
@@ -153,7 +141,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
             }
             None => {}
         }
-        let mut used_ref_id = false;
+        let mut used_substs = false;
         let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
             cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
                 hir::ItemConst(ref ty, ref const_expr) => {
@@ -163,21 +151,15 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
             },
             cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
                 hir::ConstTraitItem(_, _) => {
-                    used_ref_id = true;
-                    match maybe_ref_id {
+                    used_substs = true;
+                    if let Some(substs) = substs {
                         // 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 expression that refers to it.
-                        Some(ref_id) => {
-                            let mut substs = tcx.node_id_item_substs(ref_id)
-                                                .substs;
-                            if let Some(param_substs) = param_substs {
-                                substs = substs.subst(tcx, param_substs);
-                            }
-                            resolve_trait_associated_const(tcx, ti, trait_id, substs)
-                        }
-                        None => None
+                        // the substitutions for the reference to it.
+                        resolve_trait_associated_const(tcx, ti, trait_id, substs)
+                    } else {
+                        None
                     }
                 }
                 _ => None
@@ -190,10 +172,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
             },
             _ => None
         };
-        // If we used the reference expression, particularly to choose an impl
+        // If we used the substitutions, particularly to choose an impl
         // of a trait-associated const, don't cache that, because the next
         // lookup with the same def_id may yield a different result.
-        if !used_ref_id {
+        if !used_substs {
             tcx.extern_const_statics
                .borrow_mut()
                .insert(def_id, expr_ty.map(|(e, t)| (e.id, t)));
@@ -389,7 +371,8 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
                     PatKind::Path(path.clone()),
                 Some(Def::Const(def_id)) |
                 Some(Def::AssociatedConst(def_id)) => {
-                    let (expr, _ty) = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
+                    let substs = Some(tcx.node_id_item_substs(expr.id).substs);
+                    let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
                     return const_expr_to_pat(tcx, expr, span);
                 },
                 _ => unreachable!(),
@@ -788,12 +771,12 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
           match opt_def {
               Def::Const(def_id) |
               Def::AssociatedConst(def_id) => {
-                  let maybe_ref_id = if let ExprTypeChecked = ty_hint {
-                      Some(e.id)
+                  let substs = if let ExprTypeChecked = ty_hint {
+                      Some(tcx.node_id_item_substs(e.id).substs)
                   } else {
                       None
                   };
-                  if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, maybe_ref_id, None) {
+                  if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, substs) {
                       let item_hint = match ty {
                           Some(ty) => ty_hint.checked_or(ty),
                           None => ty_hint,
@@ -1077,7 +1060,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
         traits::VtableImpl(ref impl_data) => {
             match tcx.associated_consts(impl_data.impl_def_id)
                      .iter().find(|ic| ic.name == ti.name) {
-                Some(ic) => lookup_const_by_id(tcx, ic.def_id, None, None),
+                Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
                 None => match ti.node {
                     hir::ConstTraitItem(ref ty, Some(ref expr)) => {
                         Some((&*expr, ast_ty_to_prim_ty(tcx, ty)))
index 204b1c1d1e0c043ba7c3869d6c8653f12891567c..4d87d926e40551a5fa77ccc224b70dbd4b21e346 100644 (file)
@@ -672,7 +672,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
         },
         Def::Const(def_id) |
         Def::AssociatedConst(def_id) => {
-            if let Some(e) = const_eval::lookup_const_by_id(cx.tcx, def_id, Some(expr.id), None) {
+            let substs = Some(cx.tcx.node_id_item_substs(expr.id).substs);
+            if let Some((e, _)) = const_eval::lookup_const_by_id(cx.tcx, def_id, substs) {
                 // FIXME ConstVal can't be yet used with adjustments, as they would be lost.
                 if !cx.tcx.tables.borrow().adjustments.contains_key(&e.id) {
                     if let Some(v) = cx.try_const_eval_literal(e) {
index 232404417e0e4f605709a3f5e06015f4c6739e17..a98737783741710a32c8ce253e8e2e1d28131602 100644 (file)
@@ -86,9 +86,9 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
             {
                 let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
                 match def {
-                    Def::Const(def_id) | Def::AssociatedConst(def_id) =>
-                        match const_eval::lookup_const_by_id(self.cx.tcx, def_id,
-                                                             Some(pat.id), None) {
+                    Def::Const(def_id) | Def::AssociatedConst(def_id) => {
+                        let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
+                        match const_eval::lookup_const_by_id(self.cx.tcx, def_id, substs) {
                             Some((const_expr, _const_ty)) => {
                                 let pat = const_eval::const_expr_to_pat(self.cx.tcx, const_expr,
                                                                         pat.span);
@@ -99,7 +99,8 @@ fn to_pattern(&mut self, pat: &hir::Pat) -> Pattern<'tcx> {
                                     pat.span,
                                     &format!("cannot eval constant: {:?}", def_id))
                             }
-                        },
+                        }
+                    }
                     _ =>
                         self.cx.tcx.sess.span_bug(
                             pat.span,
index 74ede89be556221ede4dbcffb2a34483823b90cc..c964179d4076a2a87d707e2faa4b518b79b47f4b 100644 (file)
@@ -610,9 +610,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
                 Some(Def::Const(did)) |
                 Some(Def::AssociatedConst(did)) => {
-                    if let Some((expr, _ty)) = const_eval::lookup_const_by_id(v.tcx, did,
-                                                                       Some(e.id),
-                                                                       None) {
+                    let substs = Some(v.tcx.node_id_item_substs(e.id).substs);
+                    if let Some((expr, _)) = const_eval::lookup_const_by_id(v.tcx, did, substs) {
                         let inner = v.global_expr(Mode::Const, expr);
                         v.add_qualif(inner);
                     }
index 349afbba3ec6f9e31a3442e17d124254d183b203..82cd6aace0a35063c0825baf34c05c6f0cd96cb4 100644 (file)
 use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
 use llvm::{InternalLinkage, ValueRef, Bool, True};
 use middle::const_qualif::ConstQualif;
-use middle::cstore::LOCAL_CRATE;
 use middle::const_eval::{self, ConstEvalErr};
 use middle::def::Def;
 use middle::def_id::DefId;
 use rustc::front::map as hir_map;
-use trans::{abi, adt, closure, debuginfo, expr, inline, machine};
+use trans::{abi, adt, closure, debuginfo, expr, machine};
 use trans::base::{self, exported_name, imported_name, push_ctxt};
 use trans::callee::Callee;
 use trans::collector::{self, TransItem};
@@ -225,14 +224,11 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                 ref_expr: &hir::Expr,
                                 param_substs: &'tcx Substs<'tcx>)
                                 -> &'tcx hir::Expr {
-    let def_id = inline::maybe_instantiate_inline(ccx, def_id);
-
-    if def_id.krate != LOCAL_CRATE {
-        ccx.sess().span_bug(ref_expr.span,
-                            "cross crate constant could not be inlined");
-    }
-
-    match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(ref_expr.id), Some(param_substs)) {
+    let substs = ccx.tcx().node_id_item_substs(ref_expr.id).substs;
+    let substs = monomorphize::apply_param_substs(ccx.tcx(),
+                                                  param_substs,
+                                                  &substs.erase_regions());
+    match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(substs)) {
         Some((ref expr, _ty)) => expr,
         None => {
             ccx.sess().span_bug(ref_expr.span, "constant item not found")
index 06eef5d300520fcd9206a84a1c1075d991397e92..d4934718d75ed7f671e2843319bebaa208255f4b 100644 (file)
@@ -19,7 +19,6 @@
 use trans::consts;
 use trans::datum;
 use trans::expr;
-use trans::inline;
 use trans::type_of;
 use trans::type_::Type;
 
@@ -114,9 +113,8 @@ pub fn trans_constant(&mut self,
                     };
                 }
 
-                let substs = bcx.tcx().mk_substs(bcx.monomorphize(&substs));
-                let def_id = inline::maybe_instantiate_inline(bcx.ccx(), def_id);
-                let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, None, Some(substs))
+                let substs = Some(bcx.monomorphize(substs));
+                let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, substs)
                             .expect("def was const, but lookup_const_by_id failed").0;
                 // FIXME: this is falling back to translating from HIR. This is not easy to fix,
                 // because we would have somehow adapt const_eval to work on MIR rather than HIR.
index ef54be720376a7a79f96eb40491fa71d6ef2a8a2..49091a6c2bcfc9ea87d1686a3bcc6bc2791240ef 100644 (file)
@@ -336,7 +336,7 @@ pub fn build_impl(cx: &DocContext,
                 let did = assoc_const.def_id;
                 let type_scheme = tcx.lookup_item_type(did);
                 let default = if assoc_const.has_value {
-                    Some(const_eval::lookup_const_by_id(tcx, did, None, None)
+                    Some(const_eval::lookup_const_by_id(tcx, did, None)
                          .unwrap().0.span.to_src(cx))
                 } else {
                     None
@@ -479,7 +479,7 @@ fn build_const(cx: &DocContext, tcx: &TyCtxt,
     use rustc::middle::const_eval;
     use rustc_front::print::pprust;
 
-    let (expr, ty) = const_eval::lookup_const_by_id(tcx, did, None, None).unwrap_or_else(|| {
+    let (expr, ty) = const_eval::lookup_const_by_id(tcx, did, None).unwrap_or_else(|| {
         panic!("expected lookup_const_by_id to succeed for {:?}", did);
     });
     debug!("converting constant expr {:?} to snippet", expr);