@@ -193,24 +193,46 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
193193 datum = unpack_datum ! ( bcx, add_env( bcx, expr, datum) ) ;
194194 }
195195 AutoDerefRef ( ref adj) => {
196- // Extracting a value from a box counts as a deref, but if we are
197- // just converting Box<[T, ..n]> to Box<[T]> we aren't really doing
198- // a deref (and wouldn't if we could treat Box like a normal struct).
199- let autoderefs = match adj. autoref {
200- Some ( ty:: AutoUnsizeUniq ( ..) ) => adj. autoderefs - 1 ,
201- _ => adj. autoderefs
196+ let ( autoderefs, use_autoref) = match adj. autoref {
197+ // Extracting a value from a box counts as a deref, but if we are
198+ // just converting Box<[T, ..n]> to Box<[T]> we aren't really doing
199+ // a deref (and wouldn't if we could treat Box like a normal struct).
200+ Some ( ty:: AutoUnsizeUniq ( ..) ) => ( adj. autoderefs - 1 , true ) ,
201+ // We are a bit paranoid about adjustments and thus might have a re-
202+ // borrow here which merely derefs and then refs again (it might have
203+ // a different region or mutability, but we don't care here. It might
204+ // also be just in case we need to unsize. But if there are no nested
205+ // adjustments then it should be a no-op).
206+ Some ( ty:: AutoPtr ( _, _, None ) ) if adj. autoderefs == 1 => {
207+ match ty:: get ( datum. ty ) . sty {
208+ // Don't skip a conversion from Box<T> to &T, etc.
209+ ty:: ty_rptr( ..) => {
210+ let method_call = MethodCall :: autoderef ( expr. id , adj. autoderefs -1 ) ;
211+ let method = bcx. tcx ( ) . method_map . borrow ( ) . find ( & method_call) . is_some ( ) ;
212+ if method {
213+ // Don't skip an overloaded deref.
214+ ( adj. autoderefs , true )
215+ } else {
216+ ( adj. autoderefs - 1 , false )
217+ }
218+ }
219+ _ => ( adj. autoderefs , true ) ,
220+ }
221+ }
222+ _ => ( adj. autoderefs , true )
202223 } ;
203224
204225 if autoderefs > 0 {
205- let lval = unpack_datum ! ( bcx,
206- datum. to_lvalue_datum( bcx, "auto_deref" , expr. id) ) ;
207-
226+ // Schedule cleanup.
227+ let lval = unpack_datum ! ( bcx, datum. to_lvalue_datum( bcx, "auto_deref" , expr. id) ) ;
208228 datum = unpack_datum ! (
209229 bcx, deref_multiple( bcx, expr, lval. to_expr_datum( ) , autoderefs) ) ;
210230 }
211231
212- match adj. autoref {
213- Some ( ref a) => {
232+ // (You might think there is a more elegant way to do this than a
233+ // use_autoref bool, but then you remember that the borrow checker exists).
234+ match ( use_autoref, & adj. autoref ) {
235+ ( true , & Some ( ref a) ) => {
214236 datum = unpack_datum ! ( bcx, apply_autoref( a,
215237 bcx,
216238 expr,
@@ -221,7 +243,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
221243 }
222244 }
223245 debug ! ( "after adjustments, datum={}" , datum. to_string( bcx. ccx( ) ) ) ;
224- return DatumBlock { bcx : bcx, datum : datum } ;
246+ return DatumBlock :: new ( bcx, datum) ;
225247
226248 fn apply_autoref < ' a > ( autoref : & ty:: AutoRef ,
227249 bcx : & ' a Block < ' a > ,
0 commit comments