diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 5759cc6057284..04009fba7f081 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -20,7 +20,7 @@ use metadata::tydecode; use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter, RegionParameter}; use metadata::tyencode; -use middle::typeck::{method_origin, method_map_entry}; +use middle::typeck::method_origin; use middle::{ty, typeck, moves}; use middle; use util::ppaux::ty_to_str; @@ -573,35 +573,7 @@ impl tr for moves::CaptureVar { } // ______________________________________________________________________ -// Encoding and decoding of method_map_entry - -trait read_method_map_entry_helper { - fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext) - -> method_map_entry; -} - -fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) { - ebml_w.emit_struct("method_map_entry", 3, |ebml_w| { - ebml_w.emit_struct_field("origin", 1u, |ebml_w| { - mme.origin.encode(ebml_w); - }); - }) -} - -impl<'a> read_method_map_entry_helper for reader::Decoder<'a> { - fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext) - -> method_map_entry { - self.read_struct("method_map_entry", 3, |this| { - method_map_entry { - origin: this.read_struct_field("origin", 1, |this| { - let method_origin: method_origin = - Decodable::decode(this); - method_origin.tr(xcx) - }) - } - }) - } -} +// Encoding and decoding of method_origin impl tr for method_origin { fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin { @@ -1023,11 +995,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, { let method_map = maps.method_map.borrow(); let r = method_map.get().find(&id); - for &mme in r.iter() { + for &origin in r.iter() { ebml_w.tag(c::tag_table_method_map, |ebml_w| { ebml_w.id(id); ebml_w.tag(c::tag_table_val, |ebml_w| { - encode_method_map_entry(ebml_w, *mme) + origin.encode(ebml_w); }) }) } @@ -1364,9 +1336,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext, ty_param_defs.get().insert(id, bounds); } c::tag_table_method_map => { - let entry = val_dsr.read_method_map_entry(xcx); + let origin: method_origin = Decodable::decode(val_dsr); let mut method_map = dcx.maps.method_map.borrow_mut(); - method_map.get().insert(id, entry); + method_map.get().insert(id, origin.tr(xcx)); } c::tag_table_vtable_map => { let vtable_res = diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index fad44152a2dc1..39b232eed33b7 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -94,7 +94,7 @@ impl MarkSymbolVisitor { span: codemap::Span) { let method_map = self.method_map.borrow(); match method_map.get().find(id) { - Some(&typeck::method_map_entry { origin, .. }) => { + Some(&origin) => { match origin { typeck::method_static(def_id) => { match ty::provided_source(self.tcx, def_id) { diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index b5f8d168f6fc1..9be0a1b0fd340 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -285,8 +285,15 @@ pub fn check_expr(cx: &mut Context, e: &Expr) { // Even though the callee_id may have been the id with // node_type_substs, e.id is correct here. - ty::method_call_type_param_defs(cx.tcx, cx.method_map, e.id).expect( - "non path/method call expr has type substs??") + match cx.method_map.borrow().get().find(&e.id) { + Some(origin) => { + ty::method_call_type_param_defs(cx.tcx, *origin) + } + None => { + cx.tcx.sess.span_bug(e.span, + "non path/method call expr has type substs??"); + } + } } }; let type_param_defs = type_param_defs.borrow(); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index cadc49035567a..37784116289f6 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -1400,7 +1400,7 @@ fn check_stability(cx: &Context, e: &ast::Expr) { ast::ExprMethodCall(..) => { let method_map = cx.method_map.borrow(); match method_map.get().find(&e.id) { - Some(&typeck::method_map_entry { origin, .. }) => { + Some(&origin) => { match origin { typeck::method_static(def_id) => { // If this implements a trait method, get def_id diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 1ab5ebc6d6100..7578636b2b681 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -790,17 +790,17 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> { let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0])); match ty::get(t).sty { ty::ty_enum(_, _) | ty::ty_struct(_, _) => { - let method_map = self.method_map.borrow(); - let entry = match method_map.get().find(&expr.id) { + match self.method_map.borrow().get().find(&expr.id) { None => { self.tcx.sess.span_bug(expr.span, "method call not in \ method map"); } - Some(entry) => entry - }; - debug!("(privacy checking) checking impl method"); - self.check_method(expr.span, &entry.origin, ident); + Some(origin) => { + debug!("(privacy checking) checking impl method"); + self.check_method(expr.span, origin, ident); + } + } } _ => {} } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 42911d25f393e..ee948f5453bab 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -149,10 +149,7 @@ impl Visitor<()> for MarkSymbolVisitor { ast::ExprMethodCall(..) => { let method_map = self.method_map.borrow(); match method_map.get().find(&expr.id) { - Some(&typeck::method_map_entry { - origin: typeck::method_static(def_id), - .. - }) => { + Some(&typeck::method_static(def_id)) => { if is_local(def_id) { if ReachableContext:: def_id_represents_local_inlined_item( @@ -174,8 +171,7 @@ impl Visitor<()> for MarkSymbolVisitor { Some(_) => {} None => { self.tcx.sess.span_bug(expr.span, - "method call expression \ - not in method map?!") + "method call expression not in method map?!") } } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index dc8e786fba24e..e76b2a81490e0 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -65,6 +65,7 @@ use middle::trans::type_of; use middle::trans::type_of::*; use middle::trans::value::Value; use middle::ty; +use middle::typeck; use util::common::indenter; use util::ppaux::{Repr, ty_to_str}; use util::sha2::Sha256; @@ -535,22 +536,14 @@ pub fn get_res_dtor(ccx: @CrateContext, }; if !substs.is_empty() { assert_eq!(did.krate, ast::LOCAL_CRATE); - let tsubsts = ty::substs {regions: ty::ErasedRegions, - self_ty: None, - tps: /*bad*/ substs.to_owned() }; - - // FIXME: #4252: Generic destructors with type bounds are broken. - // - // Since the vtables aren't passed to `monomorphic_fn` here, generic destructors with type - // bounds are broken. Sadly, the `typeck` pass isn't outputting the necessary metadata - // because it does so based on method calls present in the AST. Destructor calls are not yet - // known about at that stage of compilation, since `trans` handles cleanups. - let (val, _) = monomorphize::monomorphic_fn(ccx, - did, - &tsubsts, - None, - None, - None); + let tsubsts = ty::substs { + regions: ty::ErasedRegions, + self_ty: None, + tps: substs.to_owned() + }; + + let vtables = typeck::check::vtable::trans_resolve_method(ccx.tcx, did.node, &tsubsts); + let (val, _) = monomorphize::monomorphic_fn(ccx, did, &tsubsts, vtables, None, None); val } else if did.krate == ast::LOCAL_CRATE { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 27fb9bdb0bb84..7fa116cafd094 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -95,16 +95,15 @@ pub fn trans_method_callee<'a>( bcx: &'a Block<'a>, callee_id: ast::NodeId, this: &ast::Expr, - mentry: typeck::method_map_entry, + origin: typeck::method_origin, arg_cleanup_scope: cleanup::ScopeId) -> Callee<'a> { let _icx = push_ctxt("meth::trans_method_callee"); - debug!("trans_method_callee(callee_id={:?}, mentry={})", - callee_id, - mentry.repr(bcx.tcx())); + debug!("trans_method_callee(callee_id={:?}, origin={})", + callee_id, origin.repr(bcx.tcx())); - match mentry.origin { + match origin { typeck::method_static(did) => { Callee { bcx: bcx, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 5bc3d047c9fdf..e19b6eb163401 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3242,25 +3242,21 @@ pub fn expr_has_ty_params(cx: ctxt, expr: &ast::Expr) -> bool { return node_id_has_type_params(cx, expr.id); } -pub fn method_call_type_param_defs(tcx: ctxt, - method_map: typeck::method_map, - id: ast::NodeId) - -> Option> { - let method_map = method_map.borrow(); - method_map.get().find(&id).map(|method| { - match method.origin { - typeck::method_static(did) => { +pub fn method_call_type_param_defs(tcx: ctxt, origin: typeck::method_origin) + -> Rc<~[TypeParameterDef]> { + match origin { + typeck::method_static(did) => { // n.b.: When we encode impl methods, the bounds // that we encode include both the impl bounds // and then the method bounds themselves... ty::lookup_item_type(tcx, did).generics.type_param_defs - } - typeck::method_param(typeck::method_param { - trait_id: trt_id, - method_num: n_mth, ..}) | - typeck::method_object(typeck::method_object { - trait_id: trt_id, - method_num: n_mth, ..}) => { + } + typeck::method_param(typeck::method_param { + trait_id: trt_id, + method_num: n_mth, ..}) | + typeck::method_object(typeck::method_object { + trait_id: trt_id, + method_num: n_mth, ..}) => { // ...trait methods bounds, in contrast, include only the // method bounds, so we must preprend the tps from the // trait itself. This ought to be harmonized. @@ -3271,9 +3267,8 @@ pub fn method_call_type_param_defs(tcx: ctxt, ty::trait_method(tcx, trt_id, n_mth).generics.type_param_defs())) - } } - }) + } } pub fn resolve_expr(tcx: ctxt, expr: &ast::Expr) -> ast::Def { diff --git a/src/librustc/middle/typeck/check/demand.rs b/src/librustc/middle/typeck/check/demand.rs index cf316ed284d93..1c7ad292877be 100644 --- a/src/librustc/middle/typeck/check/demand.rs +++ b/src/librustc/middle/typeck/check/demand.rs @@ -20,17 +20,17 @@ use syntax::codemap::Span; // Requires that the two types unify, and prints an error message if they // don't. -pub fn suptype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) { +pub fn suptype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) { suptype_with_fn(fcx, sp, false, expected, actual, |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) }) } -pub fn subtype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) { +pub fn subtype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) { suptype_with_fn(fcx, sp, true, actual, expected, |sp, a, e, s| { fcx.report_mismatched_types(sp, e, a, s) }) } -pub fn suptype_with_fn(fcx: @FnCtxt, +pub fn suptype_with_fn(fcx: &FnCtxt, sp: Span, b_is_expected: bool, ty_a: ty::t, diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 9c43af4f13aa7..fca89f3f91ca8 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -90,7 +90,7 @@ use middle::typeck::check::{structurally_resolved_type}; use middle::typeck::check::vtable; use middle::typeck::check; use middle::typeck::infer; -use middle::typeck::{method_map_entry, method_origin, method_param}; +use middle::typeck::{method_origin, method_param}; use middle::typeck::{method_static, method_object}; use middle::typeck::{param_numbered, param_self, param_index}; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; @@ -133,7 +133,7 @@ pub fn lookup( deref_args: check::DerefArgs, // Whether we autopointer first. check_traits: CheckTraitsFlag, // Whether we check traits only. autoderef_receiver: AutoderefReceiverFlag) - -> Option { + -> Option { let impl_dups = @RefCell::new(HashSet::new()); let lcx = LookupContext { fcx: fcx, @@ -211,7 +211,7 @@ enum RcvrMatchCondition { } impl<'a> LookupContext<'a> { - fn search(&self, self_ty: ty::t) -> Option { + fn search(&self, self_ty: ty::t) -> Option { let mut self_ty = self_ty; let mut autoderefs = 0; loop { @@ -592,7 +592,7 @@ impl<'a> LookupContext<'a> { fn search_for_autoderefd_method(&self, self_ty: ty::t, autoderefs: uint) - -> Option { + -> Option { let (self_ty, autoadjust) = self.consider_reborrow(self_ty, autoderefs); match self.search_for_method(self_ty) { @@ -686,9 +686,9 @@ impl<'a> LookupContext<'a> { } fn search_for_autosliced_method(&self, - self_ty: ty::t, - autoderefs: uint) - -> Option { + self_ty: ty::t, + autoderefs: uint) + -> Option { /*! * * Searches for a candidate by converting things like @@ -763,7 +763,7 @@ impl<'a> LookupContext<'a> { } fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint) - -> Option { + -> Option { /*! * * Converts any type `T` to `&M T` where `M` is an @@ -799,7 +799,7 @@ impl<'a> LookupContext<'a> { autoderefs: uint, mutbls: &[ast::Mutability], mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t) - -> Option { + -> Option { // This is hokey. We should have mutability inference as a // variable. But for now, try &const, then &, then &mut: let region = @@ -823,7 +823,7 @@ impl<'a> LookupContext<'a> { } fn search_for_method(&self, rcvr_ty: ty::t) - -> Option { + -> Option { debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty)); let _indenter = indenter(); @@ -855,7 +855,7 @@ impl<'a> LookupContext<'a> { fn consider_candidates(&self, rcvr_ty: ty::t, candidates: &mut ~[Candidate]) - -> Option { + -> Option { // FIXME(pcwalton): Do we need to clone here? let relevant_candidates: ~[Candidate] = candidates.iter().map(|c| (*c).clone()). @@ -926,7 +926,7 @@ impl<'a> LookupContext<'a> { } fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate) - -> method_map_entry { + -> method_origin { // This method performs two sets of substitutions, one after the other: // 1. Substitute values for any type/lifetime parameters from the impl and // method declaration into the method type. This is the function type @@ -1037,9 +1037,7 @@ impl<'a> LookupContext<'a> { self.fcx.write_ty(self.callee_id, fty); self.fcx.write_substs(self.callee_id, all_substs); - method_map_entry { - origin: candidate.origin - } + candidate.origin } fn construct_transformed_self_ty_for_object( diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 4ac8ff00f5e19..f9bf52260d551 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -590,8 +590,7 @@ pub fn check_item(ccx: @CrateCtxt, it: &ast::Item) { ast_trait_ref, impl_trait_ref, *ms); - vtable::resolve_impl(ccx, it, &impl_tpt.generics, - impl_trait_ref); + vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, impl_trait_ref); } None => { } } @@ -3831,8 +3830,7 @@ pub fn instantiate_path(fcx: @FnCtxt, // Resolves `typ` by a single level if `typ` is a type variable. If no // resolution is possible, then an error is reported. -pub fn structurally_resolved_type(fcx: @FnCtxt, sp: Span, tp: ty::t) - -> ty::t { +pub fn structurally_resolved_type(fcx: &FnCtxt, sp: Span, tp: ty::t) -> ty::t { match infer::resolve_type(fcx.infcx(), tp, force_tvar) { Ok(t_s) if !ty::type_is_ty_var(t_s) => t_s, _ => { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 721672ab677ac..ba4300b58a11a 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -18,7 +18,7 @@ use middle::typeck::check::{structurally_resolved_type}; use middle::typeck::infer::fixup_err_to_str; use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type}; use middle::typeck::infer; -use middle::typeck::{CrateCtxt, vtable_origin, vtable_res, vtable_param_res}; +use middle::typeck::{vtable_origin, vtable_res, vtable_param_res}; use middle::typeck::{vtable_static, vtable_param, impl_res}; use middle::typeck::{param_numbered, param_self, param_index}; use middle::subst::Subst; @@ -537,9 +537,7 @@ fn connect_trait_tps(vcx: &VtableContext, relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref); } -fn insert_vtables(fcx: @FnCtxt, - callee_id: ast::NodeId, - vtables: vtable_res) { +fn insert_vtables(fcx: &FnCtxt, callee_id: ast::NodeId, vtables: vtable_res) { debug!("insert_vtables(callee_id={}, vtables={:?})", callee_id, vtables.repr(fcx.tcx())); let mut vtable_map = fcx.inh.vtable_map.borrow_mut(); @@ -559,7 +557,7 @@ pub fn location_info_for_item(item: &ast::Item) -> LocationInfo { } } -pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) { +pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) { debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}", ex.id, is_early, expr_to_str(ex)); let _indent = indenter(); @@ -693,20 +691,17 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) { }); } - ast::ExprParen(e) => { - early_resolve_expr(e, fcx, is_early); - } - // Must resolve bounds on methods with bounded params ast::ExprBinary(callee_id, _, _, _) | ast::ExprUnary(callee_id, _, _) | ast::ExprAssignOp(callee_id, _, _, _) | ast::ExprIndex(callee_id, _, _) | ast::ExprMethodCall(callee_id, _, _, _) => { - match ty::method_call_type_param_defs(cx.tcx, fcx.inh.method_map, ex.id) { - Some(type_param_defs) => { + match fcx.inh.method_map.borrow().get().find(&ex.id) { + Some(origin) => { debug!("vtable resolution on parameter bounds for method call {}", ex.repr(fcx.tcx())); + let type_param_defs = ty::method_call_type_param_defs(cx.tcx, *origin); if has_trait_bounds(*type_param_defs.borrow()) { let substs = fcx.node_ty_substs(callee_id); let vcx = fcx.vtable_context(); @@ -717,7 +712,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) { } } } - None => () + None => {} } } ast::ExprCast(src, _) => { @@ -761,33 +756,27 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) { } } -fn resolve_expr(fcx: @FnCtxt, ex: &ast::Expr) { - let mut fcx = fcx; - early_resolve_expr(ex, fcx, false); - visit::walk_expr(&mut fcx, ex, ()); -} - -pub fn resolve_impl(ccx: @CrateCtxt, +pub fn resolve_impl(tcx: ty::ctxt, impl_item: &ast::Item, impl_generics: &ty::Generics, impl_trait_ref: &ty::TraitRef) { let param_env = ty::construct_parameter_environment( - ccx.tcx, + tcx, None, impl_generics.type_param_defs(), [], impl_generics.region_param_defs(), impl_item.id); - let impl_trait_ref = @impl_trait_ref.subst(ccx.tcx, ¶m_env.free_substs); + let impl_trait_ref = @impl_trait_ref.subst(tcx, ¶m_env.free_substs); - let infcx = &infer::new_infer_ctxt(ccx.tcx); + let infcx = &infer::new_infer_ctxt(tcx); let vcx = VtableContext { infcx: infcx, param_env: ¶m_env }; let loc_info = location_info_for_item(impl_item); // First, check that the impl implements any trait bounds // on the trait. - let trait_def = ty::lookup_trait_def(ccx.tcx, impl_trait_ref.def_id); + let trait_def = ty::lookup_trait_def(tcx, impl_trait_ref.def_id); let vtbls = lookup_vtables(&vcx, &loc_info, trait_def.generics.type_param_defs(), @@ -801,8 +790,8 @@ pub fn resolve_impl(ccx: @CrateCtxt, builtin_bounds: ty::EmptyBuiltinBounds(), trait_bounds: ~[impl_trait_ref] }; - let t = ty::node_id_to_type(ccx.tcx, impl_item.id); - let t = t.subst(ccx.tcx, ¶m_env.free_substs); + let t = ty::node_id_to_type(tcx, impl_item.id); + let t = t.subst(tcx, ¶m_env.free_substs); debug!("=== Doing a self lookup now."); // Right now, we don't have any place to store this. @@ -819,13 +808,36 @@ pub fn resolve_impl(ccx: @CrateCtxt, }; let impl_def_id = ast_util::local_def(impl_item.id); - let mut impl_vtables = ccx.tcx.impl_vtables.borrow_mut(); + let mut impl_vtables = tcx.impl_vtables.borrow_mut(); impl_vtables.get().insert(impl_def_id, res); } -impl visit::Visitor<()> for @FnCtxt { +/// Resolve vtables for a method call after typeck has finished. +/// Used by trans to monomorphize artificial method callees (e.g. drop). +pub fn trans_resolve_method(tcx: ty::ctxt, id: ast::NodeId, + substs: &ty::substs) -> Option { + let generics = ty::lookup_item_type(tcx, ast_util::local_def(id)).generics; + let type_param_defs = generics.type_param_defs.borrow(); + if has_trait_bounds(*type_param_defs) { + let vcx = VtableContext { + infcx: &infer::new_infer_ctxt(tcx), + param_env: &ty::construct_parameter_environment(tcx, None, [], [], [], id) + }; + let loc_info = LocationInfo { + id: id, + span: tcx.map.span(id) + }; + + Some(lookup_vtables(&vcx, &loc_info, *type_param_defs, substs, false)) + } else { + None + } +} + +impl<'a> visit::Visitor<()> for &'a FnCtxt { fn visit_expr(&mut self, ex: &ast::Expr, _: ()) { - resolve_expr(*self, ex); + early_resolve_expr(ex, *self, false); + visit::walk_expr(self, ex, ()); } fn visit_item(&mut self, _: &ast::Item, _: ()) { // no-op @@ -834,6 +846,6 @@ impl visit::Visitor<()> for @FnCtxt { // Detect points where a trait-bounded type parameter is // instantiated, resolve the impls for the parameters. -pub fn resolve_in_block(mut fcx: @FnCtxt, bl: &ast::Block) { +pub fn resolve_in_block(mut fcx: &FnCtxt, bl: &ast::Block) { visit::walk_block(&mut fcx, bl, ()); } diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 57b1efbf3e922..3741fd1c17360 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -141,16 +141,9 @@ pub struct method_object { real_index: uint, } - -#[deriving(Clone)] -pub struct method_map_entry { - // method details being invoked - origin: method_origin, -} - // maps from an expression id that corresponds to a method call to the details // of the method to be invoked -pub type method_map = @RefCell>; +pub type method_map = @RefCell>; pub type vtable_param_res = @~[vtable_origin]; // Resolutions for bounds of all parameters, left to right, for a given path. diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 4608fa649b587..14d12b7f648dd 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -870,12 +870,6 @@ impl Repr for ty::FnSig { } } -impl Repr for typeck::method_map_entry { - fn repr(&self, tcx: ctxt) -> ~str { - format!("method_map_entry \\{origin: {}\\}", self.origin.repr(tcx)) - } -} - impl Repr for typeck::method_origin { fn repr(&self, tcx: ctxt) -> ~str { match self { diff --git a/src/test/run-pass/issue-4252.rs b/src/test/run-pass/issue-4252.rs index 86b09f8dcfbdf..ba080e9818302 100644 --- a/src/test/run-pass/issue-4252.rs +++ b/src/test/run-pass/issue-4252.rs @@ -8,30 +8,34 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test - trait X { - fn call(&self); + fn call(&self, x: &T); + fn default_method(&self, x: &T) { + println!("X::default_method {:?} {:?}", self, x); + } } -struct Y; +struct Y(int); struct Z { x: T } impl X for Y { - fn call(&self) { + fn call(&self, x: &T) { + println!("X::call {:?} {:?}", self, x); } } +#[unsafe_destructor] impl Drop for Z { fn drop(&mut self) { - self.x.call(); // Adding this statement causes an ICE. + // These statements used to cause an ICE. + self.x.call(self); + self.x.default_method(self); } } pub fn main() { - let y = Y; - let _z = Z{x: y}; + let _z = Z {x: Y(42)}; }