Skip to content

Commit 5255a31

Browse files
committed
const_eval: Take just one set of substitutions in lookup_const_by_id.
1 parent f976c94 commit 5255a31

File tree

8 files changed

+50
-73
lines changed

8 files changed

+50
-73
lines changed

src/librustc/middle/check_match.rs

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

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

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

src/librustc/middle/const_eval.rs

Lines changed: 26 additions & 43 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};
@@ -78,16 +77,13 @@ fn lookup_variant_by_id<'a>(tcx: &'a TyCtxt,
7877
}
7978

8079
/// * `def_id` is the id of the constant.
81-
/// * `maybe_ref_id` is the id of the expr referencing the constant.
82-
/// * `param_substs` is the monomorphization substitution for the expression.
80+
/// * `substs` is the monomorphized substitutions for the expression.
8381
///
84-
/// `maybe_ref_id` and `param_substs` are optional and are used for
85-
/// finding substitutions in associated constants. This generally
86-
/// happens in late/trans const evaluation.
82+
/// `substs` is optional and is used for associated constants.
83+
/// This generally happens in late/trans const evaluation.
8784
pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
8885
def_id: DefId,
89-
maybe_ref_id: Option<ast::NodeId>,
90-
param_substs: Option<&'tcx subst::Substs<'tcx>>)
86+
substs: Option<subst::Substs<'tcx>>)
9187
-> Option<&'tcx Expr> {
9288
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
9389
match tcx.map.find(node_id) {
@@ -100,29 +96,20 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
10096
},
10197
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
10298
hir::ConstTraitItem(_, _) => {
103-
match maybe_ref_id {
104-
// If we have a trait item, and we know the expression
105-
// that's the source of the obligation to resolve it,
99+
if let Some(substs) = substs {
100+
// If we have a trait item and the substitutions for it,
106101
// `resolve_trait_associated_const` will select an impl
107102
// or the default.
108-
Some(ref_id) => {
109-
let trait_id = tcx.trait_of_item(def_id)
110-
.unwrap();
111-
let mut substs = tcx.node_id_item_substs(ref_id)
112-
.substs;
113-
if let Some(param_substs) = param_substs {
114-
substs = substs.subst(tcx, param_substs);
115-
}
116-
resolve_trait_associated_const(tcx, ti, trait_id,
117-
substs)
118-
}
103+
let trait_id = tcx.trait_of_item(def_id).unwrap();
104+
resolve_trait_associated_const(tcx, ti, trait_id, substs)
105+
} else {
119106
// Technically, without knowing anything about the
120107
// expression that generates the obligation, we could
121108
// still return the default if there is one. However,
122109
// it's safer to return `None` than to return some value
123110
// that may differ from what you would get from
124111
// correctly selecting an impl.
125-
None => None
112+
None
126113
}
127114
}
128115
_ => None
@@ -143,30 +130,23 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
143130
}
144131
None => {}
145132
}
146-
let mut used_ref_id = false;
133+
let mut used_substs = false;
147134
let expr_id = match tcx.sess.cstore.maybe_get_item_ast(tcx, def_id) {
148135
cstore::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
149136
hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
150137
_ => None
151138
},
152139
cstore::FoundAst::Found(&InlinedItem::TraitItem(trait_id, ref ti)) => match ti.node {
153140
hir::ConstTraitItem(_, _) => {
154-
used_ref_id = true;
155-
match maybe_ref_id {
141+
used_substs = true;
142+
if let Some(substs) = substs {
156143
// As mentioned in the comments above for in-crate
157144
// constants, we only try to find the expression for
158145
// a trait-associated const if the caller gives us
159-
// the expression that refers to it.
160-
Some(ref_id) => {
161-
let mut substs = tcx.node_id_item_substs(ref_id)
162-
.substs;
163-
if let Some(param_substs) = param_substs {
164-
substs = substs.subst(tcx, param_substs);
165-
}
166-
resolve_trait_associated_const(tcx, ti, trait_id,
167-
substs).map(|e| e.id)
168-
}
169-
None => None
146+
// the substitutions for the reference to it.
147+
resolve_trait_associated_const(tcx, ti, trait_id, substs).map(|e| e.id)
148+
} else {
149+
None
170150
}
171151
}
172152
_ => None
@@ -177,10 +157,10 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
177157
},
178158
_ => None
179159
};
180-
// If we used the reference expression, particularly to choose an impl
160+
// If we used the substitutions, particularly to choose an impl
181161
// of a trait-associated const, don't cache that, because the next
182162
// lookup with the same def_id may yield a different result.
183-
if !used_ref_id {
163+
if !used_substs {
184164
tcx.extern_const_statics
185165
.borrow_mut().insert(def_id,
186166
expr_id.unwrap_or(ast::DUMMY_NODE_ID));
@@ -370,7 +350,8 @@ pub fn const_expr_to_pat(tcx: &TyCtxt, expr: &Expr, span: Span) -> P<hir::Pat> {
370350
PatKind::Path(path.clone()),
371351
Some(Def::Const(def_id)) |
372352
Some(Def::AssociatedConst(def_id)) => {
373-
let expr = lookup_const_by_id(tcx, def_id, Some(expr.id), None).unwrap();
353+
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
354+
let expr = lookup_const_by_id(tcx, def_id, substs).unwrap();
374355
return const_expr_to_pat(tcx, expr, span);
375356
},
376357
_ => unreachable!(),
@@ -1014,7 +995,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
1014995
_ => (None, None)
1015996
}
1016997
} else {
1017-
(lookup_const_by_id(tcx, def_id, Some(e.id), None), None)
998+
let substs = Some(tcx.node_id_item_substs(e.id).substs);
999+
(lookup_const_by_id(tcx, def_id, substs), None)
10181000
}
10191001
}
10201002
Some(Def::AssociatedConst(def_id)) => {
@@ -1049,7 +1031,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
10491031
},
10501032
}
10511033
} else {
1052-
(lookup_const_by_id(tcx, def_id, Some(e.id), None), None)
1034+
let substs = Some(tcx.node_id_item_substs(e.id).substs);
1035+
(lookup_const_by_id(tcx, def_id, substs), None)
10531036
}
10541037
}
10551038
Some(Def::Variant(enum_def, variant_def)) => {
@@ -1274,7 +1257,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a TyCtxt<'tcx>,
12741257
traits::VtableImpl(ref impl_data) => {
12751258
match tcx.associated_consts(impl_data.impl_def_id)
12761259
.iter().find(|ic| ic.name == ti.name) {
1277-
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None, None),
1260+
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
12781261
None => match ti.node {
12791262
hir::ConstTraitItem(_, Some(ref expr)) => Some(&*expr),
12801263
_ => None,

src/librustc_mir/hair/cx/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,8 @@ fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr)
659659
},
660660
Def::Const(def_id) |
661661
Def::AssociatedConst(def_id) => {
662-
if let Some(e) = const_eval::lookup_const_by_id(cx.tcx, def_id, Some(expr.id), None) {
662+
let substs = Some(cx.tcx.node_id_item_substs(expr.id).substs);
663+
if let Some(e) = const_eval::lookup_const_by_id(cx.tcx, def_id, substs) {
663664
// FIXME ConstVal can't be yet used with adjustments, as they would be lost.
664665
if !cx.tcx.tables.borrow().adjustments.contains_key(&e.id) {
665666
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) => {
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
@@ -604,9 +604,8 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
604604
}
605605
Some(Def::Const(did)) |
606606
Some(Def::AssociatedConst(did)) => {
607-
if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did,
608-
Some(e.id),
609-
None) {
607+
let substs = Some(v.tcx.node_id_item_substs(e.id).substs);
608+
if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did, substs) {
610609
let inner = v.global_expr(Mode::Const, expr);
611610
v.add_qualif(inner);
612611
}

src/librustc_trans/trans/consts.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ 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, ConstVal, ConstEvalErr};
1817
use middle::const_eval::{const_int_checked_neg, const_uint_checked_neg};
1918
use middle::const_eval::{const_int_checked_add, const_uint_checked_add};
@@ -26,7 +25,7 @@ use middle::const_eval::{const_int_checked_shr, const_uint_checked_shr};
2625
use middle::def::Def;
2726
use middle::def_id::DefId;
2827
use rustc::front::map as hir_map;
29-
use trans::{abi, adt, closure, debuginfo, expr, inline, machine};
28+
use trans::{abi, adt, closure, debuginfo, expr, machine};
3029
use trans::base::{self, exported_name, imported_name, push_ctxt};
3130
use trans::callee::Callee;
3231
use trans::collector::{self, TransItem};
@@ -232,14 +231,11 @@ pub fn get_const_expr<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
232231
ref_expr: &hir::Expr,
233232
param_substs: &'tcx Substs<'tcx>)
234233
-> &'tcx hir::Expr {
235-
let def_id = inline::maybe_instantiate_inline(ccx, def_id);
236-
237-
if def_id.krate != LOCAL_CRATE {
238-
ccx.sess().span_bug(ref_expr.span,
239-
"cross crate constant could not be inlined");
240-
}
241-
242-
match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(ref_expr.id), Some(param_substs)) {
234+
let substs = ccx.tcx().node_id_item_substs(ref_expr.id).substs;
235+
let substs = monomorphize::apply_param_substs(ccx.tcx(),
236+
param_substs,
237+
&substs.erase_regions());
238+
match const_eval::lookup_const_by_id(ccx.tcx(), def_id, Some(substs)) {
243239
Some(ref expr) => expr,
244240
None => {
245241
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
@@ -18,7 +18,6 @@ use trans::common::{self, BlockAndBuilder, C_bool, C_bytes, C_floating_f64, C_in
1818
use trans::consts;
1919
use trans::datum;
2020
use trans::expr;
21-
use trans::inline;
2221
use trans::type_of;
2322

2423
use super::operand::{OperandRef, OperandValue};
@@ -94,9 +93,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
9493
};
9594
}
9695

97-
let substs = bcx.tcx().mk_substs(bcx.monomorphize(&substs));
98-
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), def_id);
99-
let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, None, Some(substs))
96+
let substs = Some(bcx.monomorphize(substs));
97+
let expr = const_eval::lookup_const_by_id(bcx.tcx(), def_id, substs)
10098
.expect("def was const, but lookup_const_by_id failed");
10199
// FIXME: this is falling back to translating from HIR. This is not easy to fix,
102100
// 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
@@ -319,7 +319,7 @@ pub fn build_impl(cx: &DocContext,
319319
let did = assoc_const.def_id;
320320
let type_scheme = tcx.lookup_item_type(did);
321321
let default = if assoc_const.has_value {
322-
Some(const_eval::lookup_const_by_id(tcx, did, None, None)
322+
Some(const_eval::lookup_const_by_id(tcx, did, None)
323323
.unwrap().span.to_src(cx))
324324
} else {
325325
None
@@ -462,7 +462,7 @@ fn build_const(cx: &DocContext, tcx: &TyCtxt,
462462
use rustc::middle::const_eval;
463463
use rustc_front::print::pprust;
464464

465-
let expr = const_eval::lookup_const_by_id(tcx, did, None, None).unwrap_or_else(|| {
465+
let expr = const_eval::lookup_const_by_id(tcx, did, None).unwrap_or_else(|| {
466466
panic!("expected lookup_const_by_id to succeed for {:?}", did);
467467
});
468468
debug!("converting constant expr {:?} to snippet", expr);

0 commit comments

Comments
 (0)