@@ -193,24 +193,46 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
193
193
datum = unpack_datum ! ( bcx, add_env( bcx, expr, datum) ) ;
194
194
}
195
195
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 )
202
223
} ;
203
224
204
225
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) ) ;
208
228
datum = unpack_datum ! (
209
229
bcx, deref_multiple( bcx, expr, lval. to_expr_datum( ) , autoderefs) ) ;
210
230
}
211
231
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) ) => {
214
236
datum = unpack_datum ! ( bcx, apply_autoref( a,
215
237
bcx,
216
238
expr,
@@ -221,7 +243,7 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
221
243
}
222
244
}
223
245
debug ! ( "after adjustments, datum={}" , datum. to_string( bcx. ccx( ) ) ) ;
224
- return DatumBlock { bcx : bcx, datum : datum } ;
246
+ return DatumBlock :: new ( bcx, datum) ;
225
247
226
248
fn apply_autoref < ' a > ( autoref : & ty:: AutoRef ,
227
249
bcx : & ' a Block < ' a > ,
0 commit comments