@@ -49,7 +49,10 @@ candidates in the same way.
49
49
If find no matching candidate at all, we proceed to auto-deref the
50
50
receiver type and search again. We keep doing that until we cannot
51
51
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`.
53
56
54
57
## Why two phases?
55
58
@@ -513,63 +516,100 @@ impl LookupContext {
513
516
}
514
517
}
515
518
516
- fn search_for_appr_autorefd_method (
519
+ fn search_for_any_autorefd_method (
517
520
& self ,
518
521
self_ty : ty:: t ,
519
522
autoderefs : uint )
520
523
-> Option < method_map_entry >
521
524
{
525
+ /*!
526
+ *
527
+ * Attempts both auto-slice and auto-ptr, as appropriate.
528
+ */
529
+
522
530
let tcx = self . tcx ( ) ;
523
531
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
+ }
536
536
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
+ }
546
541
547
- ty_trait( * ) | ty_fn( * ) => {
548
- // NDM---eventually these should be some variant of autoref
549
- return None ;
550
- }
542
+ return None ;
543
+ }
551
544
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 `&[]`. */
556
555
556
+ match ty:: get ( self_ty) . sty {
557
557
ty_evec( mt, vstore_box) |
558
558
ty_evec( mt, vstore_uniq) |
559
559
ty_evec( mt, vstore_fixed( _) ) => {
560
- return self . search_for_autorefd_method (
560
+ self . search_for_some_kind_of_autorefd_method (
561
561
AutoSlice , autoderefs, [ m_const, m_imm, m_mutbl] ,
562
562
|m, r| ty:: mk_evec ( tcx,
563
563
{ ty: mt. ty , mutbl: m} ,
564
- vstore_slice ( r) ) ) ;
564
+ vstore_slice ( r) ) )
565
565
}
566
566
567
567
ty_estr( vstore_box) |
568
568
ty_estr( vstore_uniq) |
569
569
ty_estr( vstore_fixed( _) ) => {
570
- return self . search_for_autorefd_method (
570
+ self . search_for_some_kind_of_autorefd_method (
571
571
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} ) )
573
613
}
574
614
575
615
ty_opaque_closure_ptr( _) | ty_unboxed_vec( _) |
@@ -580,7 +620,7 @@ impl LookupContext {
580
620
}
581
621
}
582
622
583
- fn search_for_autorefd_method (
623
+ fn search_for_some_kind_of_autorefd_method (
584
624
& self ,
585
625
kind : AutoRefKind ,
586
626
autoderefs : uint ,
0 commit comments