diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index f4c3f564068..d42e1d6479b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -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(); } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 0584322ef9e..2f3d427dccc 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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); }) }) } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 7c0f81b16d1..2a7ceb4f681 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -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, vtables: Option) -> 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, // values for fn's ty params vtables: Option) // 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), diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 66e0a35d638..ab474eacf25 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -797,15 +797,16 @@ pub fn node_id_type_params(bcx: &Block, node: ExprOrMethodCall) -> Vec { pub fn node_vtables(bcx: &Block, id: typeck::MethodCall) -> Option { - 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() diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 6ac25cd1f13..1c2ef8e092f 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -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, rcvr_origins: typeck::vtable_res) - -> (Vec , typeck::vtable_res) { + -> (Vec, 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>(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, vtables: typeck::vtable_res) -> Vec { 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()); diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 7d7ea5a2211..445aa9f2323 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -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 >)> = 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()); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index ff9ff64397a..25af1066ba3 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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()), } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 476142a415f..910b7e93cf8 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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()), } } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 3f50a64e630..520db02cfc7 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -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, ¶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 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. 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, ¶m_env.free_substs); diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index d7a22e91c5e..9598b1e9581 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -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 { - 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 { +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 } } } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index b5fdc492cb4..7382ce5734d 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -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>; +pub type MethodMap = RefCell>; -pub type vtable_param_res = @Vec ; +pub type vtable_param_res = Vec; // Resolutions for bounds of all parameters, left to right, for a given path. -pub type vtable_res = @Vec ; +pub type vtable_res = Vec; #[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 , vtable_res), + vtable_static(ast::DefId, Vec, 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>; +pub type vtable_map = RefCell>; // Information about the vtable resolutions for a trait impl.