librustc: Fix explicit self for objects in more cases. r=nmatsakis

This commit is contained in:
Patrick Walton 2012-12-13 13:09:38 -08:00
parent 4c2e4c37ce
commit efb9b74718
7 changed files with 212 additions and 49 deletions

View file

@ -550,8 +550,16 @@ fn trans_trait_callee(bcx: block,
let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
let mut bcx = bcx;
let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr));
let self_datum = unpack_datum!(bcx,
expr::trans_to_datum(bcx, self_expr));
let llpair = self_datum.to_ref_llval(bcx);
let llpair = match explicit_self {
ast::sty_region(_) => Load(bcx, llpair),
ast::sty_static | ast::sty_by_ref | ast::sty_value |
ast::sty_box(_) | ast::sty_uniq(_) => llpair
};
let callee_ty = node_id_type(bcx, callee_id);
trans_trait_callee_from_llval(bcx,
callee_ty,

View file

@ -153,12 +153,12 @@ struct Candidate {
}
/**
* Whether the self type should be transformed according to the form of
* explicit self provided by the method.
* How the self type should be transformed according to the form of explicit
* self provided by the method.
*/
enum TransformTypeFlag {
DontTransformType,
TransformType
TransformTypeNormally,
TransformTypeForObject,
}
impl LookupContext {
@ -327,7 +327,8 @@ impl LookupContext {
}
}
fn push_inherent_candidates_from_param(&self, rcvr_ty: ty::t,
fn push_inherent_candidates_from_param(&self,
rcvr_ty: ty::t,
param_ty: param_ty) {
debug!("push_inherent_candidates_from_param(param_ty=%?)",
param_ty);
@ -426,7 +427,7 @@ impl LookupContext {
method.self_ty,
rcvr_ty,
move init_substs,
TransformType);
TransformTypeNormally);
let cand = Candidate {
rcvr_ty: rcvr_ty,
@ -488,7 +489,7 @@ impl LookupContext {
self.create_rcvr_ty_and_substs_for_method(method.self_ty,
self_ty,
move rcvr_substs,
DontTransformType);
TransformTypeForObject);
self.inherent_candidates.push(Candidate {
rcvr_ty: rcvr_ty,
@ -519,7 +520,7 @@ impl LookupContext {
method.self_ty,
self_ty,
move rcvr_substs,
TransformType);
TransformTypeNormally);
self.inherent_candidates.push(Candidate {
rcvr_ty: rcvr_ty,
@ -574,7 +575,7 @@ impl LookupContext {
method.self_type,
impl_ty,
move impl_substs,
TransformType);
TransformTypeNormally);
candidates.push(Candidate {
rcvr_ty: impl_ty,
@ -610,7 +611,7 @@ impl LookupContext {
provided_method_info.method_info.self_type,
self_ty,
dummy_substs,
TransformType);
TransformTypeNormally);
candidates.push(Candidate {
rcvr_ty: impl_ty,
@ -658,18 +659,11 @@ impl LookupContext {
}
};
let rcvr_ty;
match transform_type {
TransformType => {
rcvr_ty = transform_self_type_for_method(self.tcx(),
rcvr_substs.self_r,
self_ty,
self_decl);
}
DontTransformType => {
rcvr_ty = self_ty;
}
}
let rcvr_ty = transform_self_type_for_method(self.tcx(),
rcvr_substs.self_r,
self_ty,
self_decl,
transform_type);
(rcvr_ty, rcvr_substs)
}
@ -686,6 +680,10 @@ impl LookupContext {
match self.search_for_method(self_ty) {
None => None,
Some(move mme) => {
debug!("(searching for autoderef'd method) writing \
adjustment (%u) to %d",
autoderefs,
self.self_expr.id);
self.fcx.write_autoderef_adjustment(
self.self_expr.id, autoderefs);
Some(mme)
@ -814,25 +812,12 @@ impl LookupContext {
match self.search_for_method(autoref_ty) {
None => {}
Some(move mme) => {
match mme.origin {
method_trait(*) => {
// Do not write adjustments; they make no sense
// here since the adjustments are to be performed
// on the self element of the object pair/triple,
// not the object itself.
//
// FIXME (#4088): This is wrong in the presence
// of autoderef.
}
_ => {
self.fcx.write_adjustment(
self.self_expr.id,
@{autoderefs: autoderefs,
autoref: Some({kind: kind,
region: region,
mutbl: *mutbl})});
}
}
self.fcx.write_adjustment(
self.self_expr.id,
@{autoderefs: autoderefs,
autoref: Some({kind: kind,
region: region,
mutbl: *mutbl})});
return Some(mme);
}
}
@ -1162,9 +1147,9 @@ impl LookupContext {
fn transform_self_type_for_method(tcx: ty::ctxt,
self_region: Option<ty::Region>,
impl_ty: ty::t,
self_type: ast::self_ty_)
-> ty::t
{
self_type: ast::self_ty_,
flag: TransformTypeFlag)
-> ty::t {
match self_type {
sty_static => {
tcx.sess.bug(~"calling transform_self_type_for_method on \
@ -1179,10 +1164,20 @@ fn transform_self_type_for_method(tcx: ty::ctxt,
{ ty: impl_ty, mutbl: mutability })
}
sty_box(mutability) => {
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
match flag {
TransformTypeNormally => {
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
}
TransformTypeForObject => impl_ty
}
}
sty_uniq(mutability) => {
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
match flag {
TransformTypeNormally => {
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
}
TransformTypeForObject => impl_ty
}
}
}
}

View file

@ -79,6 +79,7 @@ type parameter).
use middle::ty::{TyVid, vid, FnTyBase, FnMeta, FnSig, VariantInfo_};
use middle::typeck::astconv::{ast_conv, ast_path_to_ty};
use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
use middle::typeck::check::method::TransformTypeNormally;
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_ty;
use middle::typeck::check::vtable::{LocationInfo, VtableContext};
use middle::typeck::infer::{resolve_type, force_tvar};
@ -318,8 +319,11 @@ fn check_fn(ccx: @crate_ctxt,
} else {
let self_region = fcx.in_scope_regions.find(ty::br_self);
let ty = method::transform_self_type_for_method(
fcx.tcx(), self_region,
self_info.self_ty, self_info.explicit_self.node);
fcx.tcx(),
self_region,
self_info.self_ty,
self_info.explicit_self.node,
TransformTypeNormally);
Some({self_ty: ty,.. *self_info})
}
};

View file

@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}
pub trait ReaderUtil {
/// Read len bytes into a new vec.
fn read_bytes(&self, len: uint);
}
impl<T: Reader> T : ReaderUtil {
fn read_bytes(&self, len: uint) {
let count = self.read(&[mut 0], len);
}
}
struct S {
x: int,
y: int
}
impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}
fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}

View file

@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}
pub trait ReaderUtil {
/// Read len bytes into a new vec.
fn read_bytes(&self, len: uint);
}
impl<T: Reader> T : ReaderUtil {
fn read_bytes(&self, len: uint) {
let count = self.read(&[mut 0], len);
}
}
struct S {
x: int,
y: int
}
impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}
fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}

View file

@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}
pub trait ReaderUtil {
/// Read len bytes into a new vec.
fn read_bytes(len: uint);
}
impl<T: Reader> T : ReaderUtil {
fn read_bytes(len: uint) {
let count = self.read(&[mut 0], len);
}
}
struct S {
x: int,
y: int
}
impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}
fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}

View file

@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.
/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(bytes: &[mut u8], len: uint) -> uint;
}
pub trait ReaderUtil {
/// Read len bytes into a new vec.
fn read_bytes(len: uint);
}
impl<T: Reader> T : ReaderUtil {
fn read_bytes(len: uint) {
let count = self.read(&[mut 0], len);
}
}
struct S {
x: int,
y: int
}
impl S: Reader {
fn read(bytes: &[mut u8], len: uint) -> uint {
0
}
}
fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}