Skip to content

Commit efb9b74

Browse files
committed
librustc: Fix explicit self for objects in more cases. r=nmatsakis
1 parent 4c2e4c3 commit efb9b74

File tree

7 files changed

+212
-49
lines changed

7 files changed

+212
-49
lines changed

src/librustc/middle/trans/meth.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,16 @@ fn trans_trait_callee(bcx: block,
550550
551551
let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
552552
let mut bcx = bcx;
553-
let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr));
553+
let self_datum = unpack_datum!(bcx,
554+
expr::trans_to_datum(bcx, self_expr));
554555
let llpair = self_datum.to_ref_llval(bcx);
556+
557+
let llpair = match explicit_self {
558+
ast::sty_region(_) => Load(bcx, llpair),
559+
ast::sty_static | ast::sty_by_ref | ast::sty_value |
560+
ast::sty_box(_) | ast::sty_uniq(_) => llpair
561+
};
562+
555563
let callee_ty = node_id_type(bcx, callee_id);
556564
trans_trait_callee_from_llval(bcx,
557565
callee_ty,

src/librustc/middle/typeck/check/method.rs

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,12 @@ struct Candidate {
153153
}
154154

155155
/**
156-
* Whether the self type should be transformed according to the form of
157-
* explicit self provided by the method.
156+
* How the self type should be transformed according to the form of explicit
157+
* self provided by the method.
158158
*/
159159
enum TransformTypeFlag {
160-
DontTransformType,
161-
TransformType
160+
TransformTypeNormally,
161+
TransformTypeForObject,
162162
}
163163

164164
impl LookupContext {
@@ -327,7 +327,8 @@ impl LookupContext {
327327
}
328328
}
329329

330-
fn push_inherent_candidates_from_param(&self, rcvr_ty: ty::t,
330+
fn push_inherent_candidates_from_param(&self,
331+
rcvr_ty: ty::t,
331332
param_ty: param_ty) {
332333
debug!("push_inherent_candidates_from_param(param_ty=%?)",
333334
param_ty);
@@ -426,7 +427,7 @@ impl LookupContext {
426427
method.self_ty,
427428
rcvr_ty,
428429
move init_substs,
429-
TransformType);
430+
TransformTypeNormally);
430431

431432
let cand = Candidate {
432433
rcvr_ty: rcvr_ty,
@@ -488,7 +489,7 @@ impl LookupContext {
488489
self.create_rcvr_ty_and_substs_for_method(method.self_ty,
489490
self_ty,
490491
move rcvr_substs,
491-
DontTransformType);
492+
TransformTypeForObject);
492493

493494
self.inherent_candidates.push(Candidate {
494495
rcvr_ty: rcvr_ty,
@@ -519,7 +520,7 @@ impl LookupContext {
519520
method.self_ty,
520521
self_ty,
521522
move rcvr_substs,
522-
TransformType);
523+
TransformTypeNormally);
523524

524525
self.inherent_candidates.push(Candidate {
525526
rcvr_ty: rcvr_ty,
@@ -574,7 +575,7 @@ impl LookupContext {
574575
method.self_type,
575576
impl_ty,
576577
move impl_substs,
577-
TransformType);
578+
TransformTypeNormally);
578579

579580
candidates.push(Candidate {
580581
rcvr_ty: impl_ty,
@@ -610,7 +611,7 @@ impl LookupContext {
610611
provided_method_info.method_info.self_type,
611612
self_ty,
612613
dummy_substs,
613-
TransformType);
614+
TransformTypeNormally);
614615

615616
candidates.push(Candidate {
616617
rcvr_ty: impl_ty,
@@ -658,18 +659,11 @@ impl LookupContext {
658659
}
659660
};
660661

661-
let rcvr_ty;
662-
match transform_type {
663-
TransformType => {
664-
rcvr_ty = transform_self_type_for_method(self.tcx(),
665-
rcvr_substs.self_r,
666-
self_ty,
667-
self_decl);
668-
}
669-
DontTransformType => {
670-
rcvr_ty = self_ty;
671-
}
672-
}
662+
let rcvr_ty = transform_self_type_for_method(self.tcx(),
663+
rcvr_substs.self_r,
664+
self_ty,
665+
self_decl,
666+
transform_type);
673667

674668
(rcvr_ty, rcvr_substs)
675669
}
@@ -686,6 +680,10 @@ impl LookupContext {
686680
match self.search_for_method(self_ty) {
687681
None => None,
688682
Some(move mme) => {
683+
debug!("(searching for autoderef'd method) writing \
684+
adjustment (%u) to %d",
685+
autoderefs,
686+
self.self_expr.id);
689687
self.fcx.write_autoderef_adjustment(
690688
self.self_expr.id, autoderefs);
691689
Some(mme)
@@ -814,25 +812,12 @@ impl LookupContext {
814812
match self.search_for_method(autoref_ty) {
815813
None => {}
816814
Some(move mme) => {
817-
match mme.origin {
818-
method_trait(*) => {
819-
// Do not write adjustments; they make no sense
820-
// here since the adjustments are to be performed
821-
// on the self element of the object pair/triple,
822-
// not the object itself.
823-
//
824-
// FIXME (#4088): This is wrong in the presence
825-
// of autoderef.
826-
}
827-
_ => {
828-
self.fcx.write_adjustment(
829-
self.self_expr.id,
830-
@{autoderefs: autoderefs,
831-
autoref: Some({kind: kind,
832-
region: region,
833-
mutbl: *mutbl})});
834-
}
835-
}
815+
self.fcx.write_adjustment(
816+
self.self_expr.id,
817+
@{autoderefs: autoderefs,
818+
autoref: Some({kind: kind,
819+
region: region,
820+
mutbl: *mutbl})});
836821
return Some(mme);
837822
}
838823
}
@@ -1162,9 +1147,9 @@ impl LookupContext {
11621147
fn transform_self_type_for_method(tcx: ty::ctxt,
11631148
self_region: Option<ty::Region>,
11641149
impl_ty: ty::t,
1165-
self_type: ast::self_ty_)
1166-
-> ty::t
1167-
{
1150+
self_type: ast::self_ty_,
1151+
flag: TransformTypeFlag)
1152+
-> ty::t {
11681153
match self_type {
11691154
sty_static => {
11701155
tcx.sess.bug(~"calling transform_self_type_for_method on \
@@ -1179,10 +1164,20 @@ fn transform_self_type_for_method(tcx: ty::ctxt,
11791164
{ ty: impl_ty, mutbl: mutability })
11801165
}
11811166
sty_box(mutability) => {
1182-
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
1167+
match flag {
1168+
TransformTypeNormally => {
1169+
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
1170+
}
1171+
TransformTypeForObject => impl_ty
1172+
}
11831173
}
11841174
sty_uniq(mutability) => {
1185-
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
1175+
match flag {
1176+
TransformTypeNormally => {
1177+
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
1178+
}
1179+
TransformTypeForObject => impl_ty
1180+
}
11861181
}
11871182
}
11881183
}

src/librustc/middle/typeck/check/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ type parameter).
7979
use middle::ty::{TyVid, vid, FnTyBase, FnMeta, FnSig, VariantInfo_};
8080
use middle::typeck::astconv::{ast_conv, ast_path_to_ty};
8181
use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
82+
use middle::typeck::check::method::TransformTypeNormally;
8283
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_ty;
8384
use middle::typeck::check::vtable::{LocationInfo, VtableContext};
8485
use middle::typeck::infer::{resolve_type, force_tvar};
@@ -318,8 +319,11 @@ fn check_fn(ccx: @crate_ctxt,
318319
} else {
319320
let self_region = fcx.in_scope_regions.find(ty::br_self);
320321
let ty = method::transform_self_type_for_method(
321-
fcx.tcx(), self_region,
322-
self_info.self_ty, self_info.explicit_self.node);
322+
fcx.tcx(),
323+
self_region,
324+
self_info.self_ty,
325+
self_info.explicit_self.node,
326+
TransformTypeNormally);
323327
Some({self_ty: ty,.. *self_info})
324328
}
325329
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
pub trait Reader {
2+
// FIXME (#2004): Seekable really should be orthogonal.
3+
4+
/// Read up to len bytes (or EOF) and put them into bytes (which
5+
/// must be at least len bytes long). Return number of bytes read.
6+
// FIXME (#2982): This should probably return an error.
7+
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
8+
}
9+
10+
pub trait ReaderUtil {
11+
12+
/// Read len bytes into a new vec.
13+
fn read_bytes(&self, len: uint);
14+
}
15+
16+
impl<T: Reader> T : ReaderUtil {
17+
18+
fn read_bytes(&self, len: uint) {
19+
let count = self.read(&[mut 0], len);
20+
}
21+
22+
}
23+
24+
struct S {
25+
x: int,
26+
y: int
27+
}
28+
29+
impl S: Reader {
30+
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
31+
0
32+
}
33+
}
34+
35+
fn main() {
36+
let x = S { x: 1, y: 2 };
37+
let x = x as @Reader;
38+
x.read_bytes(0);
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
pub trait Reader {
2+
// FIXME (#2004): Seekable really should be orthogonal.
3+
4+
/// Read up to len bytes (or EOF) and put them into bytes (which
5+
/// must be at least len bytes long). Return number of bytes read.
6+
// FIXME (#2982): This should probably return an error.
7+
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
8+
}
9+
10+
pub trait ReaderUtil {
11+
12+
/// Read len bytes into a new vec.
13+
fn read_bytes(&self, len: uint);
14+
}
15+
16+
impl<T: Reader> T : ReaderUtil {
17+
18+
fn read_bytes(&self, len: uint) {
19+
let count = self.read(&[mut 0], len);
20+
}
21+
22+
}
23+
24+
struct S {
25+
x: int,
26+
y: int
27+
}
28+
29+
impl S: Reader {
30+
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
31+
0
32+
}
33+
}
34+
35+
fn main() {
36+
let x = S { x: 1, y: 2 };
37+
let x = x as @Reader;
38+
x.read_bytes(0);
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
pub trait Reader {
2+
// FIXME (#2004): Seekable really should be orthogonal.
3+
4+
/// Read up to len bytes (or EOF) and put them into bytes (which
5+
/// must be at least len bytes long). Return number of bytes read.
6+
// FIXME (#2982): This should probably return an error.
7+
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
8+
}
9+
10+
pub trait ReaderUtil {
11+
12+
/// Read len bytes into a new vec.
13+
fn read_bytes(len: uint);
14+
}
15+
16+
impl<T: Reader> T : ReaderUtil {
17+
18+
fn read_bytes(len: uint) {
19+
let count = self.read(&[mut 0], len);
20+
}
21+
22+
}
23+
24+
struct S {
25+
x: int,
26+
y: int
27+
}
28+
29+
impl S: Reader {
30+
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
31+
0
32+
}
33+
}
34+
35+
fn main() {
36+
let x = S { x: 1, y: 2 };
37+
let x = x as @Reader;
38+
x.read_bytes(0);
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
pub trait Reader {
2+
// FIXME (#2004): Seekable really should be orthogonal.
3+
4+
/// Read up to len bytes (or EOF) and put them into bytes (which
5+
/// must be at least len bytes long). Return number of bytes read.
6+
// FIXME (#2982): This should probably return an error.
7+
fn read(bytes: &[mut u8], len: uint) -> uint;
8+
}
9+
10+
pub trait ReaderUtil {
11+
12+
/// Read len bytes into a new vec.
13+
fn read_bytes(len: uint);
14+
}
15+
16+
impl<T: Reader> T : ReaderUtil {
17+
18+
fn read_bytes(len: uint) {
19+
let count = self.read(&[mut 0], len);
20+
}
21+
22+
}
23+
24+
struct S {
25+
x: int,
26+
y: int
27+
}
28+
29+
impl S: Reader {
30+
fn read(bytes: &[mut u8], len: uint) -> uint {
31+
0
32+
}
33+
}
34+
35+
fn main() {
36+
let x = S { x: 1, y: 2 };
37+
let x = x as @Reader;
38+
x.read_bytes(0);
39+
}

0 commit comments

Comments
 (0)