Skip to content

Commit 7912f94

Browse files
committed
const_eval: Take just one set of substitutions in lookup_const_by_id.
1 parent 5eeda54 commit 7912f94

File tree

8 files changed

+49
-72
lines changed

8 files changed

+49
-72
lines changed

src/librustc/middle/check_match.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -475,9 +475,9 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
475475
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
476476
match def {
477477
Some(Def::AssociatedConst(did)) |
478-
Some(Def::Const(did)) => match lookup_const_by_id(self.tcx, did,
479-
Some(pat.id), None) {
480-
Some((const_expr, _const_ty)) => {
478+
Some(Def::Const(did)) => {
479+
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
480+
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
481481
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
482482

483483
if let Some(ref mut renaming_map) = self.renaming_map {
@@ -487,14 +487,13 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
487487

488488
new_pat
489489
})
490-
}
491-
None => {
490+
} else {
492491
self.failed = true;
493492
span_err!(self.tcx.sess, pat.span, E0158,
494493
"statics cannot be referenced in patterns");
495494
pat
496495
}
497-
},
496+
}
498497
_ => noop_fold_pat(pat, self)
499498
}
500499
}

src/librustc/middle/const_eval.rs

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use front::map::blocks::FnLikeNode;
1919
use middle::cstore::{self, CrateStore, InlinedItem};
2020
use middle::{infer, subst, traits};
2121
use middle::def::Def;
22-
use middle::subst::Subst;
2322
use middle::def_id::DefId;
2423
use middle::pat_util::def_to_path;
2524
use middle::ty::{self, Ty, TyCtxt};
@@ -89,16 +88,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::TyCtxt,
8988
}
9089

