@@ -201,7 +201,13 @@ pub fn lookup_in_trait<'a>(
201
201
struct LookupContext < ' a > {
202
202
fcx : @FnCtxt ,
203
203
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".
204
209
self_expr : Option < & ' a ast:: Expr > ,
210
+
205
211
m_name : ast:: Name ,
206
212
supplied_tps : & ' a [ ty:: t ] ,
207
213
impl_dups : @RefCell < HashSet < DefId > > ,
@@ -243,51 +249,69 @@ impl<'a> LookupContext<'a> {
243
249
let span = self . self_expr . map_or ( self . span , |e| e. span ) ;
244
250
let self_expr_id = self . self_expr . map ( |e| e. id ) ;
245
251
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) ) ;
251
255
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
+ }
258
270
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 => { }
263
283
}
264
- check:: DoDerefArgs => {
265
- match self . search_for_autoptrd_method ( self_ty, autoderefs) {
266
- Some ( result) => return Some ( Some ( result) ) ,
267
- None => { }
268
- }
269
284
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 => { }
274
288
}
275
289
}
290
+ check:: DoDerefArgs => {
291
+ match self . search_for_autoptrd_method ( self_ty, autoderefs) {
292
+ Some ( result) => return Some ( Some ( result) ) ,
293
+ None => { }
294
+ }
276
295
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
+ }
282
300
}
283
- } ) ;
301
+ }
284
302
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
288
308
}
289
309
}
290
310
311
+ fn is_overloaded_deref ( & self ) -> bool {
312
+ self . self_expr . is_none ( )
313
+ }
314
+
291
315
// ______________________________________________________________________
292
316
// Candidate collection (see comment at start of file)
293
317
@@ -625,17 +649,13 @@ impl<'a> LookupContext<'a> {
625
649
let ( self_ty, auto_deref_ref) =
626
650
self . consider_reborrow ( self_ty, autoderefs) ;
627
651
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
639
659
} ;
640
660
641
661
match self . search_for_method ( self_ty) {
@@ -733,9 +753,9 @@ impl<'a> LookupContext<'a> {
733
753
autoderefs : uint )
734
754
-> Option < MethodCallee > {
735
755
/*!
736
- *
737
756
* Searches for a candidate by converting things like
738
- * `~[]` to `&[]`. */
757
+ * `~[]` to `&[]`.
758
+ */
739
759
740
760
let tcx = self . tcx ( ) ;
741
761
let sty = ty:: get ( self_ty) . sty . clone ( ) ;
@@ -843,15 +863,20 @@ impl<'a> LookupContext<'a> {
843
863
mutbls : & [ ast:: Mutability ] ,
844
864
mk_autoref_ty : |ast:: Mutability , ty:: Region | -> ty:: t)
845
865
-> 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.
848
870
let self_expr_id = match self . self_expr {
849
871
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
853
877
}
854
878
} ;
879
+
855
880
// This is hokey. We should have mutability inference as a
856
881
// variable. But for now, try &const, then &, then &mut:
857
882
let region =
@@ -1119,7 +1144,8 @@ impl<'a> LookupContext<'a> {
1119
1144
& self ,
1120
1145
trait_def_id : ast:: DefId ,
1121
1146
rcvr_substs : & ty:: substs ,
1122
- method_ty : & ty:: Method ) -> ty:: t {
1147
+ method_ty : & ty:: Method )
1148
+ -> ty:: t {
1123
1149
/*!
1124
1150
* This is a bit tricky. We have a match against a trait method
1125
1151
* being invoked on an object, and we want to generate the
0 commit comments