]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/transform/cleanup_post_borrowck.rs
New upstream version 1.32.0~beta.2+dfsg1
[rustc.git] / src / librustc_mir / transform / cleanup_post_borrowck.rs
CommitLineData
041b39d2
XL
1// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
0531ce1d 11//! This module provides two passes:
041b39d2 12//!
a1dfa0c6
XL
13//! - [CleanAscribeUserType], that replaces all
14//! [StatementKind::AscribeUserType] statements with [StatementKind::Nop].
15//! - [CleanFakeReadsAndBorrows], that replaces all [FakeRead] statements and
16//! borrows that are read by [FakeReadCause::ForMatchGuard] fake reads with
17//! [StatementKind::Nop].
0531ce1d 18//!
a1dfa0c6 19//! The [CleanFakeReadsAndBorrows] "pass" is actually implemented as two
0531ce1d 20//! traversals (aka visits) of the input MIR. The first traversal,
a1dfa0c6
XL
21//! [DeleteAndRecordFakeReads], deletes the fake reads and finds the temporaries
22//! read by [ForMatchGuard] reads, and [DeleteFakeBorrows] deletes the
23//! initialization of those temporaries.
041b39d2
XL
24
25use rustc_data_structures::fx::FxHashSet;
26
0bf4aa26 27use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place};
a1dfa0c6
XL
28use rustc::mir::{Statement, StatementKind};
29use rustc::mir::visit::MutVisitor;
30use rustc::ty::TyCtxt;
abe05a73 31use transform::{MirPass, MirSource};
041b39d2 32
b7449926 33pub struct CleanAscribeUserType;
0531ce1d 34
b7449926 35pub struct DeleteAscribeUserType;
0531ce1d 36
b7449926 37impl MirPass for CleanAscribeUserType {
0531ce1d
XL
38 fn run_pass<'a, 'tcx>(&self,
39 _tcx: TyCtxt<'a, 'tcx, 'tcx>,
40 _source: MirSource,
41 mir: &mut Mir<'tcx>) {
b7449926 42 let mut delete = DeleteAscribeUserType;
0531ce1d
XL
43 delete.visit_mir(mir);
44 }
45}
46
b7449926 47impl<'tcx> MutVisitor<'tcx> for DeleteAscribeUserType {
0531ce1d
XL
48 fn visit_statement(&mut self,
49 block: BasicBlock,
50 statement: &mut Statement<'tcx>,
51 location: Location) {
b7449926 52 if let StatementKind::AscribeUserType(..) = statement.kind {
0531ce1d 53 statement.make_nop();
041b39d2
XL
54 }
55 self.super_statement(block, statement, location);
56 }
57}
0bf4aa26
XL
58
59pub struct CleanFakeReadsAndBorrows;
60
61#[derive(Default)]
62pub struct DeleteAndRecordFakeReads {
63 fake_borrow_temporaries: FxHashSet<Local>,
64}
65
66pub struct DeleteFakeBorrows {
67 fake_borrow_temporaries: FxHashSet<Local>,
68}
69
70// Removes any FakeReads from the MIR
71impl MirPass for CleanFakeReadsAndBorrows {
72 fn run_pass<'a, 'tcx>(&self,
73 _tcx: TyCtxt<'a, 'tcx, 'tcx>,
74 _source: MirSource,
75 mir: &mut Mir<'tcx>) {
76 let mut delete_reads = DeleteAndRecordFakeReads::default();
77 delete_reads.visit_mir(mir);
78 let mut delete_borrows = DeleteFakeBorrows {
79 fake_borrow_temporaries: delete_reads.fake_borrow_temporaries,
80 };
81 delete_borrows.visit_mir(mir);
82 }
83}
84
85impl<'tcx> MutVisitor<'tcx> for DeleteAndRecordFakeReads {
86 fn visit_statement(&mut self,
87 block: BasicBlock,
88 statement: &mut Statement<'tcx>,
89 location: Location) {
90 if let StatementKind::FakeRead(cause, ref place) = statement.kind {
91 if let FakeReadCause::ForMatchGuard = cause {
92 match *place {
93 Place::Local(local) => self.fake_borrow_temporaries.insert(local),
94 _ => bug!("Fake match guard read of non-local: {:?}", place),
95 };
96 }
97 statement.make_nop();
98 }
99 self.super_statement(block, statement, location);
100 }
101}
102
103impl<'tcx> MutVisitor<'tcx> for DeleteFakeBorrows {
104 fn visit_statement(&mut self,
105 block: BasicBlock,
106 statement: &mut Statement<'tcx>,
107 location: Location) {
108 if let StatementKind::Assign(Place::Local(local), _) = statement.kind {
109 if self.fake_borrow_temporaries.contains(&local) {
110 statement.make_nop();
111 }
112 }
113 self.super_statement(block, statement, location);
114 }
115}