9190
/// * `def_id` is the id of the constant.
92-
/// * `maybe_ref_id` is the id of the expr referencing the constant.
93-
/// * `param_substs` is the monomorphization substitution for the expression.
91+
/// * `substs` is the monomorphized substitutions for the expression.
9492
///
95-
/// `maybe_ref_id` and `param_substs` are optional and are used for
96-
/// finding substitutions in associated constants. This generally
97-
/// happens in late/trans const evaluation.
93+
/// `substs` is optional and is used for associated constants.
94+
/// This generally happens in late/trans const evaluation.
9895
pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
9996
def_id: DefId,
100-
maybe_ref_id: Option<ast::NodeId>,
101-
param_substs: Option<&'tcx subst::Substs<'tcx>>)
97+
substs: Option<subst::Substs<'tcx>>)
10298
-> Option<(&'tcx Expr, Option<ty::Ty<'tcx>>)> {
10399
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
104100
match tcx.map.find(node_id) {
@@ -111,28 +107,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
111107
},
112108
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
113109
hir::ConstTraitItem(_, _) => {
114-
match maybe_ref_id {
115-
// If we have a trait item, and we know the expression
116-
// that's the source of the obligation to resolve it,
110+
if let Some(substs) = substs {
111+
// If we have a trait item and the substitutions for it,
117112
// `resolve_trait_associated_const` will select an impl
118113
// or the default.
119-
Some(ref_id) => {
120-
let trait_id = tcx.trait_of_item(def_id)
121-
.unwrap();
122-
let mut substs = tcx.node_id_item_substs(ref_id)
123-
.substs;
124-
if let Some(param_substs) = param_substs {
125-
substs = substs.subst(tcx, param_substs);
126-
}
127-
resolve_trait_associated_const(tcx, ti, trait_id, substs)
128-
}
114+
let trait_id = tcx.trait_of_item(def_id).unwrap();
115+
resolve_trait_associated_const(tcx, ti, trait_id, substs)
116+
} else {
129117
// Technically, without knowing anything about the
130118
// expression that generates the obligation, we could
131119
// still return the default if there is one. However,
132120
// it's safer to return `None` than to return some value
133121
// that may differ from what you would get from
134122
// correctly selecting an impl.
135-
None => None
123+
None
136124
}
137125
}
138126
_ => None
@@ -153,7 +141,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
153141
}
154142
None => {}
155143
}
156-
let mut used_ref_id = false;
144+
let mut used_substs = false;
157145
let expr_ty = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
158146
cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
159147
hir::ItemConst(ref ty, ref const_expr) => {
@@ -163,21 +151,15 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
163151
},
164152
cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
165153
hir::ConstTraitItem(_, _) => {
166-
used_ref_id = true;
167-
match maybe_ref_id {
154+
used_substs = true;
155+
if let Some(substs) = substs {
168156
// As mentioned in the comments above for in-crate
169157
// constants, we only try to find the expression for
170158
// a trait-associated const if the caller gives us
171-
// the expression that refers to it.
172-
Some(ref_id) => {
173-
let mut substs = tcx.node_id_item_substs(ref_id)
174-
.substs;
175-
if let Some(param_substs) = param_substs {
176-
substs = substs.subst(tcx, param_substs);
177-
}
178-
resolve_trait_associated_const(tcx, ti, trait_id, substs)
179-
}
180-
None => None
159+
// the substitutions for the reference to it.
160+
resolve_trait_associated_const(tcx, ti, trait_id, substs)
161+
} else {
162+
None
181163
}
182164
}
183165
_ => None
@@ -190,10 +172,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
190172
},
191173
_ => None
192174
};
193-
// If we used the reference expression, particularly to choose an impl
175+
// If we used the substitutions, particularly to choose an impl
194176
// of a trait-associated const, don't cache that, because the next
195177
// lookup with the same def_id may yield a different result.
196-
if !used_ref_id {
178+
if !used_substs {
197179
tcx.extern_const_statics
198180
.borrow_mut()
199181
.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> {
389371
PatKind::Path(path.clone()),
390372
Some(Def::Const(def_id)) |
391373
Some(Def::AssociatedConst(def_id)) => {
392-
let (expr, _ty) = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
374+
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
375+
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
393376
return const_expr_to_pat(tcx, expr, span);
394377
},
395378
_ => unreachable!(),
@@ -788,12 +771,12 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
788771
match opt_def {
789772
Def::Const(def_id) |
790773
Def::AssociatedConst(def_id) => {
791-
let maybe_ref_id = if let ExprTypeChecked = ty_hint {
792-
Some(e.id)
774+
let substs = if let ExprTypeChecked = ty_hint {
775+
Some(tcx.node_id_item_substs(e.id).substs)
793776
} else {
794777
None
795778
};
796-
if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, maybe_ref_id, None) {
779+
if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, substs) {
797780
let item_hint = match ty {
798781
Some(ty) => ty_hint.checked_or(ty),
799782
None => ty_hint,
@@ -1077,7 +1060,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
10771060
traits::VtableImpl(ref impl_data) => {
10781061
match tcx.associated_consts(impl_data.impl_def_id)
10791062
.iter().find(|ic| ic.name == ti.name) {
1080-
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None, None),
1063+
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
10811064
None => match ti.node {
10821065
hir::ConstTraitItem(ref ty, Some(ref expr)) => {
10831066
Some((&*expr, ast_ty_to_prim_ty(tcx, ty)))

src/librustc_mir/hair/cx/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
672672
},
673673
Def::Const(def_id) |
674674
Def::AssociatedConst(def_id) => {
675-
if let Some(e) = const_eval::lookup_const_by_id(cx.tcx, def_id, Some(expr.id), None) {
675+
let substs = Some(cx.tcx.node_id_item_substs(expr.id).substs);
676+
if let Some((e, _)) = const_eval::lookup_const_by_id(cx.tcx, def_id, substs) {
676677
// FIXME ConstVal can't be yet used with adjustments, as they would be lost.
677678
if !cx.tcx.tables.borrow().adjustments.contains_key(&e.id) {
678679
if let Some(v) = cx.try_const_eval_literal(e) {

src/librustc_mir/hair/cx/pattern.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
8686
{
8787
let def = self.cx.tcx.def_map.borrow().get(&pat.id).unwrap().full_def();
8888
match def {
89-
Def::Const(def_id) | Def::AssociatedConst(def_id) =>
90-
match const_eval::lookup_const_by_id(self.cx.tcx, def_id,
91-
Some(pat.id), None) {
89+
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
90+
let substs = Some(self.cx.tcx.node_id_item_substs(pat.id).substs);
91+
match const_eval::lookup_const_by_id(self.cx.tcx, def_id, substs) {
9292
Some((const_expr, _const_ty)) => {
9393
let pat = const_eval::const_expr_to_pat(self.cx.tcx, const_expr,
9494
pat.span);
@@ -99,7 +99,8 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> {
9999
pat.span,
100100
&format!("cannot eval constant: {:?}", def_id))
101101
}
102-
},
102+
}
103+
}
103104
_ =>
104105
self.cx.tcx.sess.span_bug(
105106
pat.span,

src/librustc_passes/consts.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,9 +610,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
610610
}
611611
Some(Def::Const(did)) |
612612
Some(Def::AssociatedConst(did)) => {
613-
if let Some((expr, _ty)) = const_eval::lookup_const_by_id(v.tcx, did,
614-
Some(e.id),
615-
None) {
613+
let substs = Some(v.tcx.node_id_item_substs(e.id).substs);
614+
if let Some((expr, _)) = const_eval::lookup_const_by_id(v.tcx, did, substs) {
616615
let inner = v.global_expr(Mode::Const, expr);
617616
v.add_qualif(inner);
618617
}

src/librustc_trans/trans/consts.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ use llvm;
1313
use llvm::{ConstFCmp, ConstICmp, SetLinkage, SetUnnamedAddr};
1414
use llvm::{InternalLinkage, ValueRef, Bool, True};
1515
use middle::const_qualif::ConstQualif;
16-
use middle::cstore::LOCAL_CRATE;
1716
use middle::const_eval::{self, ConstEvalErr};
1817
use middle::def::Def;
1918
use middle::def_id::DefId;
2019
use rustc::front::map as hir_map;
21-
use trans::{abi, adt, closure, debuginfo, expr, inline, machine};
20+
use trans::{abi, adt, closure, debuginfo, expr, machine};
2221
use trans::base::{self, exported_name, imported_name, push_ctxt};
2322
use trans::callee::Callee;
2423
use trans::collector::{self, TransItem};
@@ -225,14 +224,11 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
225224
ref_expr: &hir::Expr,
226225
param_substs: &'tcx Substs<'tcx>)
227226
-> &'tcx hir::Expr {
228-
let def_id = inline::maybe_instantiate_inline(ccx, def_id);
229-
230-
if def_id.krate != LOCAL_CRATE {
231-
ccx.sess().span_bug(ref_expr.span,
232-
"cross crate constant could not be inlined");
233-
}
234-
235-
match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(ref_expr.id), Some(param_substs)) {
227+
let substs = ccx.tcx().node_id_item_substs(ref_expr.id).substs;
228+
let substs = monomorphize::apply_param_substs(ccx.tcx(),
229+
param_substs,
230+
&substs.erase_regions());
231+
match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(substs)) {
236232
Some((ref expr, _ty)) => expr,
237233
None => {
238234
ccx.sess().span_bug(ref_expr.span, "constant item not found")

src/librustc_trans/trans/mir/constant.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use trans::common::{self, BlockAndBuilder, C_bool, C_bytes, C_floating_f64, C_in
1919
use trans::consts;
2020
use trans::datum;
2121
use trans::expr;
22-
use trans::inline;
2322
use trans::type_of;
2423
use trans::type_::Type;
2524

@@ -114,9 +113,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
114113
};
115114
}
116115

117-
let substs = bcx.tcx().mk_substs(bcx.monomorphize(&substs));
118-
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), def_id);
119-
let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, None, Some(substs))
116+
let substs = Some(bcx.monomorphize(substs));
117+
let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, substs)
120118
.expect("def was const, but lookup_const_by_id failed").0;
121119
// FIXME: this is falling back to translating from HIR. This is not easy to fix,
122120
// because we would have somehow adapt const_eval to work on MIR rather than HIR.

src/librustdoc/clean/inline.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ pub fn build_impl(cx: &DocContext,
336336
let did = assoc_const.def_id;
337337
let type_scheme = tcx.lookup_item_type(did);
338338
let default = if assoc_const.has_value {
339-
Some(const_eval::lookup_const_by_id(tcx, did, None, None)
339+
Some(const_eval::lookup_const_by_id(tcx, did, None)
340340
.unwrap().0.span.to_src(cx))
341341
} else {
342342
None
@@ -479,7 +479,7 @@ fn build_const(cx: &DocContext, tcx: &TyCtxt,
479479
use rustc::middle::const_eval;
480480
use rustc_front::print::pprust;
481481

482-
let (expr, ty) = const_eval::lookup_const_by_id(tcx, did, None, None).unwrap_or_else(|| {
482+
let (expr, ty) = const_eval::lookup_const_by_id(tcx, did, None).unwrap_or_else(|| {
483483
panic!("expected lookup_const_by_id to succeed for {:?}", did);
484484
});
485485
debug!("converting constant expr {:?} to snippet", expr);

0 commit comments

Comments
 (0)