rustc: de-@ method and vtable maps.

This commit is contained in:
Eduard Burtescu 2014-04-10 14:04:45 +03:00
parent 158d7a19b3
commit c9bf84333d
11 changed files with 210 additions and 227 deletions

View File

@ -146,8 +146,8 @@ fn encode_impl_vtables(ebml_w: &mut Encoder,
ecx: &EncodeContext,
vtables: &typeck::impl_res) {
ebml_w.start_tag(tag_item_impl_vtables);
astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_vtables);
astencode::encode_vtable_param_res(ecx, ebml_w, vtables.self_vtables);
astencode::encode_vtable_res(ecx, ebml_w, &vtables.trait_vtables);
astencode::encode_vtable_param_res(ecx, ebml_w, &vtables.self_vtables);
ebml_w.end_tag();
}

View File

@ -658,7 +658,7 @@ impl tr for MethodOrigin {
fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
ebml_w: &mut Encoder,
autoderef: u32,
dr: typeck::vtable_res) {
dr: &typeck::vtable_res) {
ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| {
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
autoderef.encode(ebml_w)
@ -671,19 +671,19 @@ fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
pub fn encode_vtable_res(ecx: &e::EncodeContext,
ebml_w: &mut Encoder,
dr: typeck::vtable_res) {
dr: &typeck::vtable_res) {
// can't autogenerate this code because automatic code of
// ty::t doesn't work, and there is no way (atm) to have
// hand-written encoding routines combine with auto-generated
// ones. perhaps we should fix this.
ebml_w.emit_from_vec(dr.as_slice(), |ebml_w, param_tables| {
Ok(encode_vtable_param_res(ecx, ebml_w, *param_tables))
Ok(encode_vtable_param_res(ecx, ebml_w, param_tables))
}).unwrap()
}
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
ebml_w: &mut Encoder,
param_tables: typeck::vtable_param_res) {
param_tables: &typeck::vtable_param_res) {
ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| {
Ok(encode_vtable_origin(ecx, ebml_w, vtable_origin))
}).unwrap()
@ -695,7 +695,7 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext,
vtable_origin: &typeck::vtable_origin) {
ebml_w.emit_enum("vtable_origin", |ebml_w| {
match *vtable_origin {
typeck::vtable_static(def_id, ref tys, vtable_res) => {
typeck::vtable_static(def_id, ref tys, ref vtable_res) => {
ebml_w.emit_enum_variant("vtable_static", 0u, 3u, |ebml_w| {
ebml_w.emit_enum_variant_arg(0u, |ebml_w| {
Ok(ebml_w.emit_def_id(def_id))
@ -756,21 +756,15 @@ impl<'a> vtable_decoder_helpers for reader::Decoder<'a> {
fn read_vtable_res(&mut self,
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
-> typeck::vtable_res {
@self.read_to_vec(|this|
Ok(this.read_vtable_param_res(tcx, cdata)))
.unwrap()
.move_iter()
.collect()
self.read_to_vec(|this| Ok(this.read_vtable_param_res(tcx, cdata)))
.unwrap().move_iter().collect()
}
fn read_vtable_param_res(&mut self,
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
-> typeck::vtable_param_res {
@self.read_to_vec(|this|
Ok(this.read_vtable_origin(tcx, cdata)))
.unwrap()
.move_iter()
.collect()
self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata)))
.unwrap().move_iter().collect()
}
fn read_vtable_origin(&mut self,
@ -1063,7 +1057,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, *dr);
encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, dr);
})
})
}
@ -1087,7 +1081,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
encode_vtable_res_with_key(ecx, ebml_w,
method_call.autoderef, *dr);
method_call.autoderef, dr);
})
})
}

View File

