auto merge of #18053 : nick29581/rust/ufcs1, r=pcwalton
With the 'receiver' as an argument and static dispatch. Part of UFCS implementation (#16293). r?
This commit is contained in:
commit
71dfa5befe
14 changed files with 231 additions and 114 deletions
|
@ -407,13 +407,10 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
|
||||||
method_did.def_id());
|
method_did.def_id());
|
||||||
match impl_item {
|
match impl_item {
|
||||||
ty::MethodTraitItem(ref m) => {
|
ty::MethodTraitItem(ref m) => {
|
||||||
if m.explicit_self ==
|
encode_reexported_static_method(rbml_w,
|
||||||
ty::StaticExplicitSelfCategory {
|
exp,
|
||||||
encode_reexported_static_method(rbml_w,
|
m.def_id,
|
||||||
exp,
|
m.ident);
|
||||||
m.def_id,
|
|
||||||
m.ident);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::TypeTraitItem(_) => {}
|
ty::TypeTraitItem(_) => {}
|
||||||
}
|
}
|
||||||
|
@ -434,8 +431,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
|
||||||
Some(trait_items) => {
|
Some(trait_items) => {
|
||||||
for trait_item in trait_items.iter() {
|
for trait_item in trait_items.iter() {
|
||||||
match *trait_item {
|
match *trait_item {
|
||||||
ty::MethodTraitItem(ref m) if m.explicit_self ==
|
ty::MethodTraitItem(ref m) => {
|
||||||
ty::StaticExplicitSelfCategory => {
|
|
||||||
encode_reexported_static_method(rbml_w,
|
encode_reexported_static_method(rbml_w,
|
||||||
exp,
|
exp,
|
||||||
m.def_id,
|
m.def_id,
|
||||||
|
@ -1408,18 +1404,16 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
encode_family(rbml_w,
|
encode_family(rbml_w,
|
||||||
fn_style_static_method_family(
|
fn_style_static_method_family(
|
||||||
method_ty.fty.fn_style));
|
method_ty.fty.fn_style));
|
||||||
|
|
||||||
let pty = ty::lookup_item_type(tcx,
|
|
||||||
method_def_id);
|
|
||||||
encode_bounds_and_type(rbml_w, ecx, &pty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
encode_family(rbml_w,
|
encode_family(rbml_w,
|
||||||
style_fn_family(
|
style_fn_family(
|
||||||
method_ty.fty.fn_style));
|
method_ty.fty.fn_style));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let pty = ty::lookup_item_type(tcx,
|
||||||
|
method_def_id);
|
||||||
|
encode_bounds_and_type(rbml_w, ecx, &pty);
|
||||||
|
|
||||||
is_nonstatic_method = method_ty.explicit_self !=
|
is_nonstatic_method = method_ty.explicit_self !=
|
||||||
ty::StaticExplicitSelfCategory;
|
ty::StaticExplicitSelfCategory;
|
||||||
|
|
|
@ -453,8 +453,8 @@ impl tr for def::Def {
|
||||||
},
|
},
|
||||||
p)
|
p)
|
||||||
}
|
}
|
||||||
def::DefMethod(did0, did1) => {
|
def::DefMethod(did0, did1, p) => {
|
||||||
def::DefMethod(did0.tr(dcx), did1.map(|did1| did1.tr(dcx)))
|
def::DefMethod(did0.tr(dcx), did1.map(|did1| did1.tr(dcx)), p)
|
||||||
}
|
}
|
||||||
def::DefSelfTy(nid) => { def::DefSelfTy(dcx.tr_id(nid)) }
|
def::DefSelfTy(nid) => { def::DefSelfTy(dcx.tr_id(nid)) }
|
||||||
def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
|
def::DefMod(did) => { def::DefMod(did.tr(dcx)) }
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub enum Def {
|
||||||
DefTyParamBinder(ast::NodeId), /* struct, impl or trait with ty params */
|
DefTyParamBinder(ast::NodeId), /* struct, impl or trait with ty params */
|
||||||
DefRegion(ast::NodeId),
|
DefRegion(ast::NodeId),
|
||||||
DefLabel(ast::NodeId),
|
DefLabel(ast::NodeId),
|
||||||
DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */),
|
DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||||
|
@ -62,7 +62,7 @@ impl Def {
|
||||||
DefForeignMod(id) | DefStatic(id, _) |
|
DefForeignMod(id) | DefStatic(id, _) |
|
||||||
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
|
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
|
||||||
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
|
DefTyParam(_, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
|
||||||
DefMethod(id, _) | DefConst(id) => {
|
DefMethod(id, _, _) | DefConst(id) => {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
DefLocal(id) |
|
DefLocal(id) |
|
||||||
|
|
|
@ -811,7 +811,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
def::DefTy(_, true) => ck("enum"),
|
def::DefTy(_, true) => ck("enum"),
|
||||||
def::DefTrait(..) => ck("trait"),
|
def::DefTrait(..) => ck("trait"),
|
||||||
def::DefStruct(..) => ck("struct"),
|
def::DefStruct(..) => ck("struct"),
|
||||||
def::DefMethod(_, Some(..)) => ck("trait method"),
|
def::DefMethod(_, Some(..), _) => ck("trait method"),
|
||||||
def::DefMethod(..) => ck("method"),
|
def::DefMethod(..) => ck("method"),
|
||||||
def::DefMod(..) => ck("module"),
|
def::DefMod(..) => ck("module"),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -250,7 +250,7 @@ enum FallbackSuggestion {
|
||||||
Method,
|
Method,
|
||||||
TraitItem,
|
TraitItem,
|
||||||
StaticMethod(String),
|
StaticMethod(String),
|
||||||
StaticTraitMethod(String),
|
TraitMethod(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TypeParameters<'a> {
|
enum TypeParameters<'a> {
|
||||||
|
@ -1386,17 +1386,17 @@ impl<'a> Resolver<'a> {
|
||||||
.node {
|
.node {
|
||||||
SelfStatic => {
|
SelfStatic => {
|
||||||
// Static methods become
|
// Static methods become
|
||||||
// `def_static_method`s.
|
// `DefStaticMethod`s.
|
||||||
DefStaticMethod(
|
DefStaticMethod(local_def(method.id),
|
||||||
local_def(method.id),
|
FromImpl(local_def(item.id)),
|
||||||
FromImpl(local_def(item.id)),
|
method.pe_fn_style())
|
||||||
method.pe_fn_style())
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Non-static methods become
|
// Non-static methods become
|
||||||
// `def_method`s.
|
// `DefMethod`s.
|
||||||
DefMethod(local_def(method.id),
|
DefMethod(local_def(method.id),
|
||||||
None)
|
None,
|
||||||
|
FromImpl(local_def(item.id)))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1476,8 +1476,7 @@ impl<'a> Resolver<'a> {
|
||||||
let (def, static_flag) = match ty_m.explicit_self
|
let (def, static_flag) = match ty_m.explicit_self
|
||||||
.node {
|
.node {
|
||||||
SelfStatic => {
|
SelfStatic => {
|
||||||
// Static methods become
|
// Static methods become `DefStaticMethod`s.
|
||||||
// `def_static_method`s.
|
|
||||||
(DefStaticMethod(
|
(DefStaticMethod(
|
||||||
local_def(ty_m.id),
|
local_def(ty_m.id),
|
||||||
FromTrait(local_def(item.id)),
|
FromTrait(local_def(item.id)),
|
||||||
|
@ -1485,10 +1484,10 @@ impl<'a> Resolver<'a> {
|
||||||
StaticMethodTraitItemKind)
|
StaticMethodTraitItemKind)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Non-static methods become
|
// Non-static methods become `DefMethod`s.
|
||||||
// `def_method`s.
|
|
||||||
(DefMethod(local_def(ty_m.id),
|
(DefMethod(local_def(ty_m.id),
|
||||||
Some(local_def(item.id))),
|
Some(local_def(item.id)),
|
||||||
|
FromTrait(local_def(item.id))),
|
||||||
NonstaticMethodTraitItemKind)
|
NonstaticMethodTraitItemKind)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4607,8 +4606,7 @@ impl<'a> Resolver<'a> {
|
||||||
// We also need a new scope for the method-
|
// We also need a new scope for the method-
|
||||||
// specific type parameters.
|
// specific type parameters.
|
||||||
this.resolve_method(
|
this.resolve_method(
|
||||||
MethodRibKind(id,
|
MethodRibKind(id, ProvidedMethod(method.id)),
|
||||||
ProvidedMethod(method.id)),
|
|
||||||
&**method);
|
&**method);
|
||||||
}
|
}
|
||||||
TypeImplItem(ref typedef) => {
|
TypeImplItem(ref typedef) => {
|
||||||
|
@ -5393,8 +5391,8 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
let ident = path.segments.last().unwrap().identifier;
|
let ident = path.segments.last().unwrap().identifier;
|
||||||
let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
|
let def = match self.resolve_definition_of_name_in_module(containing_module.clone(),
|
||||||
ident.name,
|
ident.name,
|
||||||
namespace) {
|
namespace) {
|
||||||
NoNameDefinition => {
|
NoNameDefinition => {
|
||||||
// We failed to resolve the name. Report an error.
|
// We failed to resolve the name. Report an error.
|
||||||
return None;
|
return None;
|
||||||
|
@ -5403,26 +5401,6 @@ impl<'a> Resolver<'a> {
|
||||||
(def, last_private.or(lp))
|
(def, last_private.or(lp))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match containing_module.kind.get() {
|
|
||||||
TraitModuleKind | ImplModuleKind => {
|
|
||||||
match containing_module.def_id.get() {
|
|
||||||
Some(def_id) => {
|
|
||||||
match self.trait_item_map.find(&(ident.name, def_id)) {
|
|
||||||
Some(&StaticMethodTraitItemKind) => (),
|
|
||||||
Some(&TypeTraitItemKind) => (),
|
|
||||||
None => (),
|
|
||||||
Some(&NonstaticMethodTraitItemKind) => {
|
|
||||||
debug!("containing module was a trait or impl \
|
|
||||||
and name was a method -> not resolved");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
match containing_module.def_id.get() {
|
match containing_module.def_id.get() {
|
||||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -5668,8 +5646,8 @@ impl<'a> Resolver<'a> {
|
||||||
FromTrait(_) => unreachable!()
|
FromTrait(_) => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(DefMethod(_, None)) if allowed == Everything => return Method,
|
Some(DefMethod(_, None, _)) if allowed == Everything => return Method,
|
||||||
Some(DefMethod(_, Some(_))) => return TraitItem,
|
Some(DefMethod(_, Some(_), _)) => return TraitItem,
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5684,7 +5662,9 @@ impl<'a> Resolver<'a> {
|
||||||
let path_str = self.path_idents_to_string(&trait_ref.path);
|
let path_str = self.path_idents_to_string(&trait_ref.path);
|
||||||
|
|
||||||
match self.trait_item_map.find(&(name, did)) {
|
match self.trait_item_map.find(&(name, did)) {
|
||||||
Some(&StaticMethodTraitItemKind) => return StaticTraitMethod(path_str),
|
Some(&StaticMethodTraitItemKind) => {
|
||||||
|
return TraitMethod(path_str)
|
||||||
|
}
|
||||||
Some(_) => return TraitItem,
|
Some(_) => return TraitItem,
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -5751,22 +5731,6 @@ impl<'a> Resolver<'a> {
|
||||||
// Write the result into the def map.
|
// Write the result into the def map.
|
||||||
debug!("(resolving expr) resolved `{}`",
|
debug!("(resolving expr) resolved `{}`",
|
||||||
self.path_idents_to_string(path));
|
self.path_idents_to_string(path));
|
||||||
|
|
||||||
// First-class methods are not supported yet; error
|
|
||||||
// out here.
|
|
||||||
match def {
|
|
||||||
(DefMethod(..), _) => {
|
|
||||||
self.resolve_error(expr.span,
|
|
||||||
"first-class methods \
|
|
||||||
are not supported");
|
|
||||||
self.session.span_note(expr.span,
|
|
||||||
"call the method \
|
|
||||||
using the `.` \
|
|
||||||
syntax");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.record_def(expr.id, def);
|
self.record_def(expr.id, def);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -5826,7 +5790,7 @@ impl<'a> Resolver<'a> {
|
||||||
Method
|
Method
|
||||||
| TraitItem =>
|
| TraitItem =>
|
||||||
format!("to call `self.{}`", wrong_name),
|
format!("to call `self.{}`", wrong_name),
|
||||||
StaticTraitMethod(path_str)
|
TraitMethod(path_str)
|
||||||
| StaticMethod(path_str) =>
|
| StaticMethod(path_str) =>
|
||||||
format!("to call `{}::{}`", path_str, wrong_name)
|
format!("to call `{}::{}`", path_str, wrong_name)
|
||||||
};
|
};
|
||||||
|
|
|
@ -244,7 +244,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
||||||
def::DefStaticMethod(_, _, _) |
|
def::DefStaticMethod(_, _, _) |
|
||||||
def::DefTyParam(..) |
|
def::DefTyParam(..) |
|
||||||
def::DefUse(_) |
|
def::DefUse(_) |
|
||||||
def::DefMethod(_, _) |
|
def::DefMethod(..) |
|
||||||
def::DefPrimTy(_) => {
|
def::DefPrimTy(_) => {
|
||||||
self.sess.span_bug(span, format!("lookup_def_kind for unexpected item: {:?}",
|
self.sess.span_bug(span, format!("lookup_def_kind for unexpected item: {:?}",
|
||||||
def).as_slice());
|
def).as_slice());
|
||||||
|
|
|
@ -137,7 +137,9 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, def: def::Def, ref_expr: &ast::Expr)
|
fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
|
def: def::Def,
|
||||||
|
ref_expr: &ast::Expr)
|
||||||
-> Callee<'blk, 'tcx> {
|
-> Callee<'blk, 'tcx> {
|
||||||
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
|
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
|
||||||
let expr_ty = node_id_type(bcx, ref_expr.id);
|
let expr_ty = node_id_type(bcx, ref_expr.id);
|
||||||
|
@ -165,14 +167,13 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
|
||||||
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
|
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
|
||||||
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
|
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
|
||||||
}
|
}
|
||||||
def::DefFn(did, _, _) |
|
def::DefFn(did, _, _) | def::DefMethod(did, _, def::FromImpl(_)) |
|
||||||
def::DefStaticMethod(did, def::FromImpl(_), _) => {
|
def::DefStaticMethod(did, def::FromImpl(_), _) => {
|
||||||
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
|
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
|
||||||
}
|
}
|
||||||
def::DefStaticMethod(impl_did,
|
def::DefStaticMethod(meth_did, def::FromTrait(trait_did), _) |
|
||||||
def::FromTrait(trait_did),
|
def::DefMethod(meth_did, _, def::FromTrait(trait_did)) => {
|
||||||
_) => {
|
fn_callee(bcx, meth::trans_static_method_callee(bcx, meth_did,
|
||||||
fn_callee(bcx, meth::trans_static_method_callee(bcx, impl_did,
|
|
||||||
trait_did,
|
trait_did,
|
||||||
ref_expr.id))
|
ref_expr.id))
|
||||||
}
|
}
|
||||||
|
@ -205,7 +206,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
|
||||||
def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
|
def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
|
||||||
def::DefUse(..) | def::DefTyParamBinder(..) |
|
def::DefUse(..) | def::DefTyParamBinder(..) |
|
||||||
def::DefRegion(..) | def::DefLabel(..) | def::DefTyParam(..) |
|
def::DefRegion(..) | def::DefLabel(..) | def::DefTyParam(..) |
|
||||||
def::DefSelfTy(..) | def::DefMethod(..) => {
|
def::DefSelfTy(..) => {
|
||||||
bcx.tcx().sess.span_bug(
|
bcx.tcx().sess.span_bug(
|
||||||
ref_expr.span,
|
ref_expr.span,
|
||||||
format!("cannot translate def {:?} \
|
format!("cannot translate def {:?} \
|
||||||
|
|
|
@ -5027,7 +5027,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
|
||||||
let typ = fcx.local_ty(sp, nid);
|
let typ = fcx.local_ty(sp, nid);
|
||||||
return no_params(typ);
|
return no_params(typ);
|
||||||
}
|
}
|
||||||
def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) |
|
def::DefFn(id, _, _) | def::DefStaticMethod(id, _, _) | def::DefMethod(id, _, _) |
|
||||||
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
|
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
|
||||||
def::DefStruct(id) | def::DefConst(id) => {
|
def::DefStruct(id) | def::DefConst(id) => {
|
||||||
return ty::lookup_item_type(fcx.ccx.tcx, id);
|
return ty::lookup_item_type(fcx.ccx.tcx, id);
|
||||||
|
@ -5057,9 +5057,6 @@ pub fn polytype_for_def(fcx: &FnCtxt,
|
||||||
def::DefSelfTy(..) => {
|
def::DefSelfTy(..) => {
|
||||||
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found self ty");
|
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found self ty");
|
||||||
}
|
}
|
||||||
def::DefMethod(..) => {
|
|
||||||
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found method");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5231,8 +5228,7 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
||||||
}
|
}
|
||||||
|
|
||||||
fcx.add_obligations_for_parameters(
|
fcx.add_obligations_for_parameters(
|
||||||
traits::ObligationCause::new(span,
|
traits::ObligationCause::new(span, traits::ItemObligation(def.def_id())),
|
||||||
traits::ItemObligation(def.def_id())),
|
|
||||||
&substs,
|
&substs,
|
||||||
&polytype.generics);
|
&polytype.generics);
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,12 @@ pub fn collect_item_types(ccx: &CrateCtxt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match ccx.tcx.lang_items.ty_desc() {
|
match ccx.tcx.lang_items.ty_desc() {
|
||||||
Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
|
Some(id) => { collect_intrinsic_type(ccx, id); }
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
match ccx.tcx.lang_items.opaque() {
|
match ccx.tcx.lang_items.opaque() {
|
||||||
Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
|
Some(id) => { collect_intrinsic_type(ccx, id); }
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
|
let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
|
||||||
|
@ -306,10 +308,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if ty_method.explicit_self ==
|
make_method_ty(ccx, &*ty_method);
|
||||||
ty::StaticExplicitSelfCategory {
|
|
||||||
make_static_method_ty(ccx, &*ty_method);
|
|
||||||
}
|
|
||||||
|
|
||||||
tcx.impl_or_trait_items
|
tcx.impl_or_trait_items
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -364,7 +363,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
||||||
_ => { /* Ignore things that aren't traits */ }
|
_ => { /* Ignore things that aren't traits */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_static_method_ty(ccx: &CrateCtxt, m: &ty::Method) {
|
fn make_method_ty(ccx: &CrateCtxt, m: &ty::Method) {
|
||||||
ccx.tcx.tcache.borrow_mut().insert(
|
ccx.tcx.tcache.borrow_mut().insert(
|
||||||
m.def_id,
|
m.def_id,
|
||||||
Polytype {
|
Polytype {
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
// 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 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
// issue #6698
|
|
||||||
|
|
||||||
fn V() -> bool {
|
|
||||||
std::clone::Clone::clone(true) //~ ERROR error: unresolved name `std::clone::Clone::clone`.
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
24
src/test/compile-fail/method-self-arg-1.rs
Normal file
24
src/test/compile-fail/method-self-arg-1.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2014 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test method calls with self as an argument cannot subvert type checking.
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn bar(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Foo;
|
||||||
|
Foo::bar(x); //~ERROR mismatched types: expected `&Foo`, found `Foo`
|
||||||
|
Foo::bar(&&x); //~ERROR mismatched types: expected `&Foo`, found `&&Foo`
|
||||||
|
Foo::bar(&42i); //~ERROR mismatched types: expected `&Foo`, found `&int`
|
||||||
|
}
|
27
src/test/compile-fail/method-self-arg-2.rs
Normal file
27
src/test/compile-fail/method-self-arg-2.rs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Copyright 2014 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test method calls with self as an argument cannot subvert borrow checking.
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn bar(&self) {}
|
||||||
|
fn baz(&mut self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut x = Foo;
|
||||||
|
let y = &mut x;
|
||||||
|
Foo::bar(&x); //~ERROR cannot borrow `x`
|
||||||
|
|
||||||
|
let x = Foo;
|
||||||
|
Foo::baz(&x); //~ERROR cannot borrow immutable dereference of `&`-pointer as mutable
|
||||||
|
}
|
75
src/test/run-pass/method-self-arg-trait.rs
Normal file
75
src/test/run-pass/method-self-arg-trait.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
// Copyright 2014 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test method calls with self as an argument
|
||||||
|
|
||||||
|
static mut COUNT: u64 = 1;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
fn foo1(&self);
|
||||||
|
fn foo2(self);
|
||||||
|
fn foo3(self: Box<Self>);
|
||||||
|
|
||||||
|
fn bar1(&self) {
|
||||||
|
unsafe { COUNT *= 7; }
|
||||||
|
}
|
||||||
|
fn bar2(self) {
|
||||||
|
unsafe { COUNT *= 11; }
|
||||||
|
}
|
||||||
|
fn bar3(self: Box<Self>) {
|
||||||
|
unsafe { COUNT *= 13; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bar for Foo {
|
||||||
|
fn foo1(&self) {
|
||||||
|
unsafe { COUNT *= 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo2(self) {
|
||||||
|
unsafe { COUNT *= 3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo3(self: Box<Foo>) {
|
||||||
|
unsafe { COUNT *= 5; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn baz(self) {
|
||||||
|
unsafe { COUNT *= 17; }
|
||||||
|
// Test internal call.
|
||||||
|
Bar::foo1(&self);
|
||||||
|
Bar::foo2(self);
|
||||||
|
Bar::foo3(box self);
|
||||||
|
|
||||||
|
Bar::bar1(&self);
|
||||||
|
Bar::bar2(self);
|
||||||
|
Bar::bar3(box self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Foo;
|
||||||
|
// Test external call.
|
||||||
|
Bar::foo1(&x);
|
||||||
|
Bar::foo2(x);
|
||||||
|
Bar::foo3(box x);
|
||||||
|
|
||||||
|
Bar::bar1(&x);
|
||||||
|
Bar::bar2(x);
|
||||||
|
Bar::bar3(box x);
|
||||||
|
|
||||||
|
x.baz();
|
||||||
|
|
||||||
|
unsafe { assert!(COUNT == 2u64*2*3*3*5*5*7*7*11*11*13*13*17); }
|
||||||
|
}
|
54
src/test/run-pass/method-self-arg.rs
Normal file
54
src/test/run-pass/method-self-arg.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2014 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// Test method calls with self as an argument
|
||||||
|
|
||||||
|
static mut COUNT: uint = 1;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn foo(self, x: &Foo) {
|
||||||
|
unsafe { COUNT *= 2; }
|
||||||
|
// Test internal call.
|
||||||
|
Foo::bar(&self);
|
||||||
|
Foo::bar(x);
|
||||||
|
|
||||||
|
Foo::baz(self);
|
||||||
|
Foo::baz(*x);
|
||||||
|
|
||||||
|
Foo::qux(box self);
|
||||||
|
Foo::qux(box *x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(&self) {
|
||||||
|
unsafe { COUNT *= 3; }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz(self) {
|
||||||
|
unsafe { COUNT *= 5; }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn qux(self: Box<Foo>) {
|
||||||
|
unsafe { COUNT *= 7; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Foo;
|
||||||
|
// Test external call.
|
||||||
|
Foo::bar(&x);
|
||||||
|
Foo::baz(x);
|
||||||
|
Foo::qux(box x);
|
||||||
|
|
||||||
|
x.foo(&x);
|
||||||
|
|
||||||
|
unsafe { assert!(COUNT == 2u*3*3*3*5*5*5*7*7*7); }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue