]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #36030 - Manishearth:rollup, r=Manishearth
authorbors <bors@rust-lang.org>
Sat, 27 Aug 2016 10:07:48 +0000 (03:07 -0700)
committerGitHub <noreply@github.com>
Sat, 27 Aug 2016 10:07:48 +0000 (03:07 -0700)
Rollup of 7 pull requests

- Successful merges: #35124, #35877, #35953, #36002, #36004, #36005, #36014
- Failed merges:

1  2 
src/librustc/mir/repr.rs
src/librustc/mir/visit.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_metadata/decoder.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_trans/collector.rs

diff --combined src/librustc/mir/repr.rs
index 5279d0526089639fe9f5e6202dbc0332db65f3f3,059fcfdca8a005fa81d33d01561dc30fd5a3ffdc..8145c0aae3f74cb344303a5084468f455897943c
@@@ -911,7 -911,7 +911,7 @@@ pub enum Rvalue<'tcx> 
      Repeat(Operand<'tcx>, TypedConstVal<'tcx>),
  
      /// &x or &mut x
-     Ref(Region, BorrowKind, Lvalue<'tcx>),
+     Ref(&'tcx Region, BorrowKind, Lvalue<'tcx>),
  
      /// length of a [X] or [X;n] value
      Len(Lvalue<'tcx>),
@@@ -1239,14 -1239,3 +1239,14 @@@ impl<'a, 'b>  GraphSuccessors<'b> for M
      type Item = BasicBlock;
      type Iter = IntoIter<BasicBlock>;
  }
 +
 +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)]
 +pub struct Location {
 +    /// the location is within this block
 +    pub block: BasicBlock,
 +
 +    /// the location is the start of the this statement; or, if `statement_index`
 +    /// == num-statements, then the start of the terminator.
 +    pub statement_index: usize,
 +}
 +
