Skip to content

Commit 83d4ba7

Browse files
committed
---
yaml --- r: 129548 b: refs/heads/snap-stage3 c: 08364a4 h: refs/heads/master v: v3
1 parent bfcd5b9 commit 83d4ba7

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 566b470e138e929e8a93d613372db1ba177c494f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 52ef46251ede1ff51e5d5621d5fe2614e950f963
4+
refs/heads/snap-stage3: 08364a4cacdcd6f161e0fb0ab573ae825e22447b
55
refs/heads/try: 80b45ddbd351f0a4a939c3a3c4e20b4defec4b35
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/trans/expr.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)