diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 742d549e202..21850048c27 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -791,7 +791,7 @@ fn encode_info_for_method(ecx: &EncodeContext, if len > 0u || should_inline { (ecx.encode_inlined_item)( ecx, ebml_w, impl_path, - ii_method(local_def(parent_id), m)); + ii_method(local_def(parent_id), false, m)); } else { encode_symbol(ecx, ebml_w, m.id); } @@ -1123,21 +1123,16 @@ fn encode_info_for_item(ecx: &EncodeContext, } provided(m) => { - // This is obviously a bogus assert but I don't think this - // ever worked before anyhow...near as I can tell, before - // we would emit two items. - if method_ty.explicit_self == sty_static { - tcx.sess.span_unimpl( - item.span, - fmt!("Method %s is both provided and static", - token::ident_to_str(&method_ty.ident))); + // If this is a static method, we've already encoded + // this. + if method_ty.explicit_self != sty_static { + encode_type_param_bounds(ebml_w, ecx, + &m.generics.ty_params); } - encode_type_param_bounds(ebml_w, ecx, - &m.generics.ty_params); encode_method_sort(ebml_w, 'p'); (ecx.encode_inlined_item)( ecx, ebml_w, path, - ii_method(local_def(item.id), m)); + ii_method(local_def(item.id), true, m)); } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 7412eba1156..2e0090f7dda 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -319,7 +319,8 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { match *ii { //hack: we're not dropping items ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()), - ast::ii_method(d, m) => ast::ii_method(d, fld.fold_method(m)), + ast::ii_method(d, is_provided, m) => + ast::ii_method(d, is_provided, fld.fold_method(m)), ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)) } } @@ -340,7 +341,8 @@ fn renumber_ast(xcx: @ExtendedDecodeContext, ii: ast::inlined_item) match ii { ast::ii_item(i) => ast::ii_item(fld.fold_item(i).get()), - ast::ii_method(d, m) => ast::ii_method(xcx.tr_def_id(d), fld.fold_method(m)), + ast::ii_method(d, is_provided, m) => + ast::ii_method(xcx.tr_def_id(d), is_provided, fld.fold_method(m)), ast::ii_foreign(i) => ast::ii_foreign(fld.fold_foreign_item(i)), } } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 8074b5b3b40..0afa1c16245 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -244,7 +244,7 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ LintSpec { lint: default_methods, desc: "allow default methods", - default: deny + default: allow }), ("unused_unsafe", diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ac7805146e4..f5024f7973c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1185,7 +1185,7 @@ impl cmt_ { } } -impl Repr for cmt { +impl Repr for cmt_ { fn repr(&self, tcx: ty::ctxt) -> ~str { fmt!("{%s id:%d m:%? ty:%s}", self.cat.repr(tcx), diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 697eb2a5c04..c0336c8e60d 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -520,7 +520,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext, let _icx = push_ctxt("trans_res_dtor"); if !substs.is_empty() { let did = if did.crate != ast::local_crate { - inline::maybe_instantiate_inline(ccx, did, true) + inline::maybe_instantiate_inline(ccx, did) } else { did }; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 9b286adf8e9..01bd69f24fc 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -250,7 +250,7 @@ pub fn trans_fn_ref_with_vtables( def_id: ast::def_id, // def id of fn ref_id: ast::node_id, // node id of use of fn; may be zero if N/A type_params: &[ty::t], // values for fn's ty params - vtables: Option) + vtables: Option) // vtables for the call -> FnData { //! // @@ -361,8 +361,7 @@ pub fn trans_fn_ref_with_vtables( // def_id to the local id of the inlined copy. let def_id = { if def_id.crate != ast::local_crate { - let may_translate = opt_impl_did.is_none(); - inline::maybe_instantiate_inline(ccx, def_id, may_translate) + inline::maybe_instantiate_inline(ccx, def_id) } else { def_id } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 24648ada893..1a45ce36af2 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -154,12 +154,6 @@ impl Repr for param_substs { } } -impl Repr for @param_substs { - fn repr(&self, tcx: ty::ctxt) -> ~str { - param_substs_to_str(*self, tcx) - } -} - // Function context. Every LLVM function we create will have one of // these. pub struct fn_ctxt_ { diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 9044ef57003..69c8331bc9f 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -159,7 +159,7 @@ pub fn get_const_val(cx: @mut CrateContext, mut def_id: ast::def_id) -> ValueRef let contains_key = cx.const_values.contains_key(&def_id.node); if !ast_util::is_local(def_id) || !contains_key { if !ast_util::is_local(def_id) { - def_id = inline::maybe_instantiate_inline(cx, def_id, true); + def_id = inline::maybe_instantiate_inline(cx, def_id); } match cx.tcx.items.get_copy(&def_id.node) { ast_map::node_item(@ast::item { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 118eeeeec1f..0f5ff6bfa9b 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -956,7 +956,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { fn get_did(ccx: @mut CrateContext, did: ast::def_id) -> ast::def_id { if did.crate != ast::local_crate { - inline::maybe_instantiate_inline(ccx, did, true) + inline::maybe_instantiate_inline(ccx, did) } else { did } diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 893ef3feb56..e2d84473e23 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -22,11 +22,7 @@ use syntax::ast; use syntax::ast_map::path_name; use syntax::ast_util::local_def; -// `translate` will be true if this function is allowed to translate the -// item and false otherwise. Currently, this parameter is set to false when -// translating default methods. -pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, - translate: bool) +pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id) -> ast::def_id { let _icx = push_ctxt("maybe_instantiate_inline"); match ccx.external.find(&fn_id) { @@ -59,7 +55,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, csearch::found(ast::ii_item(item)) => { ccx.external.insert(fn_id, Some(item.id)); ccx.stats.n_inlines += 1; - if translate { trans_item(ccx, item); } + trans_item(ccx, item); local_def(item.id) } csearch::found(ast::ii_foreign(item)) => { @@ -81,19 +77,19 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, _ => ccx.sess.bug("maybe_instantiate_inline: item has a \ non-enum parent") } - if translate { trans_item(ccx, item); } + trans_item(ccx, item); local_def(my_id) } csearch::found_parent(_, _) => { ccx.sess.bug("maybe_get_item_ast returned a found_parent \ with a non-item parent"); } - csearch::found(ast::ii_method(impl_did, mth)) => { + csearch::found(ast::ii_method(impl_did, is_provided, mth)) => { ccx.stats.n_inlines += 1; ccx.external.insert(fn_id, Some(mth.id)); // If this is a default method, we can't look up the // impl type. But we aren't going to translate anyways, so don't. - if !translate { return local_def(mth.id); } + if is_provided { return local_def(mth.id); } let impl_tpt = ty::lookup_item_type(ccx.tcx, impl_did); let num_type_params = diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index bbcf68c386d..78e0c3989ec 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -63,24 +63,26 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); let _icx = push_ctxt("monomorphic_fn"); let mut must_cast = false; - let substs = real_substs.tps.iter().transform(|t| { + + let do_normalize = |t: &ty::t| { match normalize_for_monomorphization(ccx.tcx, *t) { Some(t) => { must_cast = true; t } None => *t } - }).collect::<~[ty::t]>(); - - for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); } - for substs.iter().advance |s| { assert!(!ty::type_has_params(*s)); } - let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); + }; let psubsts = @param_substs { - tys: substs, + tys: real_substs.tps.map(|x| do_normalize(x)), vtables: vtables, - self_ty: real_substs.self_ty, + self_ty: real_substs.self_ty.map(|x| do_normalize(x)), self_vtable: self_vtable }; + for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); } + for psubsts.tys.iter().advance |s| { assert!(!ty::type_has_params(*s)); } + let param_uses = type_use::type_uses_for(ccx, fn_id, psubsts.tys.len()); + + let hash_id = make_mono_id(ccx, fn_id, impl_did_opt, &*psubsts, Some(param_uses)); @@ -109,6 +111,10 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, let tpt = ty::lookup_item_type(ccx.tcx, fn_id); let llitem_ty = tpt.ty; + // We need to do special handling of the substitutions if we are + // calling a static provided method. This is sort of unfortunate. + let mut is_static_provided = None; + let map_node = session::expect( ccx.sess, ccx.tcx.items.find_copy(&fn_id.node), @@ -127,6 +133,12 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, return (get_item_val(ccx, fn_id.node), true); } ast_map::node_trait_method(@ast::provided(m), _, pt) => { + // If this is a static provided method, indicate that + // and stash the number of params on the method. + if m.explicit_self.node == ast::sty_static { + is_static_provided = Some(m.generics.ty_params.len()); + } + (pt, m.ident, m.span) } ast_map::node_trait_method(@ast::required(_), _, _) => { @@ -151,8 +163,36 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, ast_map::node_struct_ctor(_, i, pt) => (pt, i.ident, i.span) }; - let mono_ty = ty::subst_tps(ccx.tcx, psubsts.tys, - psubsts.self_ty, llitem_ty); + debug!("monomorphic_fn about to subst into %s", llitem_ty.repr(ccx.tcx)); + let mono_ty = match is_static_provided { + None => ty::subst_tps(ccx.tcx, psubsts.tys, + psubsts.self_ty, llitem_ty), + Some(num_method_ty_params) => { + // Static default methods are a little unfortunate, in + // that the "internal" and "external" type of them differ. + // Internally, the method body can refer to Self, but the + // externally visable type of the method has a type param + // inserted in between the trait type params and the + // method type params. The substs that we are given are + // the proper substs *internally* to the method body, so + // we have to use those when compiling it. + // + // In order to get the proper substitution to use on the + // type of the method, we pull apart the substitution and + // stick a substitution for the self type in. + // This is a bit unfortunate. + + let idx = psubsts.tys.len() - num_method_ty_params; + let substs = + (psubsts.tys.slice(0, idx) + + &[psubsts.self_ty.get()] + + psubsts.tys.tailn(idx)); + debug!("static default: changed substitution to %s", + substs.repr(ccx.tcx)); + + ty::subst_tps(ccx.tcx, substs, None, llitem_ty) + } + }; let llfty = type_of_fn_from_ty(ccx, mono_ty); ccx.stats.n_monos += 1; diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index b3848f5e86c..eda8f853071 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -49,6 +49,8 @@ pub type type_uses = uint; // Bitmask pub static use_repr: uint = 1; /* Dependency on size/alignment/mode and take/drop glue */ pub static use_tydesc: uint = 2; /* Takes the tydesc, or compares */ +pub static use_all: uint = use_repr|use_tydesc; + pub struct Context { ccx: @mut CrateContext, @@ -57,6 +59,14 @@ pub struct Context { pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) -> @~[type_uses] { + + fn store_type_uses(cx: Context, fn_id: def_id) -> @~[type_uses] { + let Context { uses, ccx } = cx; + let uses = @copy *uses; // freeze + ccx.type_use_cache.insert(fn_id, uses); + uses + } + match ccx.type_use_cache.find(&fn_id) { Some(uses) => return *uses, None => () @@ -65,32 +75,29 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) let fn_id_loc = if fn_id.crate == local_crate { fn_id } else { - inline::maybe_instantiate_inline(ccx, fn_id, true) + inline::maybe_instantiate_inline(ccx, fn_id) }; // Conservatively assume full use for recursive loops - ccx.type_use_cache.insert(fn_id, @vec::from_elem(n_tps, 3u)); + ccx.type_use_cache.insert(fn_id, @vec::from_elem(n_tps, use_all)); let cx = Context { ccx: ccx, uses: @mut vec::from_elem(n_tps, 0) }; - match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { - ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | - ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { - for sig.inputs.iter().advance |arg| { - type_needs(&cx, use_repr, *arg); - } - } - _ => () + + // If the method is a default method, we mark all of the types as + // used. This is imprecise, but simple. Getting it right is + // tricky because the substs on the call and the substs on the + // default method differ, because of substs on the trait/impl. + let is_default = ccx.tcx.provided_method_sources.contains_key(&fn_id_loc); + // We also mark all of the params as used if it is an extern thing + // that we haven't been able to inline yet. + if is_default || fn_id_loc.crate != local_crate { + for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_all; } + return store_type_uses(cx, fn_id); } - if fn_id_loc.crate != local_crate { - let Context { uses, _ } = cx; - let uses = @copy *uses; // freeze - ccx.type_use_cache.insert(fn_id, uses); - return uses; - } let map_node = match ccx.tcx.items.find(&fn_id_loc.node) { Some(x) => (/*bad*/copy *x), None => ccx.sess.bug(fmt!("type_uses_for: unbound item ID %?", @@ -106,7 +113,10 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) // This will be a static trait method. For now, we just assume // it fully depends on all of the type information. (Doing // otherwise would require finding the actual implementation). - for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr|use_tydesc;} + for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_all;} + // We need to return early, before the arguments are processed, + // because of difficulties in the handling of Self. + return store_type_uses(cx, fn_id); } ast_map::node_variant(_, _, _) => { for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr;} @@ -171,10 +181,19 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) token::get_ident_interner()))); } } - let Context { uses, _ } = cx; - let uses = @copy *uses; // freeze - ccx.type_use_cache.insert(fn_id, uses); - uses + + // Now handle arguments + match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty { + ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) | + ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => { + for sig.inputs.iter().advance |arg| { + type_needs(&cx, use_repr, *arg); + } + } + _ => () + } + + store_type_uses(cx, fn_id) } pub fn type_needs(cx: &Context, use_: uint, ty: ty::t) { diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 5c8ce6b2d8b..4caf0b62a54 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3327,11 +3327,15 @@ pub fn instantiate_path(fcx: @mut FnCtxt, fcx.infcx().next_ty_vars(ty_param_count) } else if ty_substs_len > ty_param_count { fcx.ccx.tcx.sess.span_err - (span, "too many type parameters provided for this item"); + (span, + fmt!("too many type parameters provided: expected %u, found %u", + ty_param_count, ty_substs_len)); fcx.infcx().next_ty_vars(ty_param_count) } else if ty_substs_len < ty_param_count { fcx.ccx.tcx.sess.span_err - (span, "not enough type parameters provided for this item"); + (span, + fmt!("not enough type parameters provided: expected %u, found %u", + ty_param_count, ty_substs_len)); fcx.infcx().next_ty_vars(ty_param_count) } else { pth.types.map(|aty| fcx.to_ty(aty)) diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 9583867b94b..ec384543dea 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -278,7 +278,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, // Represents [A',B',C'] let num_trait_bounds = trait_ty_generics.type_param_defs.len(); let non_shifted_trait_tps = do vec::from_fn(num_trait_bounds) |i| { - ty::mk_param(tcx, i, dummy_defid) + ty::mk_param(tcx, i, trait_ty_generics.type_param_defs[i].def_id) }; // Represents [D'] @@ -288,7 +288,8 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, // Represents [E',F',G'] let num_method_bounds = m.generics.type_param_defs.len(); let shifted_method_tps = do vec::from_fn(num_method_bounds) |i| { - ty::mk_param(tcx, i + 1, dummy_defid) + ty::mk_param(tcx, i + num_trait_bounds + 1, + m.generics.type_param_defs[i].def_id) }; // build up the substitution from diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 07dd19a3fed..84f20d70bf0 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -512,9 +512,6 @@ impl Repr for Option { } } -/* -Annoyingly, these conflict with @ast::expr. - impl Repr for @T { fn repr(&self, tcx: ctxt) -> ~str { (&**self).repr(tcx) @@ -526,7 +523,6 @@ impl Repr for ~T { (&**self).repr(tcx) } } -*/ fn repr_vec(tcx: ctxt, v: &[T]) -> ~str { fmt!("[%s]", v.map(|t| t.repr(tcx)).connect(",")) @@ -538,11 +534,11 @@ impl<'self, T:Repr> Repr for &'self [T] { } } -// This is necessary to handle types like Option<@~[T]>, for which +// This is necessary to handle types like Option<~[T]>, for which // autoderef cannot convert the &[T] handler -impl Repr for @~[T] { +impl Repr for ~[T] { fn repr(&self, tcx: ctxt) -> ~str { - repr_vec(tcx, **self) + repr_vec(tcx, *self) } } @@ -593,19 +589,19 @@ impl Repr for ty::TraitRef { } } -impl Repr for @ast::expr { +impl Repr for ast::expr { fn repr(&self, tcx: ctxt) -> ~str { fmt!("expr(%d: %s)", self.id, - pprust::expr_to_str(*self, tcx.sess.intr())) + pprust::expr_to_str(self, tcx.sess.intr())) } } -impl Repr for @ast::pat { +impl Repr for ast::pat { fn repr(&self, tcx: ctxt) -> ~str { fmt!("pat(%d: %s)", self.id, - pprust::pat_to_str(*self, tcx.sess.intr())) + pprust::pat_to_str(self, tcx.sess.intr())) } } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index a17fea24b2c..b9593d845a4 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -17,7 +17,7 @@ implementing the `Iterator` trait. */ -#[allow(default_methods)]; // solid enough for the use case here +#[allow(default_methods)]; // still off by default in stage0 use cmp; use iter::Times; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8c37c1510cf..b6275ed186c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1033,7 +1033,7 @@ pub enum foreign_item_ { #[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum inlined_item { ii_item(@item), - ii_method(def_id /* impl id */, @method), + ii_method(def_id /* impl id */, bool /* is provided */, @method), ii_foreign(@foreign_item), } diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 59020e9d183..e7eedcaa62e 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -165,8 +165,8 @@ pub fn map_decoded_item(diag: @span_handler, i.vis, // Wrong but OK @path)); } - ii_method(impl_did, m) => { - map_method(impl_did, @path, m, cx); + ii_method(impl_did, is_provided, m) => { + map_method(impl_did, @path, m, is_provided, cx); } } @@ -207,8 +207,11 @@ pub fn map_pat(pat: @pat, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { } pub fn map_method(impl_did: def_id, impl_path: @path, - m: @method, cx: @mut Ctx) { - cx.map.insert(m.id, node_method(m, impl_did, impl_path)); + m: @method, is_provided: bool, cx: @mut Ctx) { + let entry = if is_provided { + node_trait_method(@provided(m), impl_did, impl_path) + } else { node_method(m, impl_did, impl_path) }; + cx.map.insert(m.id, entry); cx.map.insert(m.self_id, node_local(special_idents::self_)); } @@ -219,7 +222,7 @@ pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) { item_impl(_, _, _, ref ms) => { let impl_did = ast_util::local_def(i.id); for ms.iter().advance |m| { - map_method(impl_did, extend(cx, i.ident), *m, cx); + map_method(impl_did, extend(cx, i.ident), *m, false, cx); } } item_enum(ref enum_definition, _) => { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 35ae45af392..7567dc0000b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -298,7 +298,7 @@ impl inlined_item_utils for inlined_item { match *self { ii_item(i) => /* FIXME (#2543) */ copy i.ident, ii_foreign(i) => /* FIXME (#2543) */ copy i.ident, - ii_method(_, m) => /* FIXME (#2543) */ copy m.ident, + ii_method(_, _, m) => /* FIXME (#2543) */ copy m.ident, } } @@ -306,7 +306,7 @@ impl inlined_item_utils for inlined_item { match *self { ii_item(i) => i.id, ii_foreign(i) => i.id, - ii_method(_, m) => m.id, + ii_method(_, _, m) => m.id, } } @@ -314,7 +314,7 @@ impl inlined_item_utils for inlined_item { match *self { ii_item(i) => (v.visit_item)(i, (e, v)), ii_foreign(i) => (v.visit_foreign_item)(i, (e, v)), - ii_method(_, m) => visit::visit_method_helper(m, (e, v)), + ii_method(_, _, m) => visit::visit_method_helper(m, (e, v)), } } } diff --git a/src/test/auxiliary/issue_3979_traits.rs b/src/test/auxiliary/issue_3979_traits.rs index bf3167f6051..1e56dab1559 100644 --- a/src/test/auxiliary/issue_3979_traits.rs +++ b/src/test/auxiliary/issue_3979_traits.rs @@ -18,7 +18,6 @@ trait Positioned { fn X(&self) -> int; } -#[allow(default_methods)] trait Movable: Positioned { fn translate(&self, dx: int) { self.SetX(self.X() + dx); diff --git a/src/test/auxiliary/trait_default_method_xc_aux.rs b/src/test/auxiliary/trait_default_method_xc_aux.rs index 7ae648f113a..4d910385cd6 100644 --- a/src/test/auxiliary/trait_default_method_xc_aux.rs +++ b/src/test/auxiliary/trait_default_method_xc_aux.rs @@ -1,11 +1,11 @@ -#[allow(default_methods)]; pub struct Something { x: int } pub trait A { fn f(&self) -> int; fn g(&self) -> int { 10 } - fn h(&self) -> int { 10 } + fn h(&self) -> int { 11 } + fn lurr(x: &Self, y: &Self) -> int { x.g() + y.h() } } @@ -19,6 +19,7 @@ impl A for Something { trait B { fn thing(&self, x: T, y: U) -> (T, U) { (x, y) } + fn staticthing(z: &Self, x: T, y: U) -> (T, U) { (x, y) } } impl B for int { } diff --git a/src/test/run-pass/bug-7183-generics.rs b/src/test/run-pass/bug-7183-generics.rs index 532b2312a98..52264da2e80 100644 --- a/src/test/run-pass/bug-7183-generics.rs +++ b/src/test/run-pass/bug-7183-generics.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)] trait Speak { fn say(&self, s:&str) -> ~str; fn hi(&self) -> ~str { hello(self) } diff --git a/src/test/run-pass/bug-7295.rs b/src/test/run-pass/bug-7295.rs index 080a0dbd91a..2a1a0e35c56 100644 --- a/src/test/run-pass/bug-7295.rs +++ b/src/test/run-pass/bug-7295.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; pub trait Foo { pub fn func1(&self, t: U); diff --git a/src/test/run-pass/default-method-simple.rs b/src/test/run-pass/default-method-simple.rs index 378852d8150..4072d1d2bb8 100644 --- a/src/test/run-pass/default-method-simple.rs +++ b/src/test/run-pass/default-method-simple.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Foo { fn f(&self) { diff --git a/src/test/run-pass/generic-static-methods.rs b/src/test/run-pass/generic-static-methods.rs new file mode 100755 index 00000000000..a4e592872a7 --- /dev/null +++ b/src/test/run-pass/generic-static-methods.rs @@ -0,0 +1,27 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait vec_utils { + fn map_(x: &Self, f: &fn(&T) -> U) -> ~[U]; +} + +impl vec_utils for ~[T] { + fn map_(x: &~[T], f: &fn(&T) -> U) -> ~[U] { + let mut r = ~[]; + for x.iter().advance |elt| { + r.push(f(elt)); + } + r + } +} + +fn main() { + assert_eq!(vec_utils::map_(&~[1,2,3], |&x| x+1), ~[2,3,4]); +} diff --git a/src/test/run-pass/issue-3563-2.rs b/src/test/run-pass/issue-3563-2.rs index 7d0ba866faf..0b49e43235a 100644 --- a/src/test/run-pass/issue-3563-2.rs +++ b/src/test/run-pass/issue-3563-2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)] trait Canvas { fn add_point(&self, point: &int); fn add_points(&self, shapes: &[int]) { diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index a24800e4dbb..2465cd3dd59 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -113,7 +113,6 @@ impl ToStr for AsciiArt { // This is similar to an interface in other languages: it defines a protocol which // developers can implement for arbitrary concrete types. -#[allow(default_methods)] trait Canvas { fn add_point(&mut self, shape: Point); fn add_rect(&mut self, shape: Rect); diff --git a/src/test/run-pass/issue-3683.rs b/src/test/run-pass/issue-3683.rs index 0072439935b..aa7fa0cb5f0 100644 --- a/src/test/run-pass/issue-3683.rs +++ b/src/test/run-pass/issue-3683.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Foo { fn a(&self) -> int; diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs index 5884a35a1a1..2a1ded96827 100644 --- a/src/test/run-pass/issue-3979-generics.rs +++ b/src/test/run-pass/issue-3979-generics.rs @@ -14,7 +14,6 @@ trait Positioned { fn X(&self) -> S; } -#[allow(default_methods)] trait Movable: Positioned { fn translate(&self, dx: T) { self.SetX(self.X() + dx); diff --git a/src/test/run-pass/issue-3979.rs b/src/test/run-pass/issue-3979.rs index beffea1dbf3..fe10dd5af53 100644 --- a/src/test/run-pass/issue-3979.rs +++ b/src/test/run-pass/issue-3979.rs @@ -16,7 +16,6 @@ trait Positioned { fn X(&self) -> int; } -#[allow(default_methods)] trait Movable: Positioned { fn translate(&mut self, dx: int) { let x = self.X(); diff --git a/src/test/run-pass/trait-default-method-bound-subst.rs b/src/test/run-pass/trait-default-method-bound-subst.rs index 9dbbcee0f77..ff0c23b2eed 100644 --- a/src/test/run-pass/trait-default-method-bound-subst.rs +++ b/src/test/run-pass/trait-default-method-bound-subst.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait A { fn g(&self, x: T, y: U) -> (T, U) { (x, y) } diff --git a/src/test/run-pass/trait-default-method-bound-subst2.rs b/src/test/run-pass/trait-default-method-bound-subst2.rs index dee9782d5ae..1ea3879e7fa 100644 --- a/src/test/run-pass/trait-default-method-bound-subst2.rs +++ b/src/test/run-pass/trait-default-method-bound-subst2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait A { fn g(&self, x: T) -> T { x } diff --git a/src/test/run-pass/trait-default-method-bound-subst3.rs b/src/test/run-pass/trait-default-method-bound-subst3.rs index cb86736b79d..aff20ffe962 100644 --- a/src/test/run-pass/trait-default-method-bound-subst3.rs +++ b/src/test/run-pass/trait-default-method-bound-subst3.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait A { fn g(&self, x: T, y: T) -> (T, T) { (x, y) } diff --git a/src/test/run-pass/trait-default-method-bound-subst4.rs b/src/test/run-pass/trait-default-method-bound-subst4.rs index d386fd44b6b..4804dc27347 100644 --- a/src/test/run-pass/trait-default-method-bound-subst4.rs +++ b/src/test/run-pass/trait-default-method-bound-subst4.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait A { fn g(&self, x: uint) -> uint { x } diff --git a/src/test/run-pass/trait-default-method-bound.rs b/src/test/run-pass/trait-default-method-bound.rs index ce2df508f70..8a2f1b1743b 100644 --- a/src/test/run-pass/trait-default-method-bound.rs +++ b/src/test/run-pass/trait-default-method-bound.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait A { fn g(&self) -> int { 10 } diff --git a/src/test/run-pass/trait-default-method-xc.rs b/src/test/run-pass/trait-default-method-xc.rs index 4eac1a1e730..38b386838a1 100644 --- a/src/test/run-pass/trait-default-method-xc.rs +++ b/src/test/run-pass/trait-default-method-xc.rs @@ -1,16 +1,19 @@ // xfail-fast // aux-build:trait_default_method_xc_aux.rs -#[allow(default_methods)]; extern mod aux(name = "trait_default_method_xc_aux"); -use aux::{A, B, TestEquality, Something}; - +use aux::{A, TestEquality, Something}; +use aux::B; fn f(i: T) { assert_eq!(i.g(), 10); } +fn welp(i: int, x: &T) -> int { + i.g() +} + mod stuff { pub struct thing { x: int } } @@ -43,23 +46,26 @@ fn main () { // Some tests of random things f(0); + assert_eq!(A::lurr(&0, &1), 21); + let a = stuff::thing { x: 0 }; let b = stuff::thing { x: 1 }; let c = Something { x: 1 }; assert_eq!(0i.g(), 10); assert_eq!(a.g(), 10); - assert_eq!(a.h(), 10); - assert_eq!(c.h(), 10); + assert_eq!(a.h(), 11); + assert_eq!(c.h(), 11); - 0i.thing(3.14, 1); assert_eq!(0i.thing(3.14, 1), (3.14, 1)); + assert_eq!(B::staticthing(&0i, 3.14, 1), (3.14, 1)); + assert_eq!(B::staticthing::(&0i, 3.14, 1), (3.14, 1)); assert_eq!(g(0i, 3.14, 1), (3.14, 1)); assert_eq!(g(false, 3.14, 1), (3.14, 1)); let obj = @0i as @A; - assert_eq!(obj.h(), 10); + assert_eq!(obj.h(), 11); // Trying out a real one diff --git a/src/test/run-pass/trait-with-bounds-default.rs b/src/test/run-pass/trait-with-bounds-default.rs index b3ddbbb9dc1..689df437fb4 100644 --- a/src/test/run-pass/trait-with-bounds-default.rs +++ b/src/test/run-pass/trait-with-bounds-default.rs @@ -15,7 +15,6 @@ pub trait Clone2 { fn clone(&self) -> Self; } -#[allow(default_methods)] trait Getter { fn do_get(&self) -> T; diff --git a/src/test/run-pass/traits-default-method-macro.rs b/src/test/run-pass/traits-default-method-macro.rs index b25f345b9de..a78177ea892 100644 --- a/src/test/run-pass/traits-default-method-macro.rs +++ b/src/test/run-pass/traits-default-method-macro.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Foo { fn bar(&self) -> ~str { diff --git a/src/test/run-pass/traits-default-method-mut.rs b/src/test/run-pass/traits-default-method-mut.rs index 3286c4ef593..fee76646458 100644 --- a/src/test/run-pass/traits-default-method-mut.rs +++ b/src/test/run-pass/traits-default-method-mut.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Foo { fn foo(&self, mut v: int) { v = 1; } diff --git a/src/test/run-pass/traits-default-method-self.rs b/src/test/run-pass/traits-default-method-self.rs index 65009bb716d..1027008624a 100644 --- a/src/test/run-pass/traits-default-method-self.rs +++ b/src/test/run-pass/traits-default-method-self.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Cat { fn meow(&self) -> bool; diff --git a/src/test/run-pass/traits-default-method-trivial.rs b/src/test/run-pass/traits-default-method-trivial.rs index 998d8f8946f..c6a7ab5ba49 100644 --- a/src/test/run-pass/traits-default-method-trivial.rs +++ b/src/test/run-pass/traits-default-method-trivial.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[allow(default_methods)]; trait Cat { fn meow(&self) -> bool;