diff options
| author | Isaac van Bakel <ivb@vanbakel.io> | 2018-01-01 23:36:49 +0000 |
|---|---|---|
| committer | Isaac van Bakel <ivb@vanbakel.io> | 2018-01-07 01:30:21 +0000 |
| commit | 8ec3696b37ef6508650f6df727f6d92b7bef06c4 (patch) | |
| tree | 423a13324eb2762806fb86ac5acff22a87f5ff9f | |
| parent | bf199d49652df2561459f39ff4f6f9ea02989999 (diff) | |
| download | rust-8ec3696b37ef6508650f6df727f6d92b7bef06c4.tar.gz rust-8ec3696b37ef6508650f6df727f6d92b7bef06c4.zip | |
Made eddyb's suggested change
The adjusted type is now used instead in cases of autoderefs.
| -rw-r--r-- | src/librustc_typeck/check/writeback.rs | 91 |
1 files changed, 26 insertions, 65 deletions
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 7f966cae249..93f9590a83e 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -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; @@ -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(); - }, - _ => {} - } - }); - } + }); } } } |
