Skip to content

Commit 1bceb98

Browse files
committed
typeck: Modify method resolution to use new object adjustments, and
to favor inherent methods over extension methods. The reason to favor inherent methods is that otherwise an impl like impl Foo for @foo { fn method(&self) { self.method() } } causes infinite recursion. The current change to favor inherent methods is rather hacky; the method resolution code is in need of a refactoring.
1 parent 006c6b6 commit 1bceb98

File tree

8 files changed

+317
-140
lines changed

8 files changed

+317
-140
lines changed

src/librustc/middle/astencode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ impl tr for method_origin {
586586
}
587587
)
588588
}
589-
typeck::method_trait(did, m, vstore) => {
590-
typeck::method_trait(did.tr(xcx), m, vstore)
589+
typeck::method_trait(did, m) => {
590+
typeck::method_trait(did.tr(xcx), m)
591591
}
592592
}
593593
}

src/librustc/middle/privacy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
290290
method_num: method_num,
291291
_
292292
}) |
293-
method_trait(trait_id, method_num, _) => {
293+
method_trait(trait_id, method_num) => {
294294
if trait_id.crate == LOCAL_CRATE {
295295
match tcx.items.find(&trait_id.node) {
296296
Some(&node_item(item, _)) => {

src/librustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3131,7 +3131,7 @@ pub fn method_call_type_param_defs(tcx: ctxt,
31313131
typeck::method_param(typeck::method_param {
31323132
trait_id: trt_id,
31333133
method_num: n_mth, _}) |
3134-
typeck::method_trait(trt_id, n_mth, _) => {
3134+
typeck::method_trait(trt_id, n_mth) => {
31353135
// ...trait methods bounds, in contrast, include only the
31363136
// method bounds, so we must preprend the tps from the
31373137
// trait itself. This ought to be harmonized.

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

Lines changed: 265 additions & 129 deletions
Large diffs are not rendered by default.

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,8 @@ pub mod guarantor {
863863

864864
ty::AutoBorrowVec(r, _) |
865865
ty::AutoBorrowVecRef(r, _) |
866-
ty::AutoBorrowFn(r) => {
866+
ty::AutoBorrowFn(r) |
867+
ty::AutoBorrowObj(r, _) => {
867868
// In each of these cases, what is being borrowed is
868869
// not the (autoderef'd) expr itself but rather the
869870
// contents of the autoderef'd expression (i.e., what
@@ -1072,7 +1073,8 @@ pub mod guarantor {
10721073
Some(ty::AutoPtr(r, _)) |
10731074
Some(ty::AutoBorrowVec(r, _)) |
10741075
Some(ty::AutoBorrowVecRef(r, _)) |
1075-
Some(ty::AutoBorrowFn(r)) => {
1076+
Some(ty::AutoBorrowFn(r)) |
1077+
Some(ty::AutoBorrowObj(r, _)) => {
10761078
// If there is an autoref, then the result of this
10771079
// expression will be some sort of borrowed pointer.
10781080
expr_ct.cat.guarantor = None;

src/librustc/middle/typeck/infer/coercion.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ we may want to adjust precisely when coercions occur.
6565
*/
6666

6767

68-
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn};
68+
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn, AutoBorrowObj};
6969
use middle::ty::{AutoDerefRef};
7070
use middle::ty::{vstore_slice, vstore_box, vstore_uniq};
7171
use middle::ty::{mt};
@@ -121,6 +121,12 @@ impl Coerce {
121121
};
122122
}
123123

124+
ty::ty_trait(_, _, ty::RegionTraitStore(*), _, _) => {
125+
return do self.unpack_actual_value(a) |sty_a| {
126+
self.coerce_borrowed_object(a, sty_a, b)
127+
};
128+
}
129+
124130
ty::ty_ptr(mt_b) => {
125131
return do self.unpack_actual_value(a) |sty_a| {
126132
self.coerce_unsafe_ptr(a, sty_a, b, mt_b)
@@ -265,6 +271,40 @@ impl Coerce {
265271
})))
266272
}
267273

274+
fn coerce_borrowed_object(&self,
275+
a: ty::t,
276+
sty_a: &ty::sty,
277+
b: ty::t) -> CoerceResult
278+
{
279+
debug!("coerce_borrowed_object(a=%s, sty_a=%?, b=%s)",
280+
a.inf_str(self.infcx), sty_a,
281+
b.inf_str(self.infcx));
282+
283+
let tcx = self.infcx.tcx;
284+
let r_a = self.infcx.next_region_var(Coercion(self.trace));
285+
let trt_mut;
286+
287+
let a_borrowed = match *sty_a {
288+
ty::ty_trait(_, _, ty::RegionTraitStore(_), _, _) => {
289+
return self.subtype(a, b);
290+
}
291+
ty::ty_trait(did, ref substs, _, m, b) => {
292+
trt_mut = m;
293+
ty::mk_trait(tcx, did, substs.clone(),
294+
ty::RegionTraitStore(r_a), m, b)
295+
}
296+
_ => {
297+
return self.subtype(a, b);
298+
}
299+
};
300+
301+
if_ok!(self.tys(a_borrowed, b));
302+
Ok(Some(@AutoDerefRef(AutoDerefRef {
303+
autoderefs: 0,
304+
autoref: Some(AutoBorrowObj(r_a, trt_mut))
305+
})))
306+
}
307+
268308
pub fn coerce_borrowed_fn(&self,
269309
a: ty::t,
270310
sty_a: &ty::sty,

src/librustc/middle/typeck/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub enum method_origin {
8888
method_param(method_param),
8989

9090
// method invoked on a trait instance
91-
method_trait(ast::def_id, uint, ty::TraitStore),
91+
method_trait(ast::def_id, uint),
9292

9393
}
9494

src/librustc/util/ppaux.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,8 @@ impl Repr for typeck::method_origin {
747747
&typeck::method_param(ref p) => {
748748
p.repr(tcx)
749749
}
750-
&typeck::method_trait(def_id, n, st) => {
751-
fmt!("method_trait(%s, %?, %s)", def_id.repr(tcx), n,
752-
st.repr(tcx))
750+
&typeck::method_trait(def_id, n) => {
751+
fmt!("method_trait(%s, %?)", def_id.repr(tcx), n)
753752
}
754753
}
755754
}

0 commit comments

Comments
 (0)