Skip to content

Commit e9920b3

Browse files
committed
---
yaml --- r: 32636 b: refs/heads/dist-snap c: 527a6f6 h: refs/heads/master v: v3
1 parent 4a8d46d commit e9920b3

File tree

2 files changed

+77
-37
lines changed

2 files changed

+77
-37
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: 48496fc1b62a2b7724117746f352b6b330aa63fb
10+
refs/heads/dist-snap: 527a6f60f14c6f38b524cfd5119c670aa0f9bef9
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/rustc/middle/typeck/check/method.rs

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ candidates in the same way.
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
5151
auto-deref any longer. At that point, we will attempt an auto-ref.
52-
If THAT fails, method lookup fails altogether.
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`.
5356
5457
## Why two phases?
5558
@@ -513,63 +516,100 @@ impl LookupContext {
513516
}
514517
}
515518

516-
fn search_for_appr_autorefd_method(
519+
fn search_for_any_autorefd_method(
517520
&self,
518521
self_ty: ty::t,
519522
autoderefs: uint)
520523
-> Option<method_map_entry>
521524
{
525+
/*!
526+
*
527+
* Attempts both auto-slice and auto-ptr, as appropriate.
528+
*/
529+
522530
let tcx = self.tcx();
523531

524-
// Next, try auto-ref. The precise kind of auto-ref depends on
525-
// the fully deref'd receiver type. In particular, we must
526-
// treat dynamically sized types like `str`, `[]` or `fn`
527-
// differently than other types because they cannot be fully
528-
// deref'd, unlike say @T.
529-
match ty::get(self_ty).sty {
530-
ty_box(*) | ty_uniq(*) | ty_rptr(*) => {
531-
// we should be fully autoderef'd
532-
self.bug(fmt!("Receiver type %s should be fully \
533-
autoderef'd by this point",
534-
self.ty_to_str(self_ty)));
535-
}
532+
match self.search_for_autosliced_method(self_ty, autoderefs) {
533+
Some(mme) => { return mme; }
534+
None => {}
535+
}
536536

537-
ty_infer(IntVar(_)) | // FIXME(#3211)---should be resolved
538-
ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool |
539-
ty_int(*) | ty_uint(*) |
540-
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_rec(*) |
541-
ty_class(*) | ty_tup(*) => {
542-
return self.search_for_autorefd_method(
543-
AutoPtr, autoderefs, [m_const, m_imm, m_mutbl],
544-
|m,r| ty::mk_rptr(tcx, r, {ty:self_ty, mutbl:m}));
545-
}
537+
match self.search_for_autoptrd_method(self_ty, autoderefs) {
538+
Some(mme) => { return mme; }
539+
None => {}
540+
}
546541

547-
ty_trait(*) | ty_fn(*) => {
548-
// NDM---eventually these should be some variant of autoref
549-
return None;
550-
}
542+
return None;
543+
}
551544

552-
ty_estr(vstore_slice(_)) |
553-
ty_evec(_, vstore_slice(_)) => {
554-
return None;
555-
}
545+
fn search_for_autosliced_method(
546+
&self,
547+
self_ty: ty::t,
548+
autoderefs: uint)
549+
-> Option<method_map_entry>
550+
{
551+
/*!
552+
*
553+
* Searches for a candidate by converting things like
554+
* `~[]` to `&[]`. */
556555

556+
match ty::get(self_ty).sty {
557557
ty_evec(mt, vstore_box) |
558558
ty_evec(mt, vstore_uniq) |
559559
ty_evec(mt, vstore_fixed(_)) => {
560-
return self.search_for_autorefd_method(
560+
self.search_for_some_kind_of_autorefd_method(
561561
AutoSlice, autoderefs, [m_const, m_imm, m_mutbl],
562562
|m,r| ty::mk_evec(tcx,
563563
{ty:mt.ty, mutbl:m},
564-
vstore_slice(r)));
564+
vstore_slice(r)))
565565
}
566566

567567
ty_estr(vstore_box) |
568568
ty_estr(vstore_uniq) |
569569
ty_estr(vstore_fixed(_)) => {
570-
return self.search_for_autorefd_method(
570+
self.search_for_some_kind_of_autorefd_method(
571571
AutoSlice, autoderefs, [m_imm],
572-
|_m,r| ty::mk_estr(tcx, vstore_slice(r)));
572+
|_m,r| ty::mk_estr(tcx, vstore_slice(r)))
573+
}
574+
575+
ty_trait(*) | ty_fn(*) => {
576+
// NDM---eventually these should be some variant of autoref
577+
None
578+
}
579+
580+
_ => None
581+
}
582+
}
583+
584+
fn search_for_autoptrd_method(
585+
&self,
586+
self_ty: ty::t,
587+
autoderefs: uint)
588+
-> Option<method_map_entry>
589+
{
590+
/*!
591+
*
592+
* Converts any type `T` to `&M T` where `M` is an
593+
* appropriate mutability.
594+
*/
595+
596+
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+
604+
ty_infer(IntVar(_)) | // FIXME(#3211)---should be resolved
605+
ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool |
606+
ty_int(*) | ty_uint(*) |
607+
ty_float(*) | ty_enum(*) | ty_ptr(*) | ty_rec(*) |
608+
ty_class(*) | ty_tup(*) | ty_estr(*) | ty_evec(*) |
609+
ty_trait(*) | ty_fn(*) => {
610+
self.search_for_some_kind_of_autorefd_method(
611+
AutoPtr, autoderefs, [m_const, m_imm, m_mutbl],
612+
|m,r| ty::mk_rptr(tcx, r, {ty:self_ty, mutbl:m}))
573613
}
574614

575615
ty_opaque_closure_ptr(_) | ty_unboxed_vec(_) |
@@ -580,7 +620,7 @@ impl LookupContext {
580620
}
581621
}
582622

583-
fn search_for_autorefd_method(
623+
fn search_for_some_kind_of_autorefd_method(
584624
&self,
585625
kind: AutoRefKind,
586626
autoderefs: uint,

0 commit comments

Comments
 (0)