mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
librustc: Fix explicit self for objects in more cases. r=nmatsakis
This commit is contained in:
parent
4c2e4c37ce
commit
efb9b74718
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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})
|
||||
}
|
||||
};
|
||||
|
39
src/test/run-pass/explicit-self-objects-ext-1.rs
Normal file
39
src/test/run-pass/explicit-self-objects-ext-1.rs
Normal 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);
|
||||
}
|
39
src/test/run-pass/explicit-self-objects-ext-2.rs
Normal file
39
src/test/run-pass/explicit-self-objects-ext-2.rs
Normal 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);
|
||||
}
|
39
src/test/run-pass/explicit-self-objects-ext-3.rs
Normal file
39
src/test/run-pass/explicit-self-objects-ext-3.rs
Normal 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);
|
||||
}
|
39
src/test/run-pass/explicit-self-objects-ext-4.rs
Normal file
39
src/test/run-pass/explicit-self-objects-ext-4.rs
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user