mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
rustc: de-@ method and vtable maps.
This commit is contained in:
parent
158d7a19b3
commit
c9bf84333d
@ -146,8 +146,8 @@ fn encode_impl_vtables(ebml_w: &mut Encoder,
|
|||||||
ecx: &EncodeContext,
|
ecx: &EncodeContext,
|
||||||
vtables: &typeck::impl_res) {
|
vtables: &typeck::impl_res) {
|
||||||
ebml_w.start_tag(tag_item_impl_vtables);
|
ebml_w.start_tag(tag_item_impl_vtables);
|
||||||
astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_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_param_res(ecx, ebml_w, &vtables.self_vtables);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +658,7 @@ impl tr for MethodOrigin {
|
|||||||
fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
|
fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut Encoder,
|
ebml_w: &mut Encoder,
|
||||||
autoderef: u32,
|
autoderef: u32,
|
||||||
dr: typeck::vtable_res) {
|
dr: &typeck::vtable_res) {
|
||||||
ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| {
|
ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| {
|
||||||
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
|
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
|
||||||
autoderef.encode(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,
|
pub fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut Encoder,
|
ebml_w: &mut Encoder,
|
||||||
dr: typeck::vtable_res) {
|
dr: &typeck::vtable_res) {
|
||||||
// can't autogenerate this code because automatic code of
|
// can't autogenerate this code because automatic code of
|
||||||
// ty::t doesn't work, and there is no way (atm) to have
|
// ty::t doesn't work, and there is no way (atm) to have
|
||||||
// hand-written encoding routines combine with auto-generated
|
// hand-written encoding routines combine with auto-generated
|
||||||
// ones. perhaps we should fix this.
|
// ones. perhaps we should fix this.
|
||||||
ebml_w.emit_from_vec(dr.as_slice(), |ebml_w, param_tables| {
|
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()
|
}).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
|
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut Encoder,
|
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| {
|
ebml_w.emit_from_vec(param_tables.as_slice(), |ebml_w, vtable_origin| {
|
||||||
Ok(encode_vtable_origin(ecx, ebml_w, vtable_origin))
|
Ok(encode_vtable_origin(ecx, ebml_w, vtable_origin))
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
@ -695,7 +695,7 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext,
|
|||||||
vtable_origin: &typeck::vtable_origin) {
|
vtable_origin: &typeck::vtable_origin) {
|
||||||
ebml_w.emit_enum("vtable_origin", |ebml_w| {
|
ebml_w.emit_enum("vtable_origin", |ebml_w| {
|
||||||
match *vtable_origin {
|
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("vtable_static", 0u, 3u, |ebml_w| {
|
||||||
ebml_w.emit_enum_variant_arg(0u, |ebml_w| {
|
ebml_w.emit_enum_variant_arg(0u, |ebml_w| {
|
||||||
Ok(ebml_w.emit_def_id(def_id))
|
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,
|
fn read_vtable_res(&mut self,
|
||||||
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
||||||
-> typeck::vtable_res {
|
-> typeck::vtable_res {
|
||||||
@self.read_to_vec(|this|
|
self.read_to_vec(|this| Ok(this.read_vtable_param_res(tcx, cdata)))
|
||||||
Ok(this.read_vtable_param_res(tcx, cdata)))
|
.unwrap().move_iter().collect()
|
||||||
.unwrap()
|
|
||||||
.move_iter()
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vtable_param_res(&mut self,
|
fn read_vtable_param_res(&mut self,
|
||||||
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
||||||
-> typeck::vtable_param_res {
|
-> typeck::vtable_param_res {
|
||||||
@self.read_to_vec(|this|
|
self.read_to_vec(|this| Ok(this.read_vtable_origin(tcx, cdata)))
|
||||||
Ok(this.read_vtable_origin(tcx, cdata)))
|
.unwrap().move_iter().collect()
|
||||||
.unwrap()
|
|
||||||
.move_iter()
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_vtable_origin(&mut self,
|
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.tag(c::tag_table_vtable_map, |ebml_w| {
|
||||||
ebml_w.id(id);
|
ebml_w.id(id);
|
||||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
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.id(id);
|
||||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
encode_vtable_res_with_key(ecx, ebml_w,
|
encode_vtable_res_with_key(ecx, ebml_w,
|
||||||
method_call.autoderef, *dr);
|
method_call.autoderef, dr);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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()),
|
def_id.repr(bcx.tcx()), node, type_params.repr(bcx.tcx()),
|
||||||
vtables.repr(bcx.tcx()));
|
vtables.repr(bcx.tcx()));
|
||||||
trans_fn_ref_with_vtables(bcx, def_id, node,
|
trans_fn_ref_with_vtables(bcx, def_id, node,
|
||||||
type_params.as_slice(),
|
type_params,
|
||||||
vtables)
|
vtables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
|
fn trans_fn_ref_with_vtables_to_callee<'a>(bcx: &'a Block<'a>,
|
||||||
def_id: ast::DefId,
|
def_id: ast::DefId,
|
||||||
ref_id: ast::NodeId,
|
ref_id: ast::NodeId,
|
||||||
type_params: &[ty::t],
|
type_params: Vec<ty::t>,
|
||||||
vtables: Option<typeck::vtable_res>)
|
vtables: Option<typeck::vtable_res>)
|
||||||
-> Callee<'a> {
|
-> Callee<'a> {
|
||||||
Callee {bcx: bcx,
|
Callee {bcx: bcx,
|
||||||
@ -206,29 +206,32 @@ fn resolve_default_method_vtables(bcx: &Block,
|
|||||||
let param_substs = Some(@param_substs {
|
let param_substs = Some(@param_substs {
|
||||||
tys: substs.tps.clone(),
|
tys: substs.tps.clone(),
|
||||||
self_ty: substs.self_ty,
|
self_ty: substs.self_ty,
|
||||||
vtables: impl_vtables,
|
vtables: impl_vtables.clone(),
|
||||||
self_vtables: None
|
self_vtables: None
|
||||||
});
|
});
|
||||||
|
|
||||||
let trait_vtables_fixed = resolve_vtables_under_param_substs(
|
let mut param_vtables = resolve_vtables_under_param_substs(
|
||||||
bcx.tcx(), param_substs, impl_res.trait_vtables);
|
bcx.tcx(), param_substs, impl_res.trait_vtables.as_slice());
|
||||||
|
|
||||||
// Now we pull any vtables for parameters on the actual method.
|
// Now we pull any vtables for parameters on the actual method.
|
||||||
let num_method_vtables = method.generics.type_param_defs().len();
|
let num_method_vtables = method.generics.type_param_defs().len();
|
||||||
let method_vtables = match impl_vtables {
|
match impl_vtables {
|
||||||
Some(vtables) => {
|
Some(ref vtables) => {
|
||||||
let num_impl_type_parameters =
|
let num_impl_type_parameters =
|
||||||
vtables.len() - num_method_vtables;
|
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())
|
None => {
|
||||||
};
|
param_vtables.extend(range(0, num_method_vtables).map(
|
||||||
|
|_| -> typeck::vtable_param_res {
|
||||||
let method_vtables = method_vtables.as_slice();
|
Vec::new()
|
||||||
let param_vtables = @((*trait_vtables_fixed).clone().append(method_vtables));
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let self_vtables = resolve_param_vtables_under_param_substs(
|
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)
|
(param_vtables, self_vtables)
|
||||||
}
|
}
|
||||||
@ -238,7 +241,7 @@ pub fn trans_fn_ref_with_vtables(
|
|||||||
bcx: &Block, //
|
bcx: &Block, //
|
||||||
def_id: ast::DefId, // def id of fn
|
def_id: ast::DefId, // def id of fn
|
||||||
node: ExprOrMethodCall, // node id of use of fn; may be zero if N/A
|
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
|
vtables: Option<typeck::vtable_res>) // vtables for the call
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
/*!
|
/*!
|
||||||
@ -273,9 +276,11 @@ pub fn trans_fn_ref_with_vtables(
|
|||||||
// Polytype of the function item (may have type params)
|
// Polytype of the function item (may have type params)
|
||||||
let fn_tpt = ty::lookup_item_type(tcx, def_id);
|
let fn_tpt = ty::lookup_item_type(tcx, def_id);
|
||||||
|
|
||||||
let substs = ty::substs { regions: ty::ErasedRegions,
|
let substs = ty::substs {
|
||||||
self_ty: None,
|
regions: ty::ErasedRegions,
|
||||||
tps: /*bad*/ Vec::from_slice(type_params) };
|
self_ty: None,
|
||||||
|
tps: type_params
|
||||||
|
};
|
||||||
|
|
||||||
// Load the info for the appropriate trait if necessary.
|
// Load the info for the appropriate trait if necessary.
|
||||||
match ty::trait_of_method(tcx, def_id) {
|
match ty::trait_of_method(tcx, def_id) {
|
||||||
@ -318,19 +323,20 @@ pub fn trans_fn_ref_with_vtables(
|
|||||||
// And compose them
|
// And compose them
|
||||||
let new_substs = first_subst.subst(tcx, &substs);
|
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) =
|
let (param_vtables, self_vtables) =
|
||||||
resolve_default_method_vtables(bcx, impl_id,
|
resolve_default_method_vtables(bcx, impl_id,
|
||||||
method, &substs, vtables);
|
method, &substs, vtables);
|
||||||
|
|
||||||
debug!("trans_fn_with_vtables - default method: \
|
debug!("trans_fn_with_vtables - default method: \
|
||||||
substs = {}, trait_subst = {}, \
|
|
||||||
first_subst = {}, new_subst = {}, \
|
|
||||||
vtables = {}, \
|
|
||||||
self_vtable = {}, param_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));
|
self_vtables.repr(tcx), param_vtables.repr(tcx));
|
||||||
|
|
||||||
(true, source_id,
|
(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, 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 that is inlined from a different crate, we want to reemit the
|
||||||
// intrinsic instead of trying to call it in the other crate.
|
// 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
|
true
|
||||||
} else if def_id.krate == ast::LOCAL_CRATE {
|
} else if def_id.krate == ast::LOCAL_CRATE {
|
||||||
let map_node = session::expect(
|
let map_node = session::expect(
|
||||||
@ -504,7 +510,7 @@ pub fn trans_lang_call<'a>(
|
|||||||
trans_fn_ref_with_vtables_to_callee(bcx,
|
trans_fn_ref_with_vtables_to_callee(bcx,
|
||||||
did,
|
did,
|
||||||
0,
|
0,
|
||||||
[],
|
vec!(),
|
||||||
None)
|
None)
|
||||||
},
|
},
|
||||||
ArgVals(args),
|
ArgVals(args),
|
||||||
|
@ -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)
|
pub fn node_vtables(bcx: &Block, id: typeck::MethodCall)
|
||||||
-> Option<typeck::vtable_res> {
|
-> Option<typeck::vtable_res> {
|
||||||
let vtable_map = bcx.tcx().vtable_map.borrow();
|
bcx.tcx().vtable_map.borrow().find(&id).map(|vts| {
|
||||||
let raw_vtables = vtable_map.find(&id);
|
resolve_vtables_in_fn_ctxt(bcx.fcx, vts.as_slice())
|
||||||
raw_vtables.map(|vts| resolve_vtables_in_fn_ctxt(bcx.fcx, *vts))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the typaram substitutions in the FunctionContext to some
|
// Apply the typaram substitutions in the FunctionContext to some
|
||||||
// vtables. This should eliminate any vtable_params.
|
// vtables. This should eliminate any vtable_params.
|
||||||
pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext, vts: typeck::vtable_res)
|
pub fn resolve_vtables_in_fn_ctxt(fcx: &FunctionContext,
|
||||||
-> typeck::vtable_res {
|
vts: &[typeck::vtable_param_res])
|
||||||
|
-> typeck::vtable_res {
|
||||||
resolve_vtables_under_param_substs(fcx.ccx.tcx(),
|
resolve_vtables_under_param_substs(fcx.ccx.tcx(),
|
||||||
fcx.param_substs,
|
fcx.param_substs,
|
||||||
vts)
|
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,
|
pub fn resolve_vtables_under_param_substs(tcx: &ty::ctxt,
|
||||||
param_substs: Option<@param_substs>,
|
param_substs: Option<@param_substs>,
|
||||||
vts: typeck::vtable_res)
|
vts: &[typeck::vtable_param_res])
|
||||||
-> typeck::vtable_res {
|
-> typeck::vtable_res {
|
||||||
@vts.iter().map(|ds|
|
vts.iter().map(|ds| {
|
||||||
resolve_param_vtables_under_param_substs(tcx,
|
resolve_param_vtables_under_param_substs(tcx,
|
||||||
param_substs,
|
param_substs,
|
||||||
*ds))
|
ds.as_slice())
|
||||||
.collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_param_vtables_under_param_substs(
|
pub fn resolve_param_vtables_under_param_substs(
|
||||||
tcx: &ty::ctxt,
|
tcx: &ty::ctxt,
|
||||||
param_substs: Option<@param_substs>,
|
param_substs: Option<@param_substs>,
|
||||||
ds: typeck::vtable_param_res)
|
ds: &[typeck::vtable_origin])
|
||||||
-> typeck::vtable_param_res {
|
-> typeck::vtable_param_res {
|
||||||
@ds.iter().map(
|
ds.iter().map(|d| {
|
||||||
|d| resolve_vtable_under_param_substs(tcx,
|
resolve_vtable_under_param_substs(tcx,
|
||||||
param_substs,
|
param_substs,
|
||||||
d))
|
d)
|
||||||
.collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -841,7 +842,7 @@ pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
|
|||||||
vt: &typeck::vtable_origin)
|
vt: &typeck::vtable_origin)
|
||||||
-> typeck::vtable_origin {
|
-> typeck::vtable_origin {
|
||||||
match *vt {
|
match *vt {
|
||||||
typeck::vtable_static(trait_id, ref tys, sub) => {
|
typeck::vtable_static(trait_id, ref tys, ref sub) => {
|
||||||
let tys = match param_substs {
|
let tys = match param_substs {
|
||||||
Some(substs) => {
|
Some(substs) => {
|
||||||
tys.iter().map(|t| {
|
tys.iter().map(|t| {
|
||||||
@ -855,7 +856,7 @@ pub fn resolve_vtable_under_param_substs(tcx: &ty::ctxt,
|
|||||||
};
|
};
|
||||||
typeck::vtable_static(
|
typeck::vtable_static(
|
||||||
trait_id, tys,
|
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) => {
|
typeck::vtable_param(n_param, n_bound) => {
|
||||||
match param_substs {
|
match param_substs {
|
||||||
@ -881,11 +882,11 @@ pub fn find_vtable(tcx: &ty::ctxt,
|
|||||||
n_param, n_bound, ps.repr(tcx));
|
n_param, n_bound, ps.repr(tcx));
|
||||||
|
|
||||||
let param_bounds = match n_param {
|
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) => {
|
typeck::param_numbered(n) => {
|
||||||
let tables = ps.vtables
|
let tables = ps.vtables.as_ref()
|
||||||
.expect("vtables missing where they are needed");
|
.expect("vtables missing where they are needed");
|
||||||
*tables.get(n)
|
tables.get(n)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
param_bounds.get(n_bound).clone()
|
param_bounds.get(n_bound).clone()
|
||||||
|
@ -193,21 +193,21 @@ pub fn trans_static_method_callee(bcx: &Block,
|
|||||||
name={}", method_id, expr_id, token::get_name(mname));
|
name={}", method_id, expr_id, token::get_name(mname));
|
||||||
|
|
||||||
let vtable_key = MethodCall::expr(expr_id);
|
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, ccx.tcx.vtable_map.borrow()
|
||||||
let vtbls = resolve_vtables_in_fn_ctxt(bcx.fcx, vtbls);
|
.get(&vtable_key).as_slice());
|
||||||
|
|
||||||
match vtbls.get(bound_index).get(0) {
|
match vtbls.move_iter().nth(bound_index).unwrap().move_iter().nth(0).unwrap() {
|
||||||
&typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
|
typeck::vtable_static(impl_did, rcvr_substs, rcvr_origins) => {
|
||||||
assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t)));
|
assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t)));
|
||||||
|
|
||||||
let mth_id = method_with_name(ccx, impl_did, mname);
|
let mth_id = method_with_name(ccx, impl_did, mname);
|
||||||
let (callee_substs, callee_origins) =
|
let (callee_substs, callee_origins) =
|
||||||
combine_impl_and_methods_tps(
|
combine_impl_and_methods_tps(
|
||||||
bcx, mth_id, ExprId(expr_id),
|
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),
|
let llfn = trans_fn_ref_with_vtables(bcx, mth_id, ExprId(expr_id),
|
||||||
callee_substs.as_slice(),
|
callee_substs,
|
||||||
Some(callee_origins));
|
Some(callee_origins));
|
||||||
|
|
||||||
let callee_ty = node_id_type(bcx, expr_id);
|
let callee_ty = node_id_type(bcx, expr_id);
|
||||||
@ -247,7 +247,7 @@ fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
|
|||||||
-> Callee<'a> {
|
-> Callee<'a> {
|
||||||
let _icx = push_ctxt("meth::trans_monomorphized_callee");
|
let _icx = push_ctxt("meth::trans_monomorphized_callee");
|
||||||
match vtbl {
|
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 ccx = bcx.ccx();
|
||||||
let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident;
|
let mname = ty::trait_method(ccx.tcx(), trait_id, n_method).ident;
|
||||||
let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
|
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) =
|
let (callee_substs, callee_origins) =
|
||||||
combine_impl_and_methods_tps(
|
combine_impl_and_methods_tps(
|
||||||
bcx, mth_id, MethodCall(method_call),
|
bcx, mth_id, MethodCall(method_call),
|
||||||
rcvr_substs.as_slice(), rcvr_origins);
|
rcvr_substs, rcvr_origins);
|
||||||
|
|
||||||
// translate the function
|
// translate the function
|
||||||
let llfn = trans_fn_ref_with_vtables(bcx,
|
let llfn = trans_fn_ref_with_vtables(bcx,
|
||||||
mth_id,
|
mth_id,
|
||||||
MethodCall(method_call),
|
MethodCall(method_call),
|
||||||
callee_substs.as_slice(),
|
callee_substs,
|
||||||
Some(callee_origins));
|
Some(callee_origins));
|
||||||
|
|
||||||
Callee { bcx: bcx, data: Fn(llfn) }
|
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,
|
fn combine_impl_and_methods_tps(bcx: &Block,
|
||||||
mth_did: ast::DefId,
|
mth_did: ast::DefId,
|
||||||
node: ExprOrMethodCall,
|
node: ExprOrMethodCall,
|
||||||
rcvr_substs: &[ty::t],
|
rcvr_substs: Vec<ty::t>,
|
||||||
rcvr_origins: typeck::vtable_res)
|
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
|
* 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 n_m_tps = method.generics.type_param_defs().len();
|
||||||
let node_substs = node_id_type_params(bcx, node);
|
let node_substs = node_id_type_params(bcx, node);
|
||||||
debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx()));
|
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()));
|
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()));
|
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),
|
ExprId(id) => MethodCall::expr(id),
|
||||||
MethodCall(method_call) => method_call
|
MethodCall(method_call) => method_call
|
||||||
};
|
};
|
||||||
let vtables = node_vtables(bcx, vtable_key);
|
let mut vtables = rcvr_origins;
|
||||||
let r_m_origins = match vtables {
|
match node_vtables(bcx, vtable_key) {
|
||||||
Some(vt) => vt,
|
Some(vt) => {
|
||||||
None => @Vec::from_elem(node_substs.len(), @Vec::new())
|
let start = vt.len() - n_m_tps;
|
||||||
};
|
vtables.extend(vt.move_iter().skip(start));
|
||||||
let vtables
|
}
|
||||||
= @Vec::from_slice(rcvr_origins.as_slice())
|
None => {
|
||||||
.append(r_m_origins.tailn(r_m_origins.len() - n_m_tps));
|
vtables.extend(range(0, n_m_tps).map(
|
||||||
|
|_| -> typeck::vtable_param_res {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(ty_substs, vtables)
|
(ty_substs, vtables)
|
||||||
}
|
}
|
||||||
@ -422,10 +431,10 @@ pub fn vtable_id(ccx: &CrateContext,
|
|||||||
origin: &typeck::vtable_origin)
|
origin: &typeck::vtable_origin)
|
||||||
-> mono_id {
|
-> mono_id {
|
||||||
match origin {
|
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 {
|
let psubsts = param_substs {
|
||||||
tys: (*substs).clone(),
|
tys: (*substs).clone(),
|
||||||
vtables: Some(sub_vtables),
|
vtables: Some(sub_vtables.clone()),
|
||||||
self_ty: None,
|
self_ty: None,
|
||||||
self_vtables: 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.
|
/// Creates a returns a dynamic vtable for the given type and vtable origin.
|
||||||
/// This is used only for objects.
|
/// This is used only for objects.
|
||||||
pub fn get_vtable(bcx: &Block,
|
fn get_vtable(bcx: &Block,
|
||||||
self_ty: ty::t,
|
self_ty: ty::t,
|
||||||
origins: typeck::vtable_param_res)
|
origins: typeck::vtable_param_res)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
let _icx = push_ctxt("meth::get_vtable");
|
let _icx = push_ctxt("meth::get_vtable");
|
||||||
|
|
||||||
@ -458,43 +467,33 @@ pub fn get_vtable(bcx: &Block,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not in the cache. Actually build it.
|
// Not in the cache. Actually build it.
|
||||||
let mut methods = Vec::new();
|
let methods = origins.move_iter().flat_map(|origin| {
|
||||||
for origin in origins.iter() {
|
match origin {
|
||||||
match *origin {
|
typeck::vtable_static(id, substs, sub_vtables) => {
|
||||||
typeck::vtable_static(id, ref substs, sub_vtables) => {
|
emit_vtable_methods(bcx, id, substs, sub_vtables).move_iter()
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => ccx.sess().bug("get_vtable: expected a static origin"),
|
_ => ccx.sess().bug("get_vtable: expected a static origin"),
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// Generate a destructor for the vtable.
|
// Generate a destructor for the vtable.
|
||||||
let drop_glue = glue::get_drop_glue(ccx, self_ty);
|
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);
|
ccx.vtables.borrow_mut().insert(hash_id, vtable);
|
||||||
return vtable;
|
vtable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to declare and initialize the vtable.
|
/// Helper function to declare and initialize the vtable.
|
||||||
pub fn make_vtable(ccx: &CrateContext,
|
pub fn make_vtable<I: Iterator<ValueRef>>(ccx: &CrateContext,
|
||||||
drop_glue: ValueRef,
|
drop_glue: ValueRef,
|
||||||
ptrs: &[ValueRef])
|
ptrs: I)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
|
let _icx = push_ctxt("meth::make_vtable");
|
||||||
|
|
||||||
|
let components: Vec<_> = Some(drop_glue).move_iter().chain(ptrs).collect();
|
||||||
|
|
||||||
unsafe {
|
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 tbl = C_struct(ccx, components.as_slice(), false);
|
||||||
let sym = token::gensym("vtable");
|
let sym = token::gensym("vtable");
|
||||||
let vt_gvar = format!("vtable{}", sym).with_c_str(|buf| {
|
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,
|
fn emit_vtable_methods(bcx: &Block,
|
||||||
impl_id: ast::DefId,
|
impl_id: ast::DefId,
|
||||||
substs: &[ty::t],
|
substs: Vec<ty::t>,
|
||||||
vtables: typeck::vtable_res)
|
vtables: typeck::vtable_res)
|
||||||
-> Vec<ValueRef> {
|
-> Vec<ValueRef> {
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
@ -539,7 +538,8 @@ fn emit_vtable_methods(bcx: &Block,
|
|||||||
token::get_ident(ident));
|
token::get_ident(ident));
|
||||||
C_null(Type::nil(ccx).ptr_to())
|
C_null(Type::nil(ccx).ptr_to())
|
||||||
} else {
|
} 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()
|
}).collect()
|
||||||
}
|
}
|
||||||
@ -576,8 +576,12 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>,
|
|||||||
bcx = datum.store_to(bcx, llboxdest);
|
bcx = datum.store_to(bcx, llboxdest);
|
||||||
|
|
||||||
// Store the vtable into the second half of pair.
|
// Store the vtable into the second half of pair.
|
||||||
let res = *ccx.tcx.vtable_map.borrow().get(&MethodCall::expr(id));
|
let origins = {
|
||||||
let origins = *resolve_vtables_in_fn_ctxt(bcx.fcx, res).get(0);
|
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 vtable = get_vtable(bcx, v_ty, origins);
|
||||||
let llvtabledest = GEPi(bcx, lldest, [0u, abi::trt_field_vtable]);
|
let llvtabledest = GEPi(bcx, lldest, [0u, abi::trt_field_vtable]);
|
||||||
let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
|
let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
|
||||||
|
@ -296,7 +296,7 @@ pub fn make_mono_id(ccx: &CrateContext,
|
|||||||
// .collect() to work.
|
// .collect() to work.
|
||||||
let substs_iter = substs.self_ty.iter().chain(substs.tys.iter());
|
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 {
|
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={}",
|
debug!("make_mono_id vtables={} substs={}",
|
||||||
vts.repr(ccx.tcx()), substs.tys.repr(ccx.tcx()));
|
vts.repr(ccx.tcx()), substs.tys.repr(ccx.tcx()));
|
||||||
let vts_iter = substs.self_vtables.iter().chain(vts.iter());
|
let vts_iter = substs.self_vtables.iter().chain(vts.iter());
|
||||||
|
@ -1134,8 +1134,8 @@ pub fn mk_ctxt(s: Session,
|
|||||||
upvar_borrow_map: RefCell::new(HashMap::new()),
|
upvar_borrow_map: RefCell::new(HashMap::new()),
|
||||||
extern_const_statics: RefCell::new(DefIdMap::new()),
|
extern_const_statics: RefCell::new(DefIdMap::new()),
|
||||||
extern_const_variants: RefCell::new(DefIdMap::new()),
|
extern_const_variants: RefCell::new(DefIdMap::new()),
|
||||||
method_map: @RefCell::new(FnvHashMap::new()),
|
method_map: RefCell::new(FnvHashMap::new()),
|
||||||
vtable_map: @RefCell::new(FnvHashMap::new()),
|
vtable_map: RefCell::new(FnvHashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,8 +265,8 @@ impl<'a> Inherited<'a> {
|
|||||||
node_types: RefCell::new(NodeMap::new()),
|
node_types: RefCell::new(NodeMap::new()),
|
||||||
node_type_substs: RefCell::new(NodeMap::new()),
|
node_type_substs: RefCell::new(NodeMap::new()),
|
||||||
adjustments: RefCell::new(NodeMap::new()),
|
adjustments: RefCell::new(NodeMap::new()),
|
||||||
method_map: @RefCell::new(FnvHashMap::new()),
|
method_map: RefCell::new(FnvHashMap::new()),
|
||||||
vtable_map: @RefCell::new(FnvHashMap::new()),
|
vtable_map: RefCell::new(FnvHashMap::new()),
|
||||||
upvar_borrow_map: RefCell::new(HashMap::new()),
|
upvar_borrow_map: RefCell::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ use util::ppaux::Repr;
|
|||||||
|
|
||||||
use collections::HashSet;
|
use collections::HashSet;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::result;
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_util;
|
use syntax::ast_util;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
@ -112,7 +111,7 @@ fn lookup_vtables(vcx: &VtableContext,
|
|||||||
type_param_defs.repr(vcx.tcx()),
|
type_param_defs.repr(vcx.tcx()),
|
||||||
substs.repr(vcx.tcx()),
|
substs.repr(vcx.tcx()),
|
||||||
result.repr(vcx.tcx()));
|
result.repr(vcx.tcx()));
|
||||||
@result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_vtables_for_param(vcx: &VtableContext,
|
fn lookup_vtables_for_param(vcx: &VtableContext,
|
||||||
@ -170,7 +169,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
|
|||||||
ty.repr(vcx.tcx()),
|
ty.repr(vcx.tcx()),
|
||||||
param_result.repr(vcx.tcx()));
|
param_result.repr(vcx.tcx()));
|
||||||
|
|
||||||
return @param_result;
|
param_result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relate_trait_refs(vcx: &VtableContext,
|
fn relate_trait_refs(vcx: &VtableContext,
|
||||||
@ -189,8 +188,8 @@ fn relate_trait_refs(vcx: &VtableContext,
|
|||||||
infer::RelateTraitRefs(span),
|
infer::RelateTraitRefs(span),
|
||||||
act_trait_ref,
|
act_trait_ref,
|
||||||
exp_trait_ref) {
|
exp_trait_ref) {
|
||||||
result::Ok(()) => {} // Ok.
|
Ok(()) => {} // Ok.
|
||||||
result::Err(ref err) => {
|
Err(ref err) => {
|
||||||
// There is an error, but we need to do some work to make
|
// There is an error, but we need to do some work to make
|
||||||
// the message good.
|
// the message good.
|
||||||
// Resolve any type vars in the trait refs
|
// Resolve any type vars in the trait refs
|
||||||
@ -368,8 +367,8 @@ fn search_for_vtable(vcx: &VtableContext,
|
|||||||
infer::RelateSelfType(span),
|
infer::RelateSelfType(span),
|
||||||
ty,
|
ty,
|
||||||
for_ty) {
|
for_ty) {
|
||||||
result::Err(_) => continue,
|
Err(_) => continue,
|
||||||
result::Ok(()) => ()
|
Ok(()) => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, in the previous example, for_ty is bound to
|
// 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);
|
is_early);
|
||||||
|
|
||||||
if !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
|
// Now, if this is &trait, we need to link the
|
||||||
@ -743,7 +742,7 @@ pub fn resolve_impl(tcx: &ty::ctxt,
|
|||||||
[],
|
[],
|
||||||
impl_item.id);
|
impl_item.id);
|
||||||
|
|
||||||
let impl_trait_ref = @impl_trait_ref.subst(tcx, ¶m_env.free_substs);
|
let impl_trait_ref = impl_trait_ref.subst(tcx, ¶m_env.free_substs);
|
||||||
|
|
||||||
let infcx = &infer::new_infer_ctxt(tcx);
|
let infcx = &infer::new_infer_ctxt(tcx);
|
||||||
let vcx = VtableContext { infcx: infcx, param_env: ¶m_env };
|
let vcx = VtableContext { infcx: infcx, param_env: ¶m_env };
|
||||||
@ -761,7 +760,7 @@ pub fn resolve_impl(tcx: &ty::ctxt,
|
|||||||
// but that falls out of doing this.
|
// but that falls out of doing this.
|
||||||
let param_bounds = ty::ParamBounds {
|
let param_bounds = ty::ParamBounds {
|
||||||
builtin_bounds: ty::EmptyBuiltinBounds(),
|
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 = ty::node_id_to_type(tcx, impl_item.id);
|
||||||
let t = t.subst(tcx, ¶m_env.free_substs);
|
let t = t.subst(tcx, ¶m_env.free_substs);
|
||||||
|
@ -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) {
|
fn resolve_method_map_entry(wbcx: &mut WbCtxt, sp: Span, method_call: MethodCall) {
|
||||||
let fcx = wbcx.fcx;
|
let fcx = wbcx.fcx;
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
|
|
||||||
// Resolve any method map entry
|
// 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) => {
|
Some(method) => {
|
||||||
debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
|
debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
|
||||||
method_call, method.repr(tcx));
|
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 {
|
let new_method = MethodCallee {
|
||||||
origin: method.origin,
|
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 {
|
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,
|
regions: ty::ErasedRegions,
|
||||||
self_ty: None
|
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) {
|
fn resolve_vtable_map_entry(fcx: &FnCtxt, sp: Span, vtable_key: MethodCall) {
|
||||||
// Resolve any vtable map entry
|
// 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) => {
|
Some(origins) => {
|
||||||
let r_origins = resolve_origins(fcx, sp, 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={:?})",
|
debug!("writeback::resolve_vtable_map_entry(vtable_key={}, vtables={:?})",
|
||||||
vtable_key, r_origins.repr(fcx.tcx()));
|
vtable_key, r_origins.repr(fcx.tcx()));
|
||||||
|
fcx.tcx().vtable_map.borrow_mut().insert(vtable_key, r_origins);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_origins(fcx: &FnCtxt, sp: Span,
|
fn resolve_origins(fcx: &FnCtxt, sp: Span,
|
||||||
vtbls: vtable_res) -> vtable_res {
|
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 {
|
match origin {
|
||||||
&vtable_static(def_id, ref tys, origins) => {
|
vtable_static(def_id, tys, origins) => {
|
||||||
let r_tys = resolve_type_vars_in_types(fcx,
|
let r_tys = tys.move_iter().map(|t| {
|
||||||
sp,
|
match resolve_type_vars_in_type(fcx, sp, t) {
|
||||||
tys.as_slice());
|
Some(t1) => t1,
|
||||||
|
None => ty::mk_err()
|
||||||
|
}
|
||||||
|
}).collect();
|
||||||
let r_origins = resolve_origins(fcx, sp, origins);
|
let r_origins = resolve_origins(fcx, sp, origins);
|
||||||
vtable_static(def_id, r_tys, r_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()
|
}).collect()).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
|
fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId) {
|
||||||
-> Option<ty::t> {
|
|
||||||
let fcx = wbcx.fcx;
|
let fcx = wbcx.fcx;
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
|
|
||||||
// Resolve any borrowings for the node with id `id`
|
// Resolve any borrowings for the node with id `id`
|
||||||
match fcx.inh.adjustments.borrow().find_copy(&id) {
|
let resolved_adj = match fcx.inh.adjustments.borrow_mut().pop(&id) {
|
||||||
None => (),
|
None => None,
|
||||||
|
|
||||||
Some(adjustment) => {
|
Some(adjustment) => {
|
||||||
match *adjustment {
|
Some(match *adjustment {
|
||||||
ty::AutoAddEnv(store) => {
|
ty::AutoAddEnv(store) => {
|
||||||
let r = match store {
|
let r = match store {
|
||||||
ty::RegionTraitStore(r, _) => r,
|
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: \
|
format!("cannot resolve bound for closure: \
|
||||||
{}",
|
{}",
|
||||||
infer::fixup_err_to_str(e)));
|
infer::fixup_err_to_str(e)));
|
||||||
|
wbcx.success = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Ok(r1) => {
|
Ok(r1) => {
|
||||||
// FIXME(eddyb) #2190 Allow only statically resolved
|
// 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")
|
"cannot coerce non-statically resolved bare fn")
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolved_adj = @ty::AutoAddEnv(match store {
|
ty::AutoAddEnv(match store {
|
||||||
ty::RegionTraitStore(..) => {
|
ty::RegionTraitStore(..) => {
|
||||||
ty::RegionTraitStore(r1, ast::MutMutable)
|
ty::RegionTraitStore(r1, ast::MutMutable)
|
||||||
}
|
}
|
||||||
ty::UniqTraitStore => ty::UniqTraitStore
|
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);
|
resolve_vtable_map_entry(wbcx.fcx, sp, method_call);
|
||||||
}
|
}
|
||||||
|
|
||||||
let fixup_region = |r| {
|
ty::AutoDerefRef(ty::AutoDerefRef {
|
||||||
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 {
|
|
||||||
autoderefs: adj.autoderefs,
|
autoderefs: adj.autoderefs,
|
||||||
autoref: resolved_autoref,
|
autoref: adj.autoref.map(|r| r.map_region(|r| {
|
||||||
});
|
match resolve_region(fcx.infcx(), r,
|
||||||
debug!("Adjustments for node {}: {:?}", id, resolved_adj);
|
resolve_all | force_all) {
|
||||||
tcx.adjustments.borrow_mut().insert(id, resolved_adj);
|
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(..) => {
|
adjustment => adjustment
|
||||||
debug!("Adjustments for node {}: {:?}", id, adjustment);
|
})
|
||||||
tcx.adjustments.borrow_mut().insert(id, 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`
|
// 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) {
|
match resolve_type_vars_in_type(fcx, sp, n_ty) {
|
||||||
None => {
|
None => {
|
||||||
wbcx.success = false;
|
wbcx.success = false;
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
debug!("resolve_type_vars_for_node(id={}, n_ty={}, 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));
|
id, ppaux::ty_to_str(tcx, n_ty), ppaux::ty_to_str(tcx, t));
|
||||||
write_ty_to_tcx(tcx, id, t);
|
write_ty_to_tcx(tcx, id, t);
|
||||||
let mut ret = Some(t);
|
|
||||||
fcx.opt_node_ty_substs(id, |substs| {
|
fcx.opt_node_ty_substs(id, |substs| {
|
||||||
let mut new_tps = Vec::new();
|
let mut new_tps = Vec::new();
|
||||||
for subst in substs.tps.iter() {
|
for subst in substs.tps.iter() {
|
||||||
match resolve_type_vars_in_type(fcx, sp, *subst) {
|
match resolve_type_vars_in_type(fcx, sp, *subst) {
|
||||||
Some(t) => new_tps.push(t),
|
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);
|
write_substs_to_tcx(tcx, id, new_tps);
|
||||||
ret.is_some()
|
wbcx.success
|
||||||
});
|
});
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,11 +171,11 @@ impl MethodCall {
|
|||||||
|
|
||||||
// maps from an expression id that corresponds to a method call to the details
|
// maps from an expression id that corresponds to a method call to the details
|
||||||
// of the method to be invoked
|
// 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.
|
// 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)]
|
#[deriving(Clone)]
|
||||||
pub enum vtable_origin {
|
pub enum vtable_origin {
|
||||||
@ -184,7 +184,7 @@ pub enum vtable_origin {
|
|||||||
from whence comes the vtable, and tys are the type substs.
|
from whence comes the vtable, and tys are the type substs.
|
||||||
vtable_res is the vtable itself
|
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:
|
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.
|
// Information about the vtable resolutions for a trait impl.
|
||||||
|
Loading…
Reference in New Issue
Block a user