Skip to content

Commit f55b0e2

Browse files
committed
---
yaml --- r: 133044 b: refs/heads/dist-snap c: 08364a4 h: refs/heads/master v: v3
1 parent 042e026 commit f55b0e2

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
@@ -6,7 +6,7 @@ refs/heads/try: 457a3c991d79b971be07fce75f9d0c12848fb37c
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 52ef46251ede1ff51e5d5621d5fe2614e950f963
9+
refs/heads/dist-snap: 08364a4cacdcd6f161e0fb0ab573ae825e22447b
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/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)