]> git.proxmox.com Git - rustc.git/blob - src/librustc_metadata/astencode.rs
New upstream version 1.19.0+dfsg1
[rustc.git] / src / librustc_metadata / astencode.rs
1 // Copyright 2012-2015 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
11 use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
12
13 use isolated_encoder::IsolatedEncoder;
14 use schema::*;
15
16 use rustc::hir;
17 use rustc::ty;
18
19 #[derive(RustcEncodable, RustcDecodable)]
20 pub struct Ast<'tcx> {
21 pub body: Lazy<hir::Body>,
22 pub tables: Lazy<ty::TypeckTables<'tcx>>,
23 pub nested_bodies: LazySeq<hir::Body>,
24 pub rvalue_promotable_to_static: bool,
25 }
26
27 impl_stable_hash_for!(struct Ast<'tcx> {
28 body,
29 tables,
30 nested_bodies,
31 rvalue_promotable_to_static
32 });
33
34 impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> {
35 pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy<Ast<'tcx>> {
36 let body = self.tcx.hir.body(body_id);
37 let lazy_body = self.lazy(body);
38
39 let tables = self.tcx.body_tables(body_id);
40 let lazy_tables = self.lazy(tables);
41
42 let mut visitor = NestedBodyCollector {
43 tcx: self.tcx,
44 bodies_found: Vec::new(),
45 };
46 visitor.visit_body(body);
47 let lazy_nested_bodies = self.lazy_seq_ref_from_slice(&visitor.bodies_found);
48
49 let rvalue_promotable_to_static =
50 self.tcx.rvalue_promotable_to_static.borrow()[&body.value.id];
51
52 self.lazy(&Ast {
53 body: lazy_body,
54 tables: lazy_tables,
55 nested_bodies: lazy_nested_bodies,
56 rvalue_promotable_to_static: rvalue_promotable_to_static
57 })
58 }
59 }
60
61 struct NestedBodyCollector<'a, 'tcx: 'a> {
62 tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
63 bodies_found: Vec<&'tcx hir::Body>,
64 }
65
66 impl<'a, 'tcx: 'a> Visitor<'tcx> for NestedBodyCollector<'a, 'tcx> {
67 fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
68 NestedVisitorMap::None
69 }
70
71 fn visit_nested_body(&mut self, body: hir::BodyId) {
72 let body = self.tcx.hir.body(body);
73 self.bodies_found.push(body);
74 self.visit_body(body);
75 }
76 }