Skip to content

Commit 9b1865a

Browse files
committed
Add a limited prim type lookup for safer const expr evaluation
1 parent edfb546 commit 9b1865a

File tree

6 files changed

+285
-209
lines changed

6 files changed

+285
-209
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
use metadata::csearch;
1313
use middle::astencode;
14+
1415
use middle::ty;
16+
use middle::typeck::astconv;
1517
use middle;
1618

1719
use syntax::{ast, ast_map, ast_util};
@@ -445,8 +447,17 @@ pub fn eval_const_expr_partial<T: ty::ExprTyProvider>(tcx: &T, e: &Expr)
445447
_ => Err(~"Bad operands for binary")
446448
}
447449
}
448-
ExprCast(base, _) => {
449-
let ety = tcx.expr_ty(e);
450+
ExprCast(base, target_ty) => {
451+
// This tends to get called w/o the type actually having been
452+
// populated in the ctxt, which was causing things to blow up
453+
// (#5900). Fall back to doing a limited lookup to get past it.
454+
let ety = ty::expr_ty_opt(tcx.ty_ctxt(), e)
455+
.or_else(|| astconv::ast_ty_to_prim_ty(tcx.ty_ctxt(), target_ty))
456+
.unwrap_or_else(|| tcx.ty_ctxt().sess.span_fatal(
457+
target_ty.span,
458+
format!("Target type not found for const cast")
459+
));
460+
450461
let base = eval_const_expr_partial(tcx, base);
451462
match base {
452463
Err(_) => base,

src/librustc/middle/ty.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2617,17 +2617,24 @@ pub fn node_id_to_trait_ref(cx: ctxt, id: ast::NodeId) -> @ty::TraitRef {
26172617
}
26182618

26192619
pub fn node_id_to_type(cx: ctxt, id: ast::NodeId) -> t {
2620-
//printfln!("{:?}/{:?}", id, cx.node_types.len());
2621-
let node_types = cx.node_types.borrow();
2622-
match node_types.get().find(&(id as uint)) {
2623-
Some(&t) => t,
2620+
match node_id_to_type_opt(cx, id) {
2621+
Some(t) => t,
26242622
None => cx.sess.bug(
26252623
format!("node_id_to_type: no type for node `{}`",
26262624
ast_map::node_id_to_str(cx.items, id,
26272625
token::get_ident_interner())))
26282626
}
26292627
}
26302628

2629+
pub fn node_id_to_type_opt(cx: ctxt, id: ast::NodeId) -> Option<t> {
2630+
let node_types = cx.node_types.borrow();
2631+
debug!("id: {:?}, node_types: {:?}", id, node_types);
2632+
match node_types.get().find(&(id as uint)) {
2633+
Some(&t) => Some(t),
2634+
None => None
2635+
}
2636+
}
2637+
26312638
// FIXME(pcwalton): Makes a copy, bleh. Probably better to not do that.
26322639
pub fn node_id_to_type_params(cx: ctxt, id: ast::NodeId) -> ~[t] {
26332640
let node_type_substs = cx.node_type_substs.borrow();
@@ -2798,6 +2805,10 @@ pub fn expr_ty(cx: ctxt, expr: &ast::Expr) -> t {
27982805
return node_id_to_type(cx, expr.id);
27992806
}
28002807

2808+
pub fn expr_ty_opt(cx: ctxt, expr: &ast::Expr) -> Option<t> {
2809+
return node_id_to_type_opt(cx, expr.id);
2810+
}
2811+
28012812
pub fn expr_ty_adjusted(cx: ctxt, expr: &ast::Expr) -> t {
28022813
/*!
28032814
*

0 commit comments

Comments
 (0)