@ -176,14 +176,14 @@ pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, node: ExprOrMethodCall) ->
def_id.repr(bcx.tcx()), node, type_params.repr(bcx.tcx()),
vtables.repr(bcx.tcx()));
trans_fn_ref_with_vtables(bcx, def_id, node,
type_params.as_slice(),
type_params,
vtables)
}
fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
def_id: ast::DefId,
ref_id: ast::NodeId,
type_params: &[ty::t],
type_params: Vec<ty::t>,
vtables: Option<typeck::vtable_res>)
-> Callee<'a> {
Callee {bcx: bcx,
@ -206,29 +206,32 @@ fn resolve_default_method_vtables(bcx: &Block,
let param_substs = Some(@param_substs {
tys: substs.tps.clone(),
self_ty: substs.self_ty,
vtables: impl_vtables,
vtables: impl_vtables.clone(),
self_vtables: None
});
let trait_vtables_fixed = resolve_vtables_under_param_substs(
bcx.tcx(), param_substs, impl_res.trait_vtables);
let mut param_vtables = resolve_vtables_under_param_substs(
bcx.tcx(), param_substs, impl_res.trait_vtables.as_slice());
// Now we pull any vtables for parameters on the actual method.
let num_method_vtables = method.generics.type_param_defs().len();
let method_vtables = match impl_vtables {
Some(vtables) => {
match impl_vtables {
Some(ref vtables) => {
let num_impl_type_parameters =
vtables.len() - num_method_vtables;
Vec::from_slice(vtables.tailn(num_impl_type_parameters))
param_vtables.push_all(vtables.tailn(num_impl_type_parameters))
},
None => Vec::from_elem(num_method_vtables, @Vec::new())
};
let method_vtables = method_vtables.as_slice();
let param_vtables = @((*trait_vtables_fixed).clone().append(method_vtables));
None => {
param_vtables.extend(range(0, num_method_vtables).map(
|_| -> typeck::vtable_param_res {
Vec::new()
}
))
}
}
let self_vtables = resolve_param_vtables_under_param_substs(
bcx.tcx(), param_substs, impl_res.self_vtables);
bcx.tcx(), param_substs, impl_res.self_vtables.as_slice());
(param_vtables, self_vtables)
}
@ -238,7 +241,7 @@ pub fn trans_fn_ref_with_vtables(
bcx: &Block, //
def_id: ast::DefId, // def id of fn
node: ExprOrMethodCall, // node id of use of fn; may be zero if N/A
type_params: &[ty::t], // values for fn's ty params
type_params: Vec<ty::t>, // values for fn's ty params
vtables: Option<typeck::vtable_res>) // vtables for the call
-> ValueRef {
/*!
@ -273,9 +276,11 @@ pub fn trans_fn_ref_with_vtables(
// Polytype of the function item (may have type params)
let fn_tpt = ty::lookup_item_type(tcx, def_id);
let substs = ty::substs { regions: ty::ErasedRegions,
self_ty: None,
tps: /*bad*/ Vec::from_slice(type_params) };
let substs = ty::substs {
regions: ty::ErasedRegions,
self_ty: None,
tps: type_params
};
// Load the info for the appropriate trait if necessary.
match ty::trait_of_method(tcx, def_id) {
@ -318,19 +323,20 @@ pub fn trans_fn_ref_with_vtables(
// And compose them
let new_substs = first_subst.subst(tcx, &substs);
debug!("trans_fn_with_vtables - default method: \
substs = {}, trait_subst = {}, \
first_subst = {}, new_subst = {}, \
vtables = {}",
substs.repr(tcx), trait_ref.substs.repr(tcx),
first_subst.repr(tcx), new_substs.repr(tcx),
vtables.repr(tcx));
let (param_vtables, self_vtables) =
resolve_default_method_vtables(bcx, impl_id,
method, &substs, vtables);
debug!("trans_fn_with_vtables - default method: \
substs = {}, trait_subst = {}, \
first_subst = {}, new_subst = {}, \
vtables = {}, \
self_vtable = {}, param_vtables = {}",
substs.repr(tcx), trait_ref.substs.repr(tcx),
first_subst.repr(tcx), new_substs.repr(tcx),
vtables.repr(tcx),
self_vtables.repr(tcx), param_vtables.repr(tcx));
(true, source_id,
@ -352,7 +358,7 @@ pub fn trans_fn_ref_with_vtables(
// intrinsic, or is a default method. In particular, if we see an
// intrinsic that is inlined from a different crate, we want to reemit the
// intrinsic instead of trying to call it in the other crate.
let must_monomorphise = if type_params.len() > 0 || is_default {
let must_monomorphise = if substs.tps.len() > 0 || is_default {
true
} else if def_id.krate == ast::LOCAL_CRATE {
let map_node = session::expect(
@ -504,7 +510,7 @@ pub fn trans_lang_call<'a>(
trans_fn_ref_with_vtables_to_callee(bcx,
did,
0,
[],
vec!(),
None)
},
ArgVals(args),

View File

@ -797,15 +797,16 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec<ty::t> {
pub fn node_vtables(bcx: &Block, id: typeck::MethodCall)
-> Option<typeck::vtable_res> {
let vtable_map = bcx.tcx().vtable_map.borrow();
let raw_vtables = vtable_map.find(&id);
raw_vtables.map(|vts| resolve_vtables_in_fn_ctxt(bcx.fcx, *vts))
bcx.tcx().vtable_map.borrow().find(&id).map(|vts| {
resolve_vtables_in_fn_ctxt(bcx.fcx, vts.as_slice())
})
}
// Apply the typaram substitutions in the FunctionContext to some
// vtables. This should eliminate any vtable_params.
pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res)
-> typeck::vtable_res {
pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext,
vts: &[typeck::vtable_param_res])
-> typeck::vtable_res {
resolve_vtables_under_param_substs(fcx.ccx.tcx(),
fcx.param_substs,
vts)
@ -813,25 +814,25 @@ pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res
pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt,
param_substs: Option<@param_substs>,
vts: typeck::vtable_res)
-> typeck::vtable_res {
@vts.iter().map(|ds|
vts: &[typeck::vtable_param_res])
-> typeck::vtable_res {
vts.iter().map(|ds| {
resolve_param_vtables_under_param_substs(tcx,
param_substs,
*ds))
.collect()
ds.as_slice())
}).collect()
}
pub fn resolve_param_vtables_under_param_substs(
tcx: &ty::ctxt,
param_substs: Option<@param_substs>,
ds: typeck::vtable_param_res)
ds: &[typeck::vtable_origin])
-> typeck::vtable_param_res {
@ds.iter().map(
|d| resolve_vtable_under_param_substs(tcx,
param_substs,
d))
.collect()
ds.iter().map(|d| {
resolve_vtable_under_param_substs(tcx,
param_substs,
d)
}).collect()
}
@ -841,7 +842,7 @@ pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
vt: &typeck::vtable_origin)
-> typeck::vtable_origin {
match *vt {
typeck::vtable_static(trait_id, ref tys, sub) => {
typeck::vtable_static(trait_id, ref tys, ref sub) => {
let tys = match param_substs {
Some(substs) => {
tys.iter().map(|t| {
@ -855,7 +856,7 @@ pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
};
typeck::vtable_static(
trait_id, tys,
resolve_vtables_under_param_substs(tcx, param_substs, sub))
resolve_vtables_under_param_substs(tcx, param_substs, sub.as_slice()))
}
typeck::vtable_param(n_param, n_bound) => {
match param_substs {
@ -881,11 +882,11 @@ pub fn find_vtable(tcx: &ty::ctxt,
n_param, n_bound, ps.repr(tcx));
let param_bounds = match n_param {
typeck::param_self => ps.self_vtables.expect("self vtables missing"),
typeck::param_self => ps.self_vtables.as_ref().expect("self vtables missing"),
typeck::param_numbered(n) => {
let tables = ps.vtables
let tables = ps.vtables.as_ref()
.expect("vtables missing where they are needed");
*tables.get(n)
tables.get(n)
}
};
param_bounds.get(n_bound).clone()

View File

@ -193,21 +193,21 @@ pub fn trans_static_method_callee(bcx: &Block,
name={}", method_id, expr_id, token::get_name(mname));
let vtable_key = MethodCall::expr(expr_id);
let vtbls = ccx.tcx.vtable_map.borrow().get_copy(&vtable_key);
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls);
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, ccx.tcx.vtable_map.borrow()
.get(&vtable_key).as_slice());
match vtbls.get(bound_index).get(0) {
&typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
match vtbls.move_iter().nth(bound_index).unwrap().move_iter().nth(0).unwrap() {
typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t)));
let mth_id = method_with_name(ccx, impl_did, mname);
let (callee_substs, callee_origins) =
combine_impl_and_methods_tps(
bcx, mth_id, ExprId(expr_id),
rcvr_substs.as_slice(), rcvr_origins);
rcvr_substs, rcvr_origins);
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, ExprId(expr_id),
callee_substs.as_slice(),
callee_substs,
Some(callee_origins));
let callee_ty = node_id_type(bcx, expr_id);
@ -247,7 +247,7 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
-> Callee<'a> {
let _icx = push_ctxt("meth::trans_monomorphized_callee");
match vtbl {
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
let ccx = bcx.ccx();
let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident;
let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
@ -257,13 +257,13 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
let (callee_substs, callee_origins) =
combine_impl_and_methods_tps(
bcx, mth_id, MethodCall(method_call),
rcvr_substs.as_slice(), rcvr_origins);
rcvr_substs, rcvr_origins);
// translate the function
let llfn = trans_fn_ref_with_vtables(bcx,
mth_id,
MethodCall(method_call),
callee_substs.as_slice(),
callee_substs,
Some(callee_origins));
Callee { bcx: bcx, data: Fn(llfn) }
@ -277,9 +277,9 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
fn combine_impl_and_methods_tps(bcx: &Block,
mth_did: ast::DefId,
node: ExprOrMethodCall,
rcvr_substs: &[ty::t],
rcvr_substs: Vec<ty::t>,
rcvr_origins: typeck::vtable_res)
-> (Vec<ty::t> , typeck::vtable_res) {
-> (Vec<ty::t>, typeck::vtable_res) {
/*!
*
* Creates a concatenated set of substitutions which includes
@ -302,10 +302,13 @@ fn combine_impl_and_methods_tps(bcx: &Block,
let n_m_tps = method.generics.type_param_defs().len();
let node_substs = node_id_type_params(bcx, node);
debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx()));
let ty_substs
= Vec::from_slice(rcvr_substs).append(node_substs.tailn(node_substs.len() - n_m_tps));
debug!("n_m_tps={:?}", n_m_tps);
debug!("node_substs={:?}", node_substs.repr(ccx.tcx()));
let mut ty_substs = rcvr_substs;
{
let start = node_substs.len() - n_m_tps;
ty_substs.extend(node_substs.move_iter().skip(start));
}
debug!("n_m_tps={:?}", n_m_tps);
debug!("ty_substs={:?}", ty_substs.repr(ccx.tcx()));
@ -315,14 +318,20 @@ fn combine_impl_and_methods_tps(bcx: &Block,
ExprId(id) => MethodCall::expr(id),
MethodCall(method_call) => method_call
};
let vtables = node_vtables(bcx, vtable_key);
let r_m_origins = match vtables {
Some(vt) => vt,
None => @Vec::from_elem(node_substs.len(), @Vec::new())
};
let vtables
= @Vec::from_slice(rcvr_origins.as_slice())
.append(r_m_origins.tailn(r_m_origins.len() - n_m_tps));
let mut vtables = rcvr_origins;
match node_vtables(bcx, vtable_key) {
Some(vt) => {
let start = vt.len() - n_m_tps;
vtables.extend(vt.move_iter().skip(start));
}
None => {
vtables.extend(range(0, n_m_tps).map(
|_| -> typeck::vtable_param_res {
Vec::new()
}
));
}
}
(ty_substs, vtables)
}
@ -422,10 +431,10 @@ pub fn vtable_id(ccx: &CrateContext,
origin: &typeck::vtable_origin)
-> mono_id {
match origin {
&typeck::vtable_static(impl_id, ref substs, sub_vtables) => {
&typeck::vtable_static(impl_id, ref substs, ref sub_vtables) => {
let psubsts = param_substs {
tys: (*substs).clone(),
vtables: Some(sub_vtables),
vtables: Some(sub_vtables.clone()),
self_ty: None,
self_vtables: None
};
@ -443,10 +452,10 @@ pub fn vtable_id(ccx: &CrateContext,
/// Creates a returns a dynamic vtable for the given type and vtable origin.
/// This is used only for objects.
pub fn get_vtable(bcx: &Block,
self_ty: ty::t,
origins: typeck::vtable_param_res)
-> ValueRef {
fn get_vtable(bcx: &Block,
self_ty: ty::t,
origins: typeck::vtable_param_res)
-> ValueRef {
let ccx = bcx.ccx();
let _icx = push_ctxt("meth::get_vtable");
@ -458,43 +467,33 @@ pub fn get_vtable(bcx: &Block,
}
// Not in the cache. Actually build it.
let mut methods = Vec::new();
for origin in origins.iter() {
match *origin {
typeck::vtable_static(id, ref substs, sub_vtables) => {
let vtable_methods = emit_vtable_methods(bcx,
id,
substs.as_slice(),
sub_vtables);
for vtable_method in vtable_methods.move_iter() {
methods.push(vtable_method)
}
let methods = origins.move_iter().flat_map(|origin| {
match origin {
typeck::vtable_static(id, substs, sub_vtables) => {
emit_vtable_methods(bcx, id, substs, sub_vtables).move_iter()
}
_ => ccx.sess().bug("get_vtable: expected a static origin"),
}
}
});
// Generate a destructor for the vtable.
let drop_glue = glue::get_drop_glue(ccx, self_ty);
let vtable = make_vtable(ccx, drop_glue, methods.as_slice());
let vtable = make_vtable(ccx, drop_glue, methods);
ccx.vtables.borrow_mut().insert(hash_id, vtable);
return vtable;
vtable
}
/// Helper function to declare and initialize the vtable.
pub fn make_vtable(ccx: &CrateContext,
drop_glue: ValueRef,
ptrs: &[ValueRef])
-> ValueRef {
pub fn make_vtable<I: Iterator<ValueRef>>(ccx: &CrateContext,
drop_glue: ValueRef,
ptrs: I)
-> ValueRef {
let _icx = push_ctxt("meth::make_vtable");
let components: Vec<_> = Some(drop_glue).move_iter().chain(ptrs).collect();
unsafe {
let _icx = push_ctxt("meth::make_vtable");
let mut components = vec!(drop_glue);
for &ptr in ptrs.iter() {
components.push(ptr)
}
let tbl = C_struct(ccx, components.as_slice(), false);
let sym = token::gensym("vtable");
let vt_gvar = format!("vtable{}", sym).with_c_str(|buf| {
@ -509,7 +508,7 @@ pub fn make_vtable(ccx: &CrateContext,
fn emit_vtable_methods(bcx: &Block,
impl_id: ast::DefId,
substs: &[ty::t],
substs: Vec<ty::t>,
vtables: typeck::vtable_res)
-> Vec<ValueRef> {
let ccx = bcx.ccx();
@ -539,7 +538,8 @@ fn emit_vtable_methods(bcx: &Block,
token::get_ident(ident));
C_null(Type::nil(ccx).ptr_to())
} else {
trans_fn_ref_with_vtables(bcx, m_id, ExprId(0), substs, Some(vtables))
trans_fn_ref_with_vtables(bcx, m_id, ExprId(0),
substs.clone(), Some(vtables.clone()))
}
}).collect()
}
@ -576,8 +576,12 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>,
bcx = datum.store_to(bcx, llboxdest);
// Store the vtable into the second half of pair.
let res = *ccx.tcx.vtable_map.borrow().get(&MethodCall::expr(id));
let origins = *resolve_vtables_in_fn_ctxt(bcx.fcx, res).get(0);
let origins = {
let vtable_map = ccx.tcx.vtable_map.borrow();
resolve_param_vtables_under_param_substs(ccx.tcx(),
bcx.fcx.param_substs,
vtable_map.get(&MethodCall::expr(id)).get(0).as_slice())
};
let vtable = get_vtable(bcx, v_ty, origins);
let llvtabledest = GEPi(bcx, lldest, [0u, abi::trt_field_vtable]);
let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());

View File

@ -296,7 +296,7 @@ pub fn make_mono_id(ccx: &CrateContext,
// .collect() to work.
let substs_iter = substs.self_ty.iter().chain(substs.tys.iter());
let precise_param_ids: Vec<(ty::t, Option<@Vec<mono_id> >)> = match substs.vtables {
Some(vts) => {
Some(ref vts) => {
debug!("make_mono_id vtables={} substs={}",
vts.repr(ccx.tcx()), substs.tys.repr(ccx.tcx()));
let vts_iter = substs.self_vtables.iter().chain(vts.iter());

View File

@ -1134,8 +1134,8 @@ pub fn mk_ctxt(s: Session,
upvar_borrow_map: RefCell::new(HashMap::new()),
extern_const_statics: RefCell::new(DefIdMap::new()),
extern_const_variants: RefCell::new(DefIdMap::new()),
method_map: @RefCell::new(FnvHashMap::new()),
vtable_map: @RefCell::new(FnvHashMap::new()),
method_map: RefCell::new(FnvHashMap::new()),
vtable_map: RefCell::new(FnvHashMap::new()),
}
}

View File

@ -265,8 +265,8 @@ impl<'a> Inherited<'a> {
node_types: RefCell::new(NodeMap::new()),
node_type_substs: RefCell::new(NodeMap::new()),
adjustments: RefCell::new(NodeMap::new()),
method_map: @RefCell::new(FnvHashMap::new()),
vtable_map: @RefCell::new(FnvHashMap::new()),
method_map: RefCell::new(FnvHashMap::new()),
vtable_map: RefCell::new(FnvHashMap::new()),
upvar_borrow_map: RefCell::new(HashMap::new()),
}
}

View File

@ -29,7 +29,6 @@ use util::ppaux::Repr;
use collections::HashSet;
use std::cell::RefCell;
use std::result;
use syntax::ast;
use syntax::ast_util;
use syntax::codemap::Span;
@ -112,7 +111,7 @@ fn lookup_vtables(vcx: &VtableContext,
type_param_defs.repr(vcx.tcx()),
substs.repr(vcx.tcx()),
result.repr(vcx.tcx()));
@result
result
}
fn lookup_vtables_for_param(vcx: &VtableContext,
@ -170,7 +169,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
ty.repr(vcx.tcx()),
param_result.repr(vcx.tcx()));
return @param_result;
param_result
}
fn relate_trait_refs(vcx: &VtableContext,
@ -189,8 +188,8 @@ fn relate_trait_refs(vcx: &VtableContext,
infer::RelateTraitRefs(span),
act_trait_ref,
exp_trait_ref) {
result::Ok(()) => {} // Ok.
result::Err(ref err) => {
Ok(()) => {} // Ok.
Err(ref err) => {
// There is an error, but we need to do some work to make
// the message good.
// Resolve any type vars in the trait refs
@ -368,8 +367,8 @@ fn search_for_vtable(vcx: &VtableContext,
infer::RelateSelfType(span),
ty,
for_ty) {
result::Err(_) => continue,
result::Ok(()) => ()
Err(_) => continue,
Ok(()) => ()
}
// Now, in the previous example, for_ty is bound to
@ -583,7 +582,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
is_early);
if !is_early {
insert_vtables(fcx, MethodCall::expr(ex.id), @vec!(vtables));
insert_vtables(fcx, MethodCall::expr(ex.id), vec!(vtables));
}
// Now, if this is &trait, we need to link the
@ -743,7 +742,7 @@ pub fn resolve_impl(tcx: &ty::ctxt,
[],
impl_item.id);
let impl_trait_ref = @impl_trait_ref.subst(tcx, &param_env.free_substs);
let impl_trait_ref = impl_trait_ref.subst(tcx, &param_env.free_substs);
let infcx = &infer::new_infer_ctxt(tcx);
let vcx = VtableContext { infcx: infcx, param_env: &param_env };
@ -761,7 +760,7 @@ pub fn resolve_impl(tcx: &ty::ctxt,
// but that falls out of doing this.
let param_bounds = ty::ParamBounds {
builtin_bounds: ty::EmptyBuiltinBounds(),
trait_bounds: vec!(impl_trait_ref)
trait_bounds: vec!(@impl_trait_ref)
};
let t = ty::node_id_to_type(tcx, impl_item.id);
let t = t.subst(tcx, &param_env.free_substs);

View File

@ -51,44 +51,31 @@ fn resolve_type_vars_in_type(fcx: &FnCtxt, sp: Span, typ: ty::t)
}
}
fn resolve_type_vars_in_types(fcx: &FnCtxt, sp: Span, tys: &[ty::t])
-> Vec<ty::t> {
tys.iter().map(|t| {
match resolve_type_vars_in_type(fcx, sp, *t) {
Some(t1) => t1,
None => ty::mk_err()
}
}).collect()
}
fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall) {
let fcx = wbcx.fcx;
let tcx = fcx.ccx.tcx;
// Resolve any method map entry
match fcx.inh.method_map.borrow().find(&method_call) {
match fcx.inh.method_map.borrow_mut().pop(&method_call) {
Some(method) => {
debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
method_call, method.repr(tcx));
let method_ty = match resolve_type_vars_in_type(fcx, sp, method.ty) {
Some(t) => t,
None => {
wbcx.success = false;
return;
}
};
let mut new_tps = Vec::new();
for &subst in method.substs.tps.iter() {
match resolve_type_vars_in_type(fcx, sp, subst) {
Some(t) => new_tps.push(t),
None => { wbcx.success = false; return; }
}
}
let new_method = MethodCallee {
origin: method.origin,
ty: method_ty,
ty: match resolve_type_vars_in_type(fcx, sp, method.ty) {
Some(t) => t,
None => {
wbcx.success = false;
return;
}
},
substs: ty::substs {
tps: new_tps,
tps: method.substs.tps.move_iter().map(|subst| {
match resolve_type_vars_in_type(fcx, sp, subst) {
Some(t) => t,
None => { wbcx.success = false; ty::mk_err() }
}
}).collect(),
regions: ty::ErasedRegions,
self_ty: None
}
@ -101,46 +88,46 @@ fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall
fn resolve_vtable_map_entry(fcx: &FnCtxt, sp: Span, vtable_key: MethodCall) {
// Resolve any vtable map entry
match fcx.inh.vtable_map.borrow().find_copy(&vtable_key) {
match fcx.inh.vtable_map.borrow_mut().pop(&vtable_key) {
Some(origins) => {
let r_origins = resolve_origins(fcx, sp, origins);
fcx.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins);
debug!("writeback::resolve_vtable_map_entry(vtable_key={}, vtables={:?})",
vtable_key, r_origins.repr(fcx.tcx()));
fcx.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins);
}
None => {}
}
fn resolve_origins(fcx: &FnCtxt, sp: Span,
vtbls: vtable_res) -> vtable_res {
@vtbls.iter().map(|os| @os.iter().map(|origin| {
vtbls.move_iter().map(|os| os.move_iter().map(|origin| {
match origin {
&vtable_static(def_id, ref tys, origins) => {
let r_tys = resolve_type_vars_in_types(fcx,
sp,
tys.as_slice());
vtable_static(def_id, tys, origins) => {
let r_tys = tys.move_iter().map(|t| {
match resolve_type_vars_in_type(fcx, sp, t) {
Some(t1) => t1,
None => ty::mk_err()
}
}).collect();
let r_origins = resolve_origins(fcx, sp, origins);
vtable_static(def_id, r_tys, r_origins)
}
&vtable_param(n, b) => {
vtable_param(n, b)
}
vtable_param(n, b) => vtable_param(n, b)
}
}).collect()).collect()
}
}
fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
-> Option<ty::t> {
fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) {
let fcx = wbcx.fcx;
let tcx = fcx.ccx.tcx;
// Resolve any borrowings for the node with id `id`
match fcx.inh.adjustments.borrow().find_copy(&id) {
None => (),
let resolved_adj = match fcx.inh.adjustments.borrow_mut().pop(&id) {
None => None,
Some(adjustment) => {
match *adjustment {
Some(match *adjustment {
ty::AutoAddEnv(store) => {
let r = match store {
ty::RegionTraitStore(r, _) => r,
@ -156,6 +143,8 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
format!("cannot resolve bound for closure: \
{}",
infer::fixup_err_to_str(e)));
wbcx.success = false;
return;
}
Ok(r1) => {
// FIXME(eddyb) #2190 Allow only statically resolved
@ -170,15 +159,12 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
"cannot coerce non-statically resolved bare fn")
}
let resolved_adj = @ty::AutoAddEnv(match store {
ty::AutoAddEnv(match store {
ty::RegionTraitStore(..) => {
ty::RegionTraitStore(r1, ast::MutMutable)
}
ty::UniqTraitStore => ty::UniqTraitStore
});
debug!("Adjustments for node {}: {:?}",
id, resolved_adj);
tcx.adjustments.borrow_mut().insert(id, resolved_adj);
})
}
}
}
@ -190,42 +176,38 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
resolve_vtable_map_entry(wbcx.fcx, sp, method_call);
}
let fixup_region = |r| {
match resolve_region(fcx.infcx(),
r,
resolve_all | force_all) {
Ok(r1) => r1,
Err(e) => {
// This should not, I think, happen.
tcx.sess.span_err(
sp,
format!("cannot resolve scope of borrow: \
{}",
infer::fixup_err_to_str(e)));
r
}
}
};
let resolved_autoref = match adj.autoref {
None => None,
Some(ref r) => Some(r.map_region(fixup_region))
};
let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adj.autoderefs,
autoref: resolved_autoref,
});
debug!("Adjustments for node {}: {:?}", id, resolved_adj);
tcx.adjustments.borrow_mut().insert(id, resolved_adj);
autoref: adj.autoref.map(|r| r.map_region(|r| {
match resolve_region(fcx.infcx(), r,
resolve_all | force_all) {
Ok(r1) => r1,
Err(e) => {
// This should not, I think, happen.
tcx.sess.span_err(
sp,
format!("cannot resolve scope of borrow: \
{}",
infer::fixup_err_to_str(e)));
r
}
}
})),
})
}
ty::AutoObject(..) => {
debug!("Adjustments for node {}: {:?}", id, adjustment);
tcx.adjustments.borrow_mut().insert(id, adjustment);
}
}
adjustment => adjustment
})
}
};
debug!("Adjustments for node {}: {:?}",
id, resolved_adj);
match resolved_adj {
Some(adj) => {
tcx.adjustments.borrow_mut().insert(id, @adj);
}
None => {}
}
// Resolve the type of the node with id `id`
@ -233,26 +215,23 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
match resolve_type_vars_in_type(fcx, sp, n_ty) {
None => {
wbcx.success = false;
return None;
}
Some(t) => {
debug!("resolve_type_vars_for_node(id={}, n_ty={}, t={})",
id, ppaux::ty_to_str(tcx, n_ty), ppaux::ty_to_str(tcx, t));
write_ty_to_tcx(tcx, id, t);
let mut ret = Some(t);
fcx.opt_node_ty_substs(id, |substs| {
let mut new_tps = Vec::new();
for subst in substs.tps.iter() {
match resolve_type_vars_in_type(fcx, sp, *subst) {
Some(t) => new_tps.push(t),
None => { wbcx.success = false; ret = None; break }
None => { wbcx.success = false; break }
}
}
write_substs_to_tcx(tcx, id, new_tps);
ret.is_some()
wbcx.success
});
ret
}
}
}

View File

@ -171,11 +171,11 @@ impl MethodCall {
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
pub type MethodMap = @RefCell<FnvHashMap<MethodCall, MethodCallee>>;
pub type MethodMap = RefCell<FnvHashMap<MethodCall, MethodCallee>>;
pub type vtable_param_res = @Vec<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 = @Vec<vtable_param_res> ;
pub type vtable_res = Vec<vtable_param_res>;
#[deriving(Clone)]
pub enum vtable_origin {
@ -184,7 +184,7 @@ 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, Vec<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:
@ -215,7 +215,7 @@ impl Repr for vtable_origin {
}
}
pub type vtable_map = @RefCell<FnvHashMap<MethodCall, vtable_res>>;
pub type vtable_map = RefCell<FnvHashMap<MethodCall, vtable_res>>;
// Information about the vtable resolutions for a trait impl.