index 0a0872b5edafe3d452079e78cf14f142411cdf28,f608185157a4ec13b91b4c48b9cfd256fa1ee285..2771880735c27a71866ba304563c910d99fef0c0
@@@ -103,70 -103,60 +103,70 @@@ macro_rules! make_mir_visitor 
  
              fn visit_statement(&mut self,
                                 block: BasicBlock,
 -                               statement: & $($mutability)* Statement<'tcx>) {
 -                self.super_statement(block, statement);
 +                               statement: & $($mutability)* Statement<'tcx>,
 +                               location: Location) {
 +                self.super_statement(block, statement, location);
              }
  
              fn visit_assign(&mut self,
                              block: BasicBlock,
                              lvalue: & $($mutability)* Lvalue<'tcx>,
 -                            rvalue: & $($mutability)* Rvalue<'tcx>) {
 -                self.super_assign(block, lvalue, rvalue);
 +                            rvalue: & $($mutability)* Rvalue<'tcx>,
 +                            location: Location) {
 +                self.super_assign(block, lvalue, rvalue, location);
              }
  
              fn visit_terminator(&mut self,
                                  block: BasicBlock,
 -                                terminator: & $($mutability)* Terminator<'tcx>) {
 -                self.super_terminator(block, terminator);
 +                                terminator: & $($mutability)* Terminator<'tcx>,
 +                                location: Location) {
 +                self.super_terminator(block, terminator, location);
              }
  
              fn visit_terminator_kind(&mut self,
                                       block: BasicBlock,
 -                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
 -                self.super_terminator_kind(block, kind);
 +                                     kind: & $($mutability)* TerminatorKind<'tcx>,
 +                                     location: Location) {
 +                self.super_terminator_kind(block, kind, location);
              }
  
              fn visit_assert_message(&mut self,
 -                                    msg: & $($mutability)* AssertMessage<'tcx>) {
 -                self.super_assert_message(msg);
 +                                    msg: & $($mutability)* AssertMessage<'tcx>,
 +                                    location: Location) {
 +                self.super_assert_message(msg, location);
              }
  
              fn visit_rvalue(&mut self,
 -                            rvalue: & $($mutability)* Rvalue<'tcx>) {
 -                self.super_rvalue(rvalue);
 +                            rvalue: & $($mutability)* Rvalue<'tcx>,
 +                            location: Location) {
 +                self.super_rvalue(rvalue, location);
              }
  
              fn visit_operand(&mut self,
 -                             operand: & $($mutability)* Operand<'tcx>) {
 -                self.super_operand(operand);
 +                             operand: & $($mutability)* Operand<'tcx>,
 +                             location: Location) {
 +                self.super_operand(operand, location);
              }
  
              fn visit_lvalue(&mut self,
                              lvalue: & $($mutability)* Lvalue<'tcx>,
 -                            context: LvalueContext) {
 -                self.super_lvalue(lvalue, context);
 +                            context: LvalueContext,
 +                            location: Location) {
 +                self.super_lvalue(lvalue, context, location);
              }
  
              fn visit_projection(&mut self,
                                  lvalue: & $($mutability)* LvalueProjection<'tcx>,
 -                                context: LvalueContext) {
 -                self.super_projection(lvalue, context);
 +                                context: LvalueContext,
 +                                location: Location) {
 +                self.super_projection(lvalue, context, location);
              }
  
              fn visit_projection_elem(&mut self,
                                       lvalue: & $($mutability)* LvalueElem<'tcx>,
 -                                     context: LvalueContext) {
 -                self.super_projection_elem(lvalue, context);
 +                                     context: LvalueContext,
 +                                     location: Location) {
 +                self.super_projection_elem(lvalue, context, location);
              }
  
              fn visit_branch(&mut self,
              }
  
              fn visit_constant(&mut self,
 -                              constant: & $($mutability)* Constant<'tcx>) {
 -                self.super_constant(constant);
 +                              constant: & $($mutability)* Constant<'tcx>,
 +                              location: Location) {
 +                self.super_constant(constant, location);
              }
  
              fn visit_literal(&mut self,
 -                             literal: & $($mutability)* Literal<'tcx>) {
 -                self.super_literal(literal);
 +                             literal: & $($mutability)* Literal<'tcx>,
 +                             location: Location) {
 +                self.super_literal(literal, location);
              }
  
              fn visit_def_id(&mut self,
 -                            def_id: & $($mutability)* DefId) {
 +                            def_id: & $($mutability)* DefId,
 +                            _: Location) {
                  self.super_def_id(def_id);
              }
  
              }
  
              fn visit_const_val(&mut self,
 -                               const_val: & $($mutability)* ConstVal) {
 +                               const_val: & $($mutability)* ConstVal,
 +                               _: Location) {
                  self.super_const_val(const_val);
              }
  
              fn visit_const_usize(&mut self,
 -                                 const_usize: & $($mutability)* ConstUsize) {
 +                                 const_usize: & $($mutability)* ConstUsize,
 +                                 _: Location) {
                  self.super_const_usize(const_usize);
              }
  
              fn visit_typed_const_val(&mut self,
 -                                     val: & $($mutability)* TypedConstVal<'tcx>) {
 -                self.super_typed_const_val(val);
 +                                     val: & $($mutability)* TypedConstVal<'tcx>,
 +                                     location: Location) {
 +                self.super_typed_const_val(val, location);
              }
  
              fn visit_var_decl(&mut self,
                      is_cleanup: _
                  } = *data;
  
 +                let mut index = 0;
                  for statement in statements {
 -                    self.visit_statement(block, statement);
 +                    let location = Location { block: block, statement_index: index };
 +                    self.visit_statement(block, statement, location);
 +                    index += 1;
                  }
  
                  if let Some(ref $($mutability)* terminator) = *terminator {
 -                    self.visit_terminator(block, terminator);
 +                    let location = Location { block: block, statement_index: index };
 +                    self.visit_terminator(block, terminator, location);
                  }
              }
  
  
              fn super_statement(&mut self,
                                 block: BasicBlock,
 -                               statement: & $($mutability)* Statement<'tcx>) {
 +                               statement: & $($mutability)* Statement<'tcx>,
 +                               location: Location) {
                  let Statement {
                      ref $($mutability)* source_info,
                      ref $($mutability)* kind,
                  match *kind {
                      StatementKind::Assign(ref $($mutability)* lvalue,
                                            ref $($mutability)* rvalue) => {
 -                        self.visit_assign(block, lvalue, rvalue);
 +                        self.visit_assign(block, lvalue, rvalue, location);
                      }
                      StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
 -                        self.visit_lvalue(lvalue, LvalueContext::Store);
 +                        self.visit_lvalue(lvalue, LvalueContext::Store, location);
                      }
                      StatementKind::StorageLive(ref $($mutability)* lvalue) => {
 -                        self.visit_lvalue(lvalue, LvalueContext::StorageLive);
 +                        self.visit_lvalue(lvalue, LvalueContext::StorageLive, location);
                      }
                      StatementKind::StorageDead(ref $($mutability)* lvalue) => {
 -                        self.visit_lvalue(lvalue, LvalueContext::StorageDead);
 +                        self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
                      }
                  }
              }
              fn super_assign(&mut self,
                              _block: BasicBlock,
                              lvalue: &$($mutability)* Lvalue<'tcx>,
 -                            rvalue: &$($mutability)* Rvalue<'tcx>) {
 -                self.visit_lvalue(lvalue, LvalueContext::Store);
 -                self.visit_rvalue(rvalue);
 +                            rvalue: &$($mutability)* Rvalue<'tcx>,
 +                            location: Location) {
 +                self.visit_lvalue(lvalue, LvalueContext::Store, location);
 +                self.visit_rvalue(rvalue, location);
              }
  
              fn super_terminator(&mut self,
                                  block: BasicBlock,
 -                                terminator: &$($mutability)* Terminator<'tcx>) {
 +                                terminator: &$($mutability)* Terminator<'tcx>,
 +                                location: Location) {
                  let Terminator {
                      ref $($mutability)* source_info,
                      ref $($mutability)* kind,
                  } = *terminator;
  
                  self.visit_source_info(source_info);
 -                self.visit_terminator_kind(block, kind);
 +                self.visit_terminator_kind(block, kind, location);
              }
  
              fn super_terminator_kind(&mut self,
                                       block: BasicBlock,
 -                                     kind: & $($mutability)* TerminatorKind<'tcx>) {
 +                                     kind: & $($mutability)* TerminatorKind<'tcx>,
 +                                     source_location: Location) {
                  match *kind {
                      TerminatorKind::Goto { target } => {
                          self.visit_branch(block, target);
  
                      TerminatorKind::If { ref $($mutability)* cond,
                                           ref $($mutability)* targets } => {
 -                        self.visit_operand(cond);
 +                        self.visit_operand(cond, source_location);
                          for &target in targets.as_slice() {
                              self.visit_branch(block, target);
                          }
                      TerminatorKind::Switch { ref $($mutability)* discr,
                                               adt_def: _,
                                               ref targets } => {
 -                        self.visit_lvalue(discr, LvalueContext::Inspect);
 +                        self.visit_lvalue(discr, LvalueContext::Inspect, source_location);
                          for &target in targets {
                              self.visit_branch(block, target);
                          }
                                                  ref $($mutability)* switch_ty,
                                                  ref $($mutability)* values,
                                                  ref targets } => {
 -                        self.visit_lvalue(discr, LvalueContext::Inspect);
 +                        self.visit_lvalue(discr, LvalueContext::Inspect, source_location);
                          self.visit_ty(switch_ty);
                          for value in values {
 -                            self.visit_const_val(value);
 +                            self.visit_const_val(value, source_location);
                          }
                          for &target in targets {
                              self.visit_branch(block, target);
                      TerminatorKind::Drop { ref $($mutability)* location,
                                             target,
                                             unwind } => {
 -                        self.visit_lvalue(location, LvalueContext::Drop);
 +                        self.visit_lvalue(location, LvalueContext::Drop, source_location);
                          self.visit_branch(block, target);
                          unwind.map(|t| self.visit_branch(block, t));
                      }
                                                       ref $($mutability)* value,
                                                       target,
                                                       unwind } => {
 -                        self.visit_lvalue(location, LvalueContext::Drop);
 -                        self.visit_operand(value);
 +                        self.visit_lvalue(location, LvalueContext::Drop, source_location);
 +                        self.visit_operand(value, source_location);
                          self.visit_branch(block, target);
                          unwind.map(|t| self.visit_branch(block, t));
                      }
                                             ref $($mutability)* args,
                                             ref $($mutability)* destination,
                                             cleanup } => {
 -                        self.visit_operand(func);
 +                        self.visit_operand(func, source_location);
                          for arg in args {
 -                            self.visit_operand(arg);
 +                            self.visit_operand(arg, source_location);
                          }
                          if let Some((ref $($mutability)* destination, target)) = *destination {
 -                            self.visit_lvalue(destination, LvalueContext::Call);
 +                            self.visit_lvalue(destination, LvalueContext::Call, source_location);
                              self.visit_branch(block, target);
                          }
                          cleanup.map(|t| self.visit_branch(block, t));
                                               ref $($mutability)* msg,
                                               target,
                                               cleanup } => {
 -                        self.visit_operand(cond);
 -                        self.visit_assert_message(msg);
 +                        self.visit_operand(cond, source_location);
 +                        self.visit_assert_message(msg, source_location);
                          self.visit_branch(block, target);
                          cleanup.map(|t| self.visit_branch(block, t));
                      }
              }
  
              fn super_assert_message(&mut self,
 -                                    msg: & $($mutability)* AssertMessage<'tcx>) {
 +                                    msg: & $($mutability)* AssertMessage<'tcx>,
 +                                    location: Location) {
                  match *msg {
                      AssertMessage::BoundsCheck {
                          ref $($mutability)* len,
                          ref $($mutability)* index
                      } => {
 -                        self.visit_operand(len);
 -                        self.visit_operand(index);
 +                        self.visit_operand(len, location);
 +                        self.visit_operand(index, location);
                      }
                      AssertMessage::Math(_) => {}
                  }
              }
  
              fn super_rvalue(&mut self,
 -                            rvalue: & $($mutability)* Rvalue<'tcx>) {
 +                            rvalue: & $($mutability)* Rvalue<'tcx>,
 +                            location: Location) {
                  match *rvalue {
                      Rvalue::Use(ref $($mutability)* operand) => {
 -                        self.visit_operand(operand);
 +                        self.visit_operand(operand, location);
                      }
  
                      Rvalue::Repeat(ref $($mutability)* value,
                                     ref $($mutability)* typed_const_val) => {
 -                        self.visit_operand(value);
 -                        self.visit_typed_const_val(typed_const_val);
 +                        self.visit_operand(value, location);
 +                        self.visit_typed_const_val(typed_const_val, location);
                      }
  
                      Rvalue::Ref(r, bk, ref $($mutability)* path) => {
                          self.visit_lvalue(path, LvalueContext::Borrow {
                              region: r,
                              kind: bk
 -                        });
 +                        }, location);
                      }
  
                      Rvalue::Len(ref $($mutability)* path) => {
 -                        self.visit_lvalue(path, LvalueContext::Inspect);
 +                        self.visit_lvalue(path, LvalueContext::Inspect, location);
                      }
  
                      Rvalue::Cast(_cast_kind,
                                   ref $($mutability)* operand,
                                   ref $($mutability)* ty) => {
 -                        self.visit_operand(operand);
 +                        self.visit_operand(operand, location);
                          self.visit_ty(ty);
                      }
  
                      Rvalue::CheckedBinaryOp(_bin_op,
                                       ref $($mutability)* lhs,
                                       ref $($mutability)* rhs) => {
 -                        self.visit_operand(lhs);
 -                        self.visit_operand(rhs);
 +                        self.visit_operand(lhs, location);
 +                        self.visit_operand(rhs, location);
                      }
  
                      Rvalue::UnaryOp(_un_op, ref $($mutability)* op) => {
 -                        self.visit_operand(op);
 +                        self.visit_operand(op, location);
                      }
  
                      Rvalue::Box(ref $($mutability)* ty) => {
                              }
                              AggregateKind::Closure(ref $($mutability)* def_id,
                                                     ref $($mutability)* closure_substs) => {
 -                                self.visit_def_id(def_id);
 +                                self.visit_def_id(def_id, location);
                                  self.visit_closure_substs(closure_substs);
                              }
                          }
  
                          for operand in operands {
 -                            self.visit_operand(operand);
 +                            self.visit_operand(operand, location);
                          }
                      }
  
                                          ref $($mutability)* inputs,
                                          asm: _ } => {
                          for output in & $($mutability)* outputs[..] {
 -                            self.visit_lvalue(output, LvalueContext::Store);
 +                            self.visit_lvalue(output, LvalueContext::Store, location);
                          }
                          for input in & $($mutability)* inputs[..] {
 -                            self.visit_operand(input);
 +                            self.visit_operand(input, location);
                          }
                      }
                  }
              }
  
              fn super_operand(&mut self,
 -                             operand: & $($mutability)* Operand<'tcx>) {
 +                             operand: & $($mutability)* Operand<'tcx>,
 +                             location: Location) {
                  match *operand {
                      Operand::Consume(ref $($mutability)* lvalue) => {
 -                        self.visit_lvalue(lvalue, LvalueContext::Consume);
 +                        self.visit_lvalue(lvalue, LvalueContext::Consume, location);
                      }
                      Operand::Constant(ref $($mutability)* constant) => {
 -                        self.visit_constant(constant);
 +                        self.visit_constant(constant, location);
                      }
                  }
              }
  
              fn super_lvalue(&mut self,
                              lvalue: & $($mutability)* Lvalue<'tcx>,
 -                            context: LvalueContext) {
 +                            context: LvalueContext,
 +                            location: Location) {
                  match *lvalue {
                      Lvalue::Var(_) |
                      Lvalue::Temp(_) |
                      Lvalue::ReturnPointer => {
                      }
                      Lvalue::Static(ref $($mutability)* def_id) => {
 -                        self.visit_def_id(def_id);
 +                        self.visit_def_id(def_id, location);
                      }
                      Lvalue::Projection(ref $($mutability)* proj) => {
 -                        self.visit_projection(proj, context);
 +                        self.visit_projection(proj, context, location);
                      }
                  }
              }
  
              fn super_projection(&mut self,
                                  proj: & $($mutability)* LvalueProjection<'tcx>,
 -                                context: LvalueContext) {
 +                                context: LvalueContext,
 +                                location: Location) {
                  let Projection {
                      ref $($mutability)* base,
                      ref $($mutability)* elem,
                  } = *proj;
 -                self.visit_lvalue(base, LvalueContext::Projection);
 -                self.visit_projection_elem(elem, context);
 +                self.visit_lvalue(base, LvalueContext::Projection, location);
 +                self.visit_projection_elem(elem, context, location);
              }
  
              fn super_projection_elem(&mut self,
                                       proj: & $($mutability)* LvalueElem<'tcx>,
 -                                     _context: LvalueContext) {
 +                                     _context: LvalueContext,
 +                                     location: Location) {
                  match *proj {
                      ProjectionElem::Deref => {
                      }
                          self.visit_ty(ty);
                      }
                      ProjectionElem::Index(ref $($mutability)* operand) => {
 -                        self.visit_operand(operand);
 +                        self.visit_operand(operand, location);
                      }
                      ProjectionElem::ConstantIndex { offset: _,
                                                      min_length: _,
              }
  
              fn super_constant(&mut self,
 -                              constant: & $($mutability)* Constant<'tcx>) {
 +                              constant: & $($mutability)* Constant<'tcx>,
 +                              location: Location) {
                  let Constant {
                      ref $($mutability)* span,
                      ref $($mutability)* ty,
  
                  self.visit_span(span);
                  self.visit_ty(ty);
 -                self.visit_literal(literal);
 +                self.visit_literal(literal, location);
              }
  
              fn super_typed_const_val(&mut self,
 -                                     constant: & $($mutability)* TypedConstVal<'tcx>) {
 +                                     constant: & $($mutability)* TypedConstVal<'tcx>,
 +                                     location: Location) {
                  let TypedConstVal {
                      ref $($mutability)* span,
                      ref $($mutability)* ty,
  
                  self.visit_span(span);
                  self.visit_ty(ty);
 -                self.visit_const_usize(value);
 +                self.visit_const_usize(value, location);
              }
  
              fn super_literal(&mut self,
 -                             literal: & $($mutability)* Literal<'tcx>) {
 +                             literal: & $($mutability)* Literal<'tcx>,
 +                             location: Location) {
                  match *literal {
                      Literal::Item { ref $($mutability)* def_id,
                                      ref $($mutability)* substs } => {
 -                        self.visit_def_id(def_id);
 +                        self.visit_def_id(def_id, location);
                          self.visit_substs(substs);
                      }
                      Literal::Value { ref $($mutability)* value } => {
 -                        self.visit_const_val(value);
 +                        self.visit_const_val(value, location);
                      }
                      Literal::Promoted { index: _ } => {}
                  }
@@@ -757,7 -724,7 +757,7 @@@ make_mir_visitor!(Visitor,)
  make_mir_visitor!(MutVisitor,mut);
  
  #[derive(Copy, Clone, Debug)]
- pub enum LvalueContext {
+ pub enum LvalueContext<'tcx> {
      // Appears as LHS of an assignment
      Store,
  
      Inspect,
  
      // Being borrowed
-     Borrow { region: Region, kind: BorrowKind },
+     Borrow { region: &'tcx Region, kind: BorrowKind },
  
      // Being sliced -- this should be same as being borrowed, probably
      Slice { from_start: usize, from_end: usize },
index 57ec27aca9b04339f2e7771ed9292d0a0dfd4b41,3ff2fb8e2e527bc504e1aa6b5e8ca344ab6bc521..885bbe856c8fb441c9bfe14b864314afa08e3f16
@@@ -9,14 -9,14 +9,14 @@@
  // except according to those terms.
  
  use indexed_set::IdxSetBuf;
 -use super::gather_moves::{MoveData, MovePathIndex, MovePathContent, Location};
 +use super::gather_moves::{MoveData, MovePathIndex, MovePathContent};
  use super::dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
  use super::dataflow::{DataflowResults};
  use super::{drop_flag_effects_for_location, on_all_children_bits};
  use super::{DropFlagState, MoveDataParamEnv};
  use super::patch::MirPatch;
  use rustc::ty::{self, Ty, TyCtxt};
- use rustc::ty::subst::{Subst, Substs};
+ use rustc::ty::subst::{Kind, Subst, Substs};
  use rustc::mir::repr::*;
  use rustc::mir::transform::{Pass, MirPass, MirSource};
  use rustc::middle::const_val::ConstVal;
@@@ -26,6 -26,7 +26,7 @@@ use rustc_data_structures::indexed_vec:
  use syntax_pos::Span;
  
  use std::fmt;
+ use std::iter;
  use std::u32;
  
  pub struct ElaborateDrops;
@@@ -146,9 -147,9 +147,9 @@@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, '
              dead: self.flow_uninits.sets().on_entry_set_for(loc.block.index())
                  .to_owned(),
          };
 -        for stmt in 0..loc.index {
 +        for stmt in 0..loc.statement_index {
              data.apply_location(self.tcx, self.mir, self.env,
 -                                Location { block: loc.block, index: stmt });
 +                                Location { block: loc.block, statement_index: stmt });
          }
          data
      }
  
              let init_data = self.initialization_data_at(Location {
                  block: bb,
 -                index: data.statements.len()
 +                statement_index: data.statements.len()
              });
  
              let path = self.move_data().rev_lookup.find(location);
      fn elaborate_drops(&mut self)
      {
          for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
 -            let loc = Location { block: bb, index: data.statements.len() };
 +            let loc = Location { block: bb, statement_index: data.statements.len() };
              let terminator = data.terminator();
  
              let resume_block = self.patch.resume_block();
                  unwind: Some(unwind)
              }, bb);
              on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
 -                self.set_drop_flag(Location { block: target, index: 0 },
 +                self.set_drop_flag(Location { block: target, statement_index: 0 },
                                     child, DropFlagState::Present);
 -                self.set_drop_flag(Location { block: unwind, index: 0 },
 +                self.set_drop_flag(Location { block: unwind, statement_index: 0 },
                                     child, DropFlagState::Present);
              });
          }
          let drop_block = self.drop_block(c);
          if update_drop_flag {
              self.set_drop_flag(
 -                Location { block: drop_block, index: 0 },
 +                Location { block: drop_block, statement_index: 0 },
                  c.path,
                  DropFlagState::Absent
              );
          let unit_temp = Lvalue::Temp(self.patch.new_temp(tcx.mk_nil()));
          let free_func = tcx.lang_items.require(lang_items::BoxFreeFnLangItem)
              .unwrap_or_else(|e| tcx.sess.fatal(&e));
-         let substs = Substs::new(tcx, vec![ty], vec![]);
+         let substs = Substs::new(tcx, iter::once(Kind::from(ty)));
          let fty = tcx.lookup_item_type(free_func).ty.subst(tcx, substs);
  
          self.patch.new_block(BasicBlockData {
      }
  
      fn drop_flags_on_init(&mut self) {
 -        let loc = Location { block: START_BLOCK, index: 0 };
 +        let loc = Location { block: START_BLOCK, statement_index: 0 };
          let span = self.patch.source_info_for_location(self.mir, loc).span;
          let false_ = self.constant_bool(span, false);
          for flag in self.drop_flags.values() {
              } = data.terminator().kind {
                  assert!(!self.patch.is_patched(bb));
  
 -                let loc = Location { block: tgt, index: 0 };
 +                let loc = Location { block: tgt, statement_index: 0 };
                  let path = self.move_data().rev_lookup.find(lv);
                  on_all_children_bits(
                      self.tcx, self.mir, self.move_data(), path,
      }
  
      fn drop_flags_for_args(&mut self) {
 -        let loc = Location { block: START_BLOCK, index: 0 };
 +        let loc = Location { block: START_BLOCK, statement_index: 0 };
          super::drop_flag_effects_for_function_entry(
              self.tcx, self.mir, self.env, |path, ds| {
                  self.set_drop_flag(loc, path, ds);
                          }
                      }
                  }
 -                let loc = Location { block: bb, index: i };
 +                let loc = Location { block: bb, statement_index: i };
                  super::drop_flag_effects_for_location(
                      self.tcx, self.mir, self.env, loc, |path, ds| {
                          if ds == DropFlagState::Absent || allow_initializations {
              } = data.terminator().kind {
                  assert!(!self.patch.is_patched(bb));
  
 -                let loc = Location { block: bb, index: data.statements.len() };
 +                let loc = Location { block: bb, statement_index: data.statements.len() };
                  let path = self.move_data().rev_lookup.find(lv);
                  on_all_children_bits(
                      self.tcx, self.mir, self.move_data(), path,
index ccbc4de82fb6367a23cb43d045b954ae89c1a868,bbda089b1c2a8da13bddb647af1f1f8be237df47..afcd25a79c5a135169f6d002049864ef71e0fb40
@@@ -42,7 -42,6 +42,7 @@@ use rustc_const_math::ConstInt
  
  use rustc::mir;
  use rustc::mir::visit::MutVisitor;
 +use rustc::mir::repr::Location;
  
  use std::cell::Cell;
  use std::io;
@@@ -847,7 -846,7 +847,7 @@@ pub fn maybe_get_item_mir<'a, 'tcx>(cda
      impl<'v, 'cdata, 'codemap> mir::visit::MutVisitor<'v>
          for MirDefIdAndSpanTranslator<'cdata, 'codemap>
      {
 -        fn visit_def_id(&mut self, def_id: &mut DefId) {
 +        fn visit_def_id(&mut self, def_id: &mut DefId, _: Location) {
              *def_id = translate_def_id(self.crate_metadata, *def_id);
          }
  
      }
  }
  
- fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
+ fn get_explicit_self<'a, 'tcx>(item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                -> ty::ExplicitSelfCategory<'tcx> {
      fn get_mutability(ch: u8) -> hir::Mutability {
          match ch as char {
              'i' => hir::MutImmutable,
          // FIXME(#4846) expl. region
          '&' => {
              ty::ExplicitSelfCategory::ByReference(
-                 ty::ReEmpty,
+                 tcx.mk_region(ty::ReEmpty),
                  get_mutability(string.as_bytes()[1]))
          }
          _ => bug!("unknown self type code: `{}`", explicit_self_kind as char)
@@@ -906,16 -906,6 +907,6 @@@ pub fn get_trait_name(cdata: Cmd, id: D
      item_name(doc)
  }
  
- pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
-     let doc = cdata.lookup_item(id);
-     match item_sort(doc) {
-         Some('r') | Some('p') => {
-             get_explicit_self(doc) == ty::ExplicitSelfCategory::Static
-         }
-         _ => false
-     }
- }
  pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>)
                                          -> Option<ty::ImplOrTraitItem<'tcx>> {
      let item_doc = cdata.lookup_item(id);
                      "the type {:?} of the method {:?} is not a function?",
                      ity, name)
              };
-             let explicit_self = get_explicit_self(item_doc);
+             let explicit_self = get_explicit_self(item_doc, tcx);
  
              ty::MethodTraitItem(Rc::new(ty::Method::new(name,
                                                          generics,
@@@ -1001,7 -991,7 +992,7 @@@ pub fn get_trait_item_def_ids(cdata: Cm
      }).collect()
  }
  
- pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
+ pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec<ty::Variance> {
      let item_doc = cdata.lookup_item(id);
      let variance_doc = reader::get_doc(item_doc, tag_item_variances);
      let mut decoder = reader::Decoder::new(variance_doc);
index 840befe603eee2fe6dbd15c4095ef5b402df93e5,32c78ca4a5ad186e898adcbdbfa93318f6a357f8..9e076851bc37d9b6c900482283ecaf3cb6f6bcc2
@@@ -36,7 -36,8 +36,7 @@@ use syntax_pos::Span
  
  use std::collections::hash_map::Entry;
  use std::fmt;
 -
 -use build::Location;
 +use std::usize;
  
  use super::promote_consts::{self, Candidate, TempState};
  
@@@ -146,6 -147,7 +146,6 @@@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tc
      return_qualif: Option<Qualif>,
      qualif: Qualif,
      const_fn_arg_vars: BitVector,
 -    location: Location,
      temp_promotion_state: IndexVec<Temp, TempState>,
      promotion_candidates: Vec<Candidate>
  }
@@@ -176,6 -178,10 +176,6 @@@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx
              return_qualif: None,
              qualif: Qualif::empty(),
              const_fn_arg_vars: BitVector::new(mir.var_decls.len()),
 -            location: Location {
 -                block: START_BLOCK,
 -                statement_index: 0
 -            },
              temp_promotion_state: temps,
              promotion_candidates: vec![]
          }
      }
  
      /// Assign the current qualification to the given destination.
 -    fn assign(&mut self, dest: &Lvalue<'tcx>) {
 +    fn assign(&mut self, dest: &Lvalue<'tcx>, location: Location) {
          let qualif = self.qualif;
          let span = self.span;
          let store = |slot: &mut Option<Qualif>| {
              // This must be an explicit assignment.
              _ => {
                  // Catch more errors in the destination.
 -                self.visit_lvalue(dest, LvalueContext::Store);
 +                self.visit_lvalue(dest, LvalueContext::Store, location);
                  self.statement_like();
              }
          }
                      self.qualif = Qualif::NOT_CONST;
                      for index in 0..mir.var_decls.len() {
                          if !self.const_fn_arg_vars.contains(index) {
 -                            self.assign(&Lvalue::Var(Var::new(index)));
 +                            self.assign(&Lvalue::Var(Var::new(index)), Location {
 +                                block: bb,
 +                                statement_index: usize::MAX,
 +                            });
                          }
                      }
  
  /// For functions (constant or not), it also records
  /// candidates for promotion in promotion_candidates.
  impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 -    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext) {
 +    fn visit_lvalue(&mut self, lvalue: &Lvalue<'tcx>, context: LvalueContext, location: Location) {
          match *lvalue {
              Lvalue::Arg(_) => {
                  self.add(Qualif::FN_ARGUMENT);
              }
              Lvalue::Projection(ref proj) => {
                  self.nest(|this| {
 -                    this.super_lvalue(lvalue, context);
 +                    this.super_lvalue(lvalue, context, location);
                      match proj.elem {
                          ProjectionElem::Deref => {
                              if !this.try_consume() {
          }
      }
  
 -    fn visit_operand(&mut self, operand: &Operand<'tcx>) {
 +    fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
          match *operand {
              Operand::Consume(_) => {
                  self.nest(|this| {
 -                    this.super_operand(operand);
 +                    this.super_operand(operand, location);
                      this.try_consume();
                  });
              }
  
                  if let Literal::Item { def_id, substs } = constant.literal {
                      // Don't peek inside generic (associated) constants.
-                     if !substs.types.is_empty() {
+                     if substs.types().next().is_some() {
                          self.add_type(constant.ty);
                      } else {
                          let qualif = qualify_const_item_cached(self.tcx,
          }
      }
  
 -    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
 +    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
          // Recurse through operands and lvalues.
 -        self.super_rvalue(rvalue);
 +        self.super_rvalue(rvalue, location);
  
          match *rvalue {
              Rvalue::Use(_) |
                  }
  
                  // We might have a candidate for promotion.
 -                let candidate = Candidate::Ref(self.location);
 +                let candidate = Candidate::Ref(location);
                  if self.mode == Mode::Fn || self.mode == Mode::ConstFn {
                      if !self.qualif.intersects(Qualif::NEVER_PROMOTE) {
                          // We can only promote direct borrows of temps.
          }
      }
  
 -    fn visit_terminator_kind(&mut self, bb: BasicBlock, kind: &TerminatorKind<'tcx>) {
 +    fn visit_terminator_kind(&mut self,
 +                             bb: BasicBlock,
 +                             kind: &TerminatorKind<'tcx>,
 +                             location: Location) {
          if let TerminatorKind::Call { ref func, ref args, ref destination, .. } = *kind {
 -            self.visit_operand(func);
 +            self.visit_operand(func, location);
  
              let fn_ty = func.ty(self.mir, self.tcx);
              let (is_shuffle, is_const_fn) = match fn_ty.sty {
  
              for (i, arg) in args.iter().enumerate() {
                  self.nest(|this| {
 -                    this.visit_operand(arg);
 +                    this.visit_operand(arg, location);
                      if is_shuffle && i == 2 && this.mode == Mode::Fn {
                          let candidate = Candidate::ShuffleIndices(bb);
                          if !this.qualif.intersects(Qualif::NEVER_PROMOTE) {
                          self.deny_drop();
                      }
                  }
 -                self.assign(dest);
 +                self.assign(dest, location);
              }
          } else {
              // Qualify any operands inside other terminators.
 -            self.super_terminator_kind(bb, kind);
 +            self.super_terminator_kind(bb, kind, location);
          }
      }
  
 -    fn visit_assign(&mut self, _: BasicBlock, dest: &Lvalue<'tcx>, rvalue: &Rvalue<'tcx>) {
 -        self.visit_rvalue(rvalue);
 +    fn visit_assign(&mut self,
 +                    _: BasicBlock,
 +                    dest: &Lvalue<'tcx>,
 +                    rvalue: &Rvalue<'tcx>,
 +                    location: Location) {
 +        self.visit_rvalue(rvalue, location);
  
          // Check the allowed const fn argument forms.
          if let (Mode::ConstFn, &Lvalue::Var(index)) = (self.mode, dest) {
              }
          }
  
 -        self.assign(dest);
 +        self.assign(dest, location);
      }
  
      fn visit_source_info(&mut self, source_info: &SourceInfo) {
          self.span = source_info.span;
      }
  
 -    fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>) {
 -        assert_eq!(self.location.block, bb);
 +    fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, location: Location) {
          self.nest(|this| {
              this.visit_source_info(&statement.source_info);
              match statement.kind {
                  StatementKind::Assign(ref lvalue, ref rvalue) => {
 -                    this.visit_assign(bb, lvalue, rvalue);
 +                    this.visit_assign(bb, lvalue, rvalue, location);
                  }
                  StatementKind::SetDiscriminant { .. } |
                  StatementKind::StorageLive(_) |
                  StatementKind::StorageDead(_) => {}
              }
          });
 -        self.location.statement_index += 1;
 -    }
 -
 -    fn visit_terminator(&mut self, bb: BasicBlock, terminator: &Terminator<'tcx>) {
 -        assert_eq!(self.location.block, bb);
 -        self.nest(|this| this.super_terminator(bb, terminator));
      }
  
 -    fn visit_basic_block_data(&mut self, bb: BasicBlock, data: &BasicBlockData<'tcx>) {
 -        self.location.statement_index = 0;
 -        self.location.block = bb;
 -        self.super_basic_block_data(bb, data);
 +    fn visit_terminator(&mut self,
 +                        bb: BasicBlock,
 +                        terminator: &Terminator<'tcx>,
 +                        location: Location) {
 +        self.nest(|this| this.super_terminator(bb, terminator, location));
      }
  }
  
index c11e696302d345eb8b9ef4b081b3ce485ff5ada7,8dd76535cf811db899d663667380e20bffe4c6eb..ba979813aa1f071fe50df7f3d5f134f899a5ee31
@@@ -201,7 -201,6 +201,7 @@@ use rustc::ty::adjustment::CustomCoerce
  use rustc::mir::repr as mir;
  use rustc::mir::visit as mir_visit;
  use rustc::mir::visit::Visitor as MirVisitor;
 +use rustc::mir::repr::Location;
  
  use rustc_const_eval as const_eval;
  
@@@ -447,7 -446,7 +447,7 @@@ struct MirNeighborCollector<'a, 'tcx: '
  
  impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
  
 -    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>) {
 +    fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
          debug!("visiting rvalue {:?}", *rvalue);
  
          match *rvalue {
              _ => { /* not interesting */ }
          }
  
 -        self.super_rvalue(rvalue);
 +        self.super_rvalue(rvalue, location);
      }
  
      fn visit_lvalue(&mut self,
                      lvalue: &mir::Lvalue<'tcx>,
 -                    context: mir_visit::LvalueContext) {
 +                    context: mir_visit::LvalueContext,
 +                    location: Location) {
          debug!("visiting lvalue {:?}", *lvalue);
  
          if let mir_visit::LvalueContext::Drop = context {
              self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty)));
          }
  
 -        self.super_lvalue(lvalue, context);
 +        self.super_lvalue(lvalue, context, location);
      }
  
 -    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>) {
 +    fn visit_operand(&mut self, operand: &mir::Operand<'tcx>, location: Location) {
          debug!("visiting operand {:?}", *operand);
  
          let callee = match *operand {
              }
          }
  
 -        self.super_operand(operand);
 +        self.super_operand(operand, location);
  
          fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                def_id: DefId)
      // we would not register drop-glues.
      fn visit_terminator_kind(&mut self,
                               block: mir::BasicBlock,
 -                             kind: &mir::TerminatorKind<'tcx>) {
 +                             kind: &mir::TerminatorKind<'tcx>,
 +                             location: Location) {
          let tcx = self.scx.tcx();
          match *kind {
              mir::TerminatorKind::Call {
              _ => { /* Nothing to do. */ }
          }
  
 -        self.super_terminator_kind(block, kind);
 +        self.super_terminator_kind(block, kind, location);
  
          fn is_drop_in_place_intrinsic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                  def_id: DefId,
@@@ -756,7 -753,7 +756,7 @@@ fn find_drop_glue_neighbors<'a, 'tcx>(s
                                     .drop_trait()
                                     .unwrap();
  
-         let self_type_substs = Substs::new_trait(scx.tcx(), vec![], vec![], ty);
+         let self_type_substs = Substs::new_trait(scx.tcx(), ty, &[]);
  
          let trait_ref = ty::TraitRef {
              def_id: drop_trait_def_id,
@@@ -1238,7 -1235,7 +1238,7 @@@ fn create_trans_items_for_default_impls
                      // The substitutions we have are on the impl, so we grab
                      // the method type from the impl to substitute into.
                      let impl_substs = Substs::for_item(tcx, impl_def_id,
-                                                        |_, _| ty::ReErased,
+                                                        |_, _| tcx.mk_region(ty::ReErased),
                                                         |_, _| tcx.types.err);
                      let mth = meth::get_impl_method(tcx,
                                                      callee_substs,