use util::common::time;
use util::ppaux::Repr;
use util::ppaux;
+use util::nodemap::{DefIdMap, FnvHashMap};
use std::cell::RefCell;
-use collections::HashMap;
use std::rc::Rc;
use collections::List;
-use collections::list;
use syntax::codemap::Span;
use syntax::print::pprust::*;
use syntax::{ast, ast_map, abi};
}
#[deriving(Clone, Encodable, Decodable)]
-pub enum method_origin {
+pub enum MethodOrigin {
// fully statically resolved method
- method_static(ast::DefId),
+ MethodStatic(ast::DefId),
// method invoked on a type parameter with a bounded trait
- method_param(method_param),
+ MethodParam(MethodParam),
// method invoked on a trait instance
- method_object(method_object),
+ MethodObject(MethodObject),
}
// details for a method invoked with a receiver whose type is a type parameter
// with a bounded trait.
#[deriving(Clone, Encodable, Decodable)]
-pub struct method_param {
+pub struct MethodParam {
// the trait containing the method to be invoked
trait_id: ast::DefId,
// details for a method invoked with a receiver whose type is an object
#[deriving(Clone, Encodable, Decodable)]
-pub struct method_object {
+pub struct MethodObject {
// the (super)trait containing the method to be invoked
trait_id: ast::DefId,
real_index: uint,
}
+#[deriving(Clone)]
+pub struct MethodCallee {
+ origin: MethodOrigin,
+ ty: ty::t,
+ substs: ty::substs
+}
+
+#[deriving(Clone, Eq, TotalEq, Hash, Show)]
+pub struct MethodCall {
+ expr_id: ast::NodeId,
+ autoderef: u32
+}
+
+impl MethodCall {
+ pub fn expr(id: ast::NodeId) -> MethodCall {
+ MethodCall {
+ expr_id: id,
+ autoderef: 0
+ }
+ }
+
+ pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
+ MethodCall {
+ expr_id: expr_id,
+ autoderef: 1 + autoderef
+ }
+ }
+}
+
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
-pub type method_map = @RefCell<HashMap<ast::NodeId, method_origin>>;
+pub type MethodMap = @RefCell<FnvHashMap<MethodCall, MethodCallee>>;
-pub type vtable_param_res = @~[vtable_origin];
+pub type vtable_param_res = @Vec<vtable_origin> ;
// Resolutions for bounds of all parameters, left to right, for a given path.
-pub type vtable_res = @~[vtable_param_res];
+pub type vtable_res = @Vec<vtable_param_res> ;
#[deriving(Clone)]
pub enum vtable_origin {
from whence comes the vtable, and tys are the type substs.
vtable_res is the vtable itself
*/
- vtable_static(ast::DefId, ~[ty::t], vtable_res),
+ vtable_static(ast::DefId, Vec<ty::t> , vtable_res),
/*
Dynamic vtable, comes from a parameter that has a bound on it:
}
impl Repr for vtable_origin {
- fn repr(&self, tcx: ty::ctxt) -> ~str {
+ fn repr(&self, tcx: &ty::ctxt) -> ~str {
match *self {
vtable_static(def_id, ref tys, ref vtable_res) => {
format!("vtable_static({:?}:{}, {}, {})",
}
}
-pub type vtable_map = @RefCell<HashMap<ast::NodeId, vtable_res>>;
+pub type vtable_map = @RefCell<FnvHashMap<MethodCall, vtable_res>>;
-// Information about the vtable resolutions for for a trait impl.
+// Information about the vtable resolutions for a trait impl.
// Mostly the information is important for implementing default
// methods.
#[deriving(Clone)]
}
impl Repr for impl_res {
- fn repr(&self, tcx: ty::ctxt) -> ~str {
+ fn repr(&self, tcx: &ty::ctxt) -> ~str {
format!("impl_res \\{trait_vtables={}, self_vtables={}\\}",
self.trait_vtables.repr(tcx),
self.self_vtables.repr(tcx))
}
}
-pub type impl_vtable_map = RefCell<HashMap<ast::DefId, impl_res>>;
+pub type impl_vtable_map = RefCell<DefIdMap<impl_res>>;
-pub struct CrateCtxt {
+pub struct CrateCtxt<'a> {
// A mapping from method call sites to traits that have that method.
trait_map: resolve::TraitMap,
- method_map: method_map,
+ method_map: MethodMap,
vtable_map: vtable_map,
- tcx: ty::ctxt
+ tcx: &'a ty::ctxt
}
// Functions that write types into the node type table
-pub fn write_ty_to_tcx(tcx: ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
+pub fn write_ty_to_tcx(tcx: &ty::ctxt, node_id: ast::NodeId, ty: ty::t) {
debug!("write_ty_to_tcx({}, {})", node_id, ppaux::ty_to_str(tcx, ty));
assert!(!ty::type_needs_infer(ty));
- let mut node_types = tcx.node_types.borrow_mut();
- node_types.get().insert(node_id as uint, ty);
+ tcx.node_types.borrow_mut().insert(node_id as uint, ty);
}
-pub fn write_substs_to_tcx(tcx: ty::ctxt,
+pub fn write_substs_to_tcx(tcx: &ty::ctxt,
node_id: ast::NodeId,
- substs: ~[ty::t]) {
+ substs: Vec<ty::t> ) {
if substs.len() > 0u {
debug!("write_substs_to_tcx({}, {:?})", node_id,
substs.map(|t| ppaux::ty_to_str(tcx, *t)));
assert!(substs.iter().all(|t| !ty::type_needs_infer(*t)));
- let mut node_type_substs = tcx.node_type_substs.borrow_mut();
- node_type_substs.get().insert(node_id, substs);
+ tcx.node_type_substs.borrow_mut().insert(node_id, substs);
}
}
-pub fn write_tpt_to_tcx(tcx: ty::ctxt,
+pub fn write_tpt_to_tcx(tcx: &ty::ctxt,
node_id: ast::NodeId,
tpt: &ty::ty_param_substs_and_ty) {
write_ty_to_tcx(tcx, node_id, tpt.ty);
}
}
-pub fn lookup_def_tcx(tcx: ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
- let def_map = tcx.def_map.borrow();
- match def_map.get().find(&id) {
+pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
+ match tcx.def_map.borrow().find(&id) {
Some(&x) => x,
_ => {
tcx.sess.span_fatal(sp, "internal error looking up a definition")
pub fn no_params(t: ty::t) -> ty::ty_param_bounds_and_ty {
ty::ty_param_bounds_and_ty {
- generics: ty::Generics {type_param_defs: Rc::new(~[]),
- region_param_defs: Rc::new(~[])},
+ generics: ty::Generics {type_param_defs: Rc::new(Vec::new()),
+ region_param_defs: Rc::new(Vec::new())},
ty: t
}
}
-pub fn require_same_types(tcx: ty::ctxt,
+pub fn require_same_types(tcx: &ty::ctxt,
maybe_infcx: Option<&infer::InferCtxt>,
t1_is_expected: bool,
span: Span,
// corresponding ty::Region
pub type isr_alist = @List<(ty::BoundRegion, ty::Region)>;
-trait get_and_find_region {
- fn get(&self, br: ty::BoundRegion) -> ty::Region;
- fn find(&self, br: ty::BoundRegion) -> Option<ty::Region>;
+trait get_region<'a, T:'static> {
+ fn get(&'a self, br: ty::BoundRegion) -> ty::Region;
}
-impl get_and_find_region for isr_alist {
- fn get(&self, br: ty::BoundRegion) -> ty::Region {
- self.find(br).unwrap()
- }
-
- fn find(&self, br: ty::BoundRegion) -> Option<ty::Region> {
- let mut ret = None;
- list::each(*self, |isr| {
+impl<'a, T:'static> get_region <'a, T> for isr_alist {
+ fn get(&'a self, br: ty::BoundRegion) -> ty::Region {
+ let mut region = None;
+ for isr in self.iter() {
let (isr_br, isr_r) = *isr;
- if isr_br == br { ret = Some(isr_r); false } else { true }
- });
- ret
+ if isr_br == br { region = Some(isr_r); break; }
+ };
+ region.unwrap()
}
}
abis: abi::AbiSet::Rust(),
sig: ty::FnSig {
binder_id: main_id,
- inputs: ~[],
+ inputs: Vec::new(),
output: ty::mk_nil(),
variadic: false
}
abis: abi::AbiSet::Rust(),
sig: ty::FnSig {
binder_id: start_id,
- inputs: ~[
+ inputs: vec!(
ty::mk_int(),
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
- ],
+ ),
output: ty::mk_int(),
variadic: false
}
}
}
-pub fn check_crate(tcx: ty::ctxt,
+pub fn check_crate(tcx: &ty::ctxt,
trait_map: resolve::TraitMap,
krate: &ast::Crate)
- -> (method_map, vtable_map) {
+ -> (MethodMap, vtable_map) {
let time_passes = tcx.sess.time_passes();
- let ccx = @CrateCtxt {
+ let ccx = CrateCtxt {
trait_map: trait_map,
- method_map: @RefCell::new(HashMap::new()),
- vtable_map: @RefCell::new(HashMap::new()),
+ method_map: @RefCell::new(FnvHashMap::new()),
+ vtable_map: @RefCell::new(FnvHashMap::new()),
tcx: tcx
};
time(time_passes, "type collecting", (), |_|
- collect::collect_item_types(ccx, krate));
+ collect::collect_item_types(&ccx, krate));
// this ensures that later parts of type checking can assume that items
// have valid types and not error
variance::infer_variance(tcx, krate));
time(time_passes, "coherence checking", (), |_|
- coherence::check_coherence(ccx, krate));
+ coherence::check_coherence(&ccx, krate));
time(time_passes, "type checking", (), |_|
- check::check_item_types(ccx, krate));
+ check::check_item_types(&ccx, krate));
- check_for_entry_fn(ccx);
+ check_for_entry_fn(&ccx);
tcx.sess.abort_if_errors();
(ccx.method_map, ccx.vtable_map)
}