@@ -201,7 +201,13 @@ pub fn lookup_in_trait<'a>(
201201struct LookupContext < ' a > {
202202 fcx : @FnCtxt ,
203203 span : Span ,
204+
205+ // The receiver to the method call. Only `None` in the case of
206+ // an overloaded autoderef, where the receiver may be an intermediate
207+ // state like "the expression `x` when it has been autoderef'd
208+ // twice already".
204209 self_expr : Option < & ' a ast:: Expr > ,
210+
205211 m_name : ast:: Name ,
206212 supplied_tps : & ' a [ ty:: t ] ,
207213 impl_dups : @RefCell < HashSet < DefId > > ,
@@ -243,51 +249,69 @@ impl<'a> LookupContext<'a> {
243249 let span = self . self_expr . map_or ( self . span , |e| e. span ) ;
244250 let self_expr_id = self . self_expr . map ( |e| e. id ) ;
245251 let ( self_ty, autoderefs, result) =
246- check:: autoderef ( self . fcx , span, self_ty, self_expr_id,
247- PreferMutLvalue , |self_ty, autoderefs| {
248-
249- debug ! ( "loop: self_ty={} autoderefs={}" ,
250- self . ty_to_str( self_ty) , autoderefs) ;
252+ check:: autoderef (
253+ self . fcx , span, self_ty, self_expr_id, PreferMutLvalue ,
254+ |self_ty, autoderefs| self . search_step ( self_ty, autoderefs) ) ;
251255
252- match self . deref_args {
253- check:: DontDerefArgs => {
254- match self . search_for_autoderefd_method ( self_ty, autoderefs) {
255- Some ( result) => return Some ( Some ( result) ) ,
256- None => { }
257- }
256+ match result {
257+ Some ( Some ( result) ) => Some ( result) ,
258+ _ => {
259+ if self . is_overloaded_deref ( ) {
260+ // If we are searching for an overloaded deref, no
261+ // need to try coercing a `~[T]` to an `&[T]` and
262+ // searching for an overloaded deref on *that*.
263+ None
264+ } else {
265+ self . search_for_autosliced_method ( self_ty, autoderefs)
266+ }
267+ }
268+ }
269+ }
258270
259- match self . search_for_autoptrd_method ( self_ty, autoderefs) {
260- Some ( result) => return Some ( Some ( result) ) ,
261- None => { }
262- }
271+ fn search_step ( & self ,
272+ self_ty : ty:: t ,
273+ autoderefs : uint )
274+ -> Option < Option < MethodCallee > > {
275+ debug ! ( "search_step: self_ty={} autoderefs={}" ,
276+ self . ty_to_str( self_ty) , autoderefs) ;
277+
278+ match self . deref_args {
279+ check:: DontDerefArgs => {
280+ match self . search_for_autoderefd_method ( self_ty, autoderefs) {
281+ Some ( result) => return Some ( Some ( result) ) ,
282+ None => { }
263283 }
264- check:: DoDerefArgs => {
265- match self . search_for_autoptrd_method ( self_ty, autoderefs) {
266- Some ( result) => return Some ( Some ( result) ) ,
267- None => { }
268- }
269284
270- match self . search_for_autoderefd_method ( self_ty, autoderefs) {
271- Some ( result) => return Some ( Some ( result) ) ,
272- None => { }
273- }
285+ match self . search_for_autoptrd_method ( self_ty, autoderefs) {
286+ Some ( result) => return Some ( Some ( result) ) ,
287+ None => { }
274288 }
275289 }
290+ check:: DoDerefArgs => {
291+ match self . search_for_autoptrd_method ( self_ty, autoderefs) {
292+ Some ( result) => return Some ( Some ( result) ) ,
293+ None => { }
294+ }
276295
277- // Don't autoderef if we aren't supposed to.
278- if self . autoderef_receiver == DontAutoderefReceiver {
279- Some ( None )
280- } else {
281- None
296+ match self . search_for_autoderefd_method ( self_ty, autoderefs) {
297+ Some ( result) => return Some ( Some ( result) ) ,
298+ None => { }
299+ }
282300 }
283- } ) ;
301+ }
284302
285- match result {
286- Some ( Some ( result) ) => Some ( result) ,
287- _ => self . search_for_autosliced_method ( self_ty, autoderefs)
303+ // Don't autoderef if we aren't supposed to.
304+ if self . autoderef_receiver == DontAutoderefReceiver {
305+ Some ( None )
306+ } else {
307+ None
288308 }
289309 }
290310
311+ fn is_overloaded_deref ( & self ) -> bool {
312+ self . self_expr . is_none ( )
313+ }
314+
291315 // ______________________________________________________________________
292316 // Candidate collection (see comment at start of file)
293317
@@ -625,17 +649,13 @@ impl<'a> LookupContext<'a> {
625649 let ( self_ty, auto_deref_ref) =
626650 self . consider_reborrow ( self_ty, autoderefs) ;
627651
628- // HACK(eddyb) only overloaded auto-deref calls should be missing
629- // adjustments, because we imply an AutoPtr adjustment for them.
630- let adjustment = match auto_deref_ref {
631- ty:: AutoDerefRef {
632- autoderefs : 0 ,
633- autoref : Some ( ty:: AutoPtr ( ..) )
634- } => None ,
635- _ => match self . self_expr {
636- Some ( expr) => Some ( ( expr. id , @ty:: AutoDerefRef ( auto_deref_ref) ) ) ,
637- None => return None
638- }
652+ // Hacky. For overloaded derefs, there may be an adjustment
653+ // added to the expression from the outside context, so we do not store
654+ // an explicit adjustment, but rather we hardwire the single deref
655+ // that occurs in trans and mem_categorization.
656+ let adjustment = match self . self_expr {
657+ Some ( expr) => Some ( ( expr. id , @ty:: AutoDerefRef ( auto_deref_ref) ) ) ,
658+ None => return None
639659 } ;
640660
641661 match self . search_for_method ( self_ty) {
@@ -733,9 +753,9 @@ impl<'a> LookupContext<'a> {
733753 autoderefs : uint )
734754 -> Option < MethodCallee > {
735755 /*!
736- *
737756 * Searches for a candidate by converting things like
738- * `~[]` to `&[]`. */
757+ * `~[]` to `&[]`.
758+ */
739759
740760 let tcx = self . tcx ( ) ;
741761 let sty = ty:: get ( self_ty) . sty . clone ( ) ;
@@ -843,15 +863,20 @@ impl<'a> LookupContext<'a> {
843863 mutbls : & [ ast:: Mutability ] ,
844864 mk_autoref_ty : |ast:: Mutability , ty:: Region | -> ty:: t)
845865 -> Option < MethodCallee > {
846- // HACK(eddyb) only overloaded auto-deref calls should be missing
847- // adjustments, because we imply an AutoPtr adjustment for them.
866+ // Hacky. For overloaded derefs, there may be an adjustment
867+ // added to the expression from the outside context, so we do not store
868+ // an explicit adjustment, but rather we hardwire the single deref
869+ // that occurs in trans and mem_categorization.
848870 let self_expr_id = match self . self_expr {
849871 Some ( expr) => Some ( expr. id ) ,
850- None => match kind ( ty:: ReEmpty , ast:: MutImmutable ) {
851- ty:: AutoPtr ( ..) if autoderefs == 0 => None ,
852- _ => return None
872+ None => {
873+ assert_eq ! ( autoderefs, 0 ) ;
874+ assert_eq ! ( kind( ty:: ReEmpty , ast:: MutImmutable ) ,
875+ ty:: AutoPtr ( ty:: ReEmpty , ast:: MutImmutable ) ) ;
876+ None
853877 }
854878 } ;
879+
855880 // This is hokey. We should have mutability inference as a
856881 // variable. But for now, try &const, then &, then &mut:
857882 let region =
@@ -1119,7 +1144,8 @@ impl<'a> LookupContext<'a> {
11191144 & self ,
11201145 trait_def_id : ast:: DefId ,
11211146 rcvr_substs : & ty:: substs ,
1122- method_ty : & ty:: Method ) -> ty:: t {
1147+ method_ty : & ty:: Method )
1148+ -> ty:: t {
11231149 /*!
11241150 * This is a bit tricky. We have a match against a trait method
11251151 * being invoked on an object, and we want to generate the
0 commit comments