diff options
| author | Paul Faria <Nashenas88@gmail.com> | 2017-07-17 22:26:21 -0400 |
|---|---|---|
| committer | Paul Faria <Nashenas88@gmail.com> | 2017-07-30 12:09:35 -0400 |
| commit | d2fc06e7f6068f3e30a21099f4cf4a2e423e9159 (patch) | |
| tree | 08e079ebb88d93400ed0fd1e30841a96b1c9409f | |
| parent | 5c71e4ef90ef79c1ac79c4132333cbc80f5b85b9 (diff) | |
| download | rust-d2fc06e7f6068f3e30a21099f4cf4a2e423e9159.tar.gz rust-d2fc06e7f6068f3e30a21099f4cf4a2e423e9159.zip | |
Renumber regions as the first step of the non-lexical lifetimes inference
| -rw-r--r-- | src/librustc_mir/transform/nll.rs | 94 |
1 files changed, 82 insertions, 12 deletions
diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll.rs index 3273b4ff347..65294e9ef24 100644 --- a/src/librustc_mir/transform/nll.rs +++ b/src/librustc_mir/transform/nll.rs @@ -8,26 +8,90 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::ty::TyCtxt; -use rustc::mir::Mir; +use rustc::ty::TypeFoldable; +use rustc::ty::subst::Substs; +use rustc::ty::{Ty, TyCtxt, ClosureSubsts}; +use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::mir::transform::{MirPass, MirSource}; +use rustc::infer::{self, InferCtxt}; +use syntax_pos::Span; #[allow(dead_code)] -struct NLLVisitor<'a, 'tcx: 'a> { - tcx: TyCtxt<'a, 'tcx, 'tcx>, +struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + infcx: InferCtxt<'a, 'gcx, 'tcx>, + source: Mir<'tcx> } -impl<'a, 'tcx> NLLVisitor<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self { +impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> { + pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: Mir<'tcx>) -> Self { NLLVisitor { - tcx: tcx + infcx: infcx, + source: source, } } + + fn renumber_regions<T>(&self, value: &T, span: Span) -> T where T: TypeFoldable<'tcx> { + self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| { + self.infcx.next_region_var(infer::MiscVariable(span)) + }) + } } -impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> { - // FIXME: Nashenas88: implement me! +fn span_from_location<'tcx>(source: Mir<'tcx>, location: Location) -> Span { + source[location.block].statements[location.statement_index].source_info.span +} + +impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { + fn visit_ty(&mut self, ty: &mut Ty<'tcx>) { + let old_ty = *ty; + // FIXME: Nashenas88 - span should be narrowed down + *ty = self.renumber_regions(&old_ty, self.source.span); + } + + fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) { + // FIXME: Nashenas88 - span should be narrowed down + *substs = self.renumber_regions(&{*substs}, self.source.span); + } + + fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { + match *rvalue { + Rvalue::Ref(ref mut r, _, _) => { + let span = span_from_location(location); + let old_r = *r; + *r = self.renumber_regions(&old_r, span); + } + Rvalue::Use(..) | + Rvalue::Repeat(..) | + Rvalue::Len(..) | + Rvalue::Cast(..) | + Rvalue::BinaryOp(..) | + Rvalue::CheckedBinaryOp(..) | + Rvalue::UnaryOp(..) | + Rvalue::Discriminant(..) | + Rvalue::NullaryOp(..) | + Rvalue::Aggregate(..) => { + // These variants don't contain regions. + } + } + self.super_rvalue(rvalue, location); + } + + fn visit_closure_substs(&mut self, + substs: &mut ClosureSubsts<'tcx>) { + // FIXME: Nashenas88 - span should be narrowed down + *substs = self.renumber_regions(substs, self.source.span); + } + + fn visit_statement(&mut self, + block: BasicBlock, + statement: &mut Statement<'tcx>, + location: Location) { + if let StatementKind::EndRegion(_) = statement.kind { + statement.kind = StatementKind::Nop; + } + self.super_statement(block, statement, location); + } } // MIR Pass for non-lexical lifetimes @@ -38,10 +102,16 @@ impl MirPass for NLL { tcx: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) { - if tcx.sess.opts.debugging_opts.nll { + if !tcx.sess.opts.debugging_opts.nll { + return; + } + + tcx.infer_ctxt().enter(|infcx| { + let mut visitor = NLLVisitor::new(infcx, mir.clone()); // Clone mir so we can mutate it without disturbing the rest // of the compiler - NLLVisitor::new(tcx).visit_mir(&mut mir.clone()); - } + let mut mir = mir.clone(); + visitor.visit_mir(&mut mir); + }) } } \ No newline at end of file |
