Skip to content

Commit 12a0401

Browse files
committed
Change method res to try autoref more often. Fixes #3585.
1 parent a770d86 commit 12a0401

File tree

3 files changed

+48
-53
lines changed

3 files changed

+48
-53
lines changed

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

+11-53
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,12 @@ candidates in the same way.
4848
4949
If find no matching candidate at all, we proceed to auto-deref the
5050
receiver type and search again. We keep doing that until we cannot
51-
auto-deref any longer. At that point, we will attempt an auto-ref.
52-
If THAT fails, method lookup fails altogether. Autoref itself comes
53-
in two varieties, autoslice and autoptr. The former converts `~[]` to
54-
`&[]` and the latter converts any type `T` to `&mut T`, `&const T`, or
55-
`&T`.
51+
auto-deref any longer. At each step, we also check for candidates
52+
based on "autoptr", which if the current type is `T`, checks for `&mut
53+
T`, `&const T`, and `&T` receivers. Finally, at the very end, we will
54+
also try autoslice, which converts `~[]` to `&[]` (there is no point
55+
at trying autoslice earlier, because no autoderefable type is also
56+
sliceable).
5657
5758
## Why two phases?
5859
@@ -159,22 +160,9 @@ impl LookupContext {
159160
None => {}
160161
}
161162

162-
// some special logic around newtypes:
163-
match ty::get(self_ty).sty {
164-
ty_enum(*) => {
165-
// Note: in general, we prefer not to auto-ref a
166-
// partially autoderef'd type, because it
167-
// seems... crazy. But we have to be careful
168-
// around newtype enums. They can be further
169-
// deref'd, but they may also have intrinsic
170-
// methods hanging off of them with interior type.
171-
match self.search_for_any_autorefd_method(self_ty,
172-
autoderefs) {
173-
Some(move mme) => { return Some(mme); }
174-
None => {}
175-
}
176-
}
177-
_ => {}
163+
match self.search_for_autoptrd_method(self_ty, autoderefs) {
164+
Some(move mme) => { return Some(move mme); }
165+
None => {}
178166
}
179167

180168
match self.deref(self_ty, &enum_dids) {
@@ -186,7 +174,7 @@ impl LookupContext {
186174
}
187175
}
188176

189-
self.search_for_any_autorefd_method(self_ty, autoderefs)
177+
self.search_for_autosliced_method(self_ty, autoderefs)
190178
}
191179

192180
fn deref(ty: ty::t, enum_dids: &DVec<ast::def_id>) -> Option<ty::t> {
@@ -516,30 +504,6 @@ impl LookupContext {
516504
}
517505
}
518506

519-
fn search_for_any_autorefd_method(
520-
&self,
521-
self_ty: ty::t,
522-
autoderefs: uint)
523-
-> Option<method_map_entry>
524-
{
525-
/*!
526-
*
527-
* Attempts both auto-slice and auto-ptr, as appropriate.
528-
*/
529-
530-
match self.search_for_autosliced_method(self_ty, autoderefs) {
531-
Some(move mme) => { return Some(move mme); }
532-
None => {}
533-
}
534-
535-
match self.search_for_autoptrd_method(self_ty, autoderefs) {
536-
Some(move mme) => { return Some(move mme); }
537-
None => {}
538-
}
539-
540-
return None;
541-
}
542-
543507
fn search_for_autosliced_method(
544508
&self,
545509
self_ty: ty::t,
@@ -594,13 +558,7 @@ impl LookupContext {
594558

595559
let tcx = self.tcx();
596560
match ty::get(self_ty).sty {
597-
ty_box(*) | ty_uniq(*) | ty_rptr(*) => {
598-
// we should be fully autoderef'd
599-
self.bug(fmt!("Receiver type %s should be fully \
600-
autoderef'd by this point",
601-
self.ty_to_str(self_ty)));
602-
}
603-
561+
ty_box(*) | ty_uniq(*) | ty_rptr(*) |
604562
ty_infer(IntVar(_)) | // FIXME(#3211)---should be resolved
605563
ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool |
606564
ty_int(*) | ty_uint(*) |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
trait Foo {
2+
fn foo(&self) -> ~str;
3+
}
4+
5+
impl<T: Foo> @T: Foo {
6+
fn foo(&self) -> ~str {
7+
fmt!("@%s", (**self).foo())
8+
}
9+
}
10+
11+
impl uint: Foo {
12+
fn foo(&self) -> ~str {
13+
fmt!("%u", *self)
14+
}
15+
}
16+
17+
fn main() {
18+
let x = @3u;
19+
assert x.foo() == ~"@3";
20+
}

src/test/run-pass/autoref-vec-push.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait VecPush<T> {
2+
fn push(&mut self, +t: T);
3+
}
4+
5+
impl<T> ~[T]: VecPush<T> {
6+
fn push(&mut self, +t: T) {
7+
vec::push(*self, t);
8+
}
9+
}
10+
11+
fn main() {
12+
let mut x = ~[];
13+
x.push(1);
14+
x.push(2);
15+
x.push(3);
16+
assert x == ~[1, 2, 3];
17+
}

0 commit comments

Comments
 (0)