Skip to content

Commit

Permalink
Made eddyb's suggested change
Browse files Browse the repository at this point in the history
The adjusted type is now used instead in cases of autoderefs.
  • Loading branch information
ivanbakel committed Jan 7, 2018
1 parent bf199d4 commit 8ec3696
Showing 1 changed file with 26 additions and 65 deletions.
91 changes: 26 additions & 65 deletions src/librustc_typeck/check/writeback.rs
Expand Up @@ -12,12 +12,12 @@
// unresolved type variables and replaces "ty_var" types with their
// substitutions.

use check::{FnCtxt, LvalueOp};
use check::FnCtxt;
use rustc::hir;
use rustc::hir::def_id::{DefId, DefIndex};
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::infer::InferCtxt;
use rustc::ty::{self, LvaluePreference, Ty, TyCtxt};
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::adjustment::{Adjust, Adjustment};
use rustc::ty::fold::{TypeFoldable, TypeFolder};
use rustc::util::nodemap::DefIdSet;
Expand Down Expand Up @@ -167,73 +167,34 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
// usize-ish
fn fix_index_builtin_expr(&mut self, e: &hir::Expr) {
if let hir::ExprIndex(ref base, ref index) = e.node {
let base_ty = self.fcx.node_ty(base.hir_id);
let mut tables = self.fcx.tables.borrow_mut();

let base_ty = tables.expr_ty_adjusted(&base);
let base_ty = self.fcx.resolve_type_vars_if_possible(&base_ty);
let index_ty = self.fcx.node_ty(index.hir_id);
let index_ty = tables.expr_ty_adjusted(&index);
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);

if index_ty.is_uint() {
// HACK: the *actual* type being indexed is not stored anywhere
// so we try to find it again here by derefs
let mut autoderef = self.fcx.autoderef(e.span, base_ty);
let builtin_ty : Option<_> = {
loop {
// This is essentially a duplicate of the index discovery
// logic in typechecking code
// Find the first type dereffable to which has builtin
// indexing - this
if let Some(_) = autoderef.next() {
let current_ty = autoderef.unambiguous_final_ty();

if current_ty.builtin_index().is_some() {
// If there is a builtin index, use it
break Some(current_ty);
} else {
// If there's an overloaded index which happens
// to take a uint, stop looking - otherwise we
// might incorrectly deref further
let overloaded_method =
self.fcx.try_overloaded_lvalue_op(
e.span,
base_ty,
&[index_ty],
LvaluePreference::NoPreference,
LvalueOp::Index
);

if overloaded_method.is_some() {
break None;
}
}
} else {
break None;
}
if base_ty.builtin_index().is_some() && index_ty.is_uint() {

// Remove the method call record, which blocks use in
// constant or static cases
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);

tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
// Discard the need for a mutable borrow
match a.pop() {
// Extra adjustment made when indexing causes a drop
// of size information - we need to get rid of it
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
Some(Adjustment { kind: Adjust::Unsize, .. }) => {
// So the borrow discard actually happens here
a.pop();
},
_ => {}
}
};

if builtin_ty.is_some() {
let mut tables = self.fcx.tables.borrow_mut();

// Remove the method call record, which blocks use in
// constant or static cases
tables.type_dependent_defs_mut().remove(e.hir_id);
tables.node_substs_mut().remove(e.hir_id);

tables.adjustments_mut().get_mut(base.hir_id).map(|a| {
// Discard the need for a mutable borrow
match a.pop() {
// Extra adjustment made when indexing causes a drop
// of size information - we need to get rid of it
// Since this is "after" the other adjustment to be
// discarded, we do an extra `pop()`
Some(Adjustment { kind: Adjust::Unsize, .. }) => {
// So the borrow discard actually happens here
a.pop();
},
_ => {}
}
});
}
});
}
}
}
Expand Down

0 comments on commit 8ec3696

Please sign in to comment.