Skip to content

Commit 0a62158

Browse files
committed
Add helper methods that require tcx; these compute types of
lvalues and operands
1 parent 044096b commit 0a62158

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

src/librustc_mir/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ pub mod mir_map;
3434
mod hair;
3535
pub mod repr;
3636
mod graphviz;
37-
37+
pub mod tcx;
3838

src/librustc_mir/tcx/mod.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*!
12+
* Methods for the various MIR types. These are intended for use after
13+
* building is complete.
14+
*/
15+
16+
use repr::*;
17+
use rustc::middle::subst::Substs;
18+
use rustc::middle::ty::{self, AdtDef, Ty};
19+
20+
#[derive(Copy, Clone, Debug)]
21+
pub enum LvalueTy<'tcx> {
22+
/// Normal type.
23+
Ty { ty: Ty<'tcx> },
24+
25+
/// Downcast to a particular variant of an enum.
26+
Downcast { adt_def: AdtDef<'tcx>,
27+
substs: &'tcx Substs<'tcx>,
28+
variant_index: usize },
29+
}
30+
31+
impl<'tcx> LvalueTy<'tcx> {
32+
pub fn from_ty(ty: Ty<'tcx>) -> LvalueTy<'tcx> {
33+
LvalueTy::Ty { ty: ty }
34+
}
35+
36+
pub fn to_ty(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
37+
match *self {
38+
LvalueTy::Ty { ty } =>
39+
ty,
40+
LvalueTy::Downcast { adt_def, substs, variant_index: _ } =>
41+
tcx.mk_enum(adt_def, substs),
42+
}
43+
}
44+
45+
pub fn projection_ty(self,
46+
tcx: &ty::ctxt<'tcx>,
47+
elem: &LvalueElem<'tcx>)
48+
-> LvalueTy<'tcx>
49+
{
50+
match *elem {
51+
ProjectionElem::Deref =>
52+
LvalueTy::Ty {
53+
ty: self.to_ty(tcx).builtin_deref(true, ty::LvaluePreference::NoPreference)
54+
.unwrap()
55+
.ty
56+
},
57+
ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } =>
58+
LvalueTy::Ty {
59+
ty: self.to_ty(tcx).builtin_index().unwrap()
60+
},
61+
ProjectionElem::Downcast(adt_def1, index) =>
62+
match self.to_ty(tcx).sty {
63+
ty::TyEnum(adt_def, substs) => {
64+
assert!(index < adt_def.variants.len());
65+
assert_eq!(adt_def, adt_def1);
66+
LvalueTy::Downcast { adt_def: adt_def,
67+
substs: substs,
68+
variant_index: index }
69+
}
70+
_ => {
71+
tcx.sess.bug(&format!("cannot downcast non-enum type: `{:?}`", self))
72+
}
73+
},
74+
ProjectionElem::Field(field) => {
75+
let field_ty = match self {
76+
LvalueTy::Ty { ty } => match ty.sty {
77+
ty::TyStruct(adt_def, substs) =>
78+
adt_def.struct_variant().fields[field.index()].ty(tcx, substs),
79+
ty::TyTuple(ref tys) =>
80+
tys[field.index()],
81+
_ =>
82+
tcx.sess.bug(&format!("cannot get field of type: `{:?}`", ty)),
83+
},
84+
LvalueTy::Downcast { adt_def, substs, variant_index } =>
85+
adt_def.variants[variant_index].fields[field.index()].ty(tcx, substs),
86+
};
87+
LvalueTy::Ty { ty: field_ty }
88+
}
89+
}
90+
}
91+
}
92+
93+
impl<'tcx> Mir<'tcx> {
94+
pub fn operand_ty(&self,
95+
tcx: &ty::ctxt<'tcx>,
96+
operand: &Operand<'tcx>)
97+
-> Ty<'tcx>
98+
{
99+
match *operand {
100+
Operand::Consume(ref l) => self.lvalue_ty(tcx, l).to_ty(tcx),
101+
Operand::Constant(ref c) => c.ty,
102+
}
103+
}
104+
105+
pub fn lvalue_ty(&self,
106+
tcx: &ty::ctxt<'tcx>,
107+
lvalue: &Lvalue<'tcx>)
108+
-> LvalueTy<'tcx>
109+
{
110+
match *lvalue {
111+
Lvalue::Var(index) =>
112+
LvalueTy::Ty { ty: self.var_decls[index as usize].ty },
113+
Lvalue::Temp(index) =>
114+
LvalueTy::Ty { ty: self.temp_decls[index as usize].ty },
115+
Lvalue::Arg(index) =>
116+
LvalueTy::Ty { ty: self.arg_decls[index as usize].ty },
117+
Lvalue::Static(def_id) =>
118+
LvalueTy::Ty { ty: tcx.lookup_item_type(def_id).ty },
119+
Lvalue::ReturnPointer =>
120+
LvalueTy::Ty { ty: self.return_ty.unwrap() },
121+
Lvalue::Projection(ref proj) =>
122+
self.lvalue_ty(tcx, &proj.base).projection_ty(tcx, &proj.elem)
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)