Skip to content

Commit 8ec3696

Browse files
committed
Made eddyb's suggested change
The adjusted type is now used instead in cases of autoderefs.
1 parent bf199d4 commit 8ec3696

File tree

1 file changed

+26
-65
lines changed

1 file changed

+26
-65
lines changed

src/librustc_typeck/check/writeback.rs

+26-65
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
// unresolved type variables and replaces "ty_var" types with their
1313
// substitutions.
1414

15-
use check::{FnCtxt, LvalueOp};
15+
use check::FnCtxt;
1616
use rustc::hir;
1717
use rustc::hir::def_id::{DefId, DefIndex};
1818
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
1919
use rustc::infer::InferCtxt;
20-
use rustc::ty::{self, LvaluePreference, Ty, TyCtxt};
20+
use rustc::ty::{self, Ty, TyCtxt};
2121
use rustc::ty::adjustment::{Adjust, Adjustment};
2222
use rustc::ty::fold::{TypeFoldable, TypeFolder};
2323
use rustc::util::nodemap::DefIdSet;
@@ -167,73 +167,34 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
167167
// usize-ish
168168
fn fix_index_builtin_expr(&mut self, e: &hir::Expr) {
169169
if let hir::ExprIndex(ref base, ref index) = e.node {
170-
let base_ty = self.fcx.node_ty(base.hir_id);
170+
let mut tables = self.fcx.tables.borrow_mut();
171+
172+
let base_ty = tables.expr_ty_adjusted(&base);
171173
let base_ty = self.fcx.resolve_type_vars_if_possible(&base_ty);
172-
let index_ty = self.fcx.node_ty(index.hir_id);
174+
let index_ty = tables.expr_ty_adjusted(&index);
173175
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
174176

175-
if index_ty.is_uint() {
176-
// HACK: the *actual* type being indexed is not stored anywhere
177-
// so we try to find it again here by derefs
178-
let mut autoderef = self.fcx.autoderef(e.span, base_ty);
179-
let builtin_ty : Option<_> = {
180-
loop {
181-
// This is essentially a duplicate of the index discovery
182-
// logic in typechecking code
183-
// Find the first type dereffable to which has builtin
184-
// indexing - this
185-
if let Some(_) = autoderef.next() {
186-
let current_ty = autoderef.unambiguous_final_ty();
187-
188-
if current_ty.builtin_index().is_some() {
189-
// If there is a builtin index, use it
190-
break Some(current_ty);
191-
} else {
192-
// If there's an overloaded index which happens
193-
// to take a uint, stop looking - otherwise we
194-
// might incorrectly deref further
195-
let overloaded_method =
196-
self.fcx.try_overloaded_lvalue_op(
197-
e.span,
198-
base_ty,
199-
&[index_ty],
200-
LvaluePreference::NoPreference,
201-
LvalueOp::Index
202-
);
203-
204-
if overloaded_method.is_some() {
205-
break None;
206-
}
207-
}
208-
} else {
209-
break None;
210-
}
177+
if base_ty.builtin_index().is_some() && index_ty.is_uint() {
178+
179+
// Remove the method call record, which blocks use in
180+
// constant or static cases
181+
tables.type_dependent_defs_mut().remove(e.hir_id);
182+
tables.node_substs_mut().remove(e.hir_id);
183+
184+
tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
185+
// Discard the need for a mutable borrow
186+
match a.pop() {
187+
// Extra adjustment made when indexing causes a drop
188+
// of size information - we need to get rid of it
189+
// Since this is "after" the other adjustment to be
190+
// discarded, we do an extra `pop()`
191+
Some(Adjustment { kind: Adjust::Unsize, .. }) => {
192+
// So the borrow discard actually happens here
193+
a.pop();
194+
},
195+
_ => {}
211196
}
212-
};
213-
214-
if builtin_ty.is_some() {
215-
let mut tables = self.fcx.tables.borrow_mut();
216-
217-
// Remove the method call record, which blocks use in
218-
// constant or static cases
219-
tables.type_dependent_defs_mut().remove(e.hir_id);
220-
tables.node_substs_mut().remove(e.hir_id);
221-
222-
tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
223-
// Discard the need for a mutable borrow
224-
match a.pop() {
225-
// Extra adjustment made when indexing causes a drop
226-
// of size information - we need to get rid of it
227-
// Since this is "after" the other adjustment to be
228-
// discarded, we do an extra `pop()`
229-
Some(Adjustment { kind: Adjust::Unsize, .. }) => {
230-
// So the borrow discard actually happens here
231-
a.pop();
232-
},
233-
_ => {}
234-
}
235-
});
236-
}
197+
});
237198
}
238199
}
239200
}

0 commit comments

Comments
 (0)