]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/astencode.rs
Rollup merge of #45098 - sunjay:breakingrustfmtrls, r=alexcrichton
[rust.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::{self, TyCtxt};
18
19 use rustc::ich::Fingerprint;
20 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
21
22 #[derive(RustcEncodable, RustcDecodable)]
23 pub struct Ast<'tcx> {
24     pub body: Lazy<hir::Body>,
25     pub tables: Lazy<ty::TypeckTables<'tcx>>,
26     pub nested_bodies: LazySeq<hir::Body>,
27     pub rvalue_promotable_to_static: bool,
28     pub stable_bodies_hash: Fingerprint,
29 }
30
31 impl_stable_hash_for!(struct Ast<'tcx> {
32     body,
33     tables,
34     nested_bodies,
35     rvalue_promotable_to_static,
36     stable_bodies_hash
37 });
38
39 impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> {
40     pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy<Ast<'tcx>> {
41         let body = self.tcx.hir.body(body_id);
42
43         // In order to avoid having to hash hir::Bodies from extern crates, we
44         // hash them here, during export, and store the hash with metadata.
45         let stable_bodies_hash = {
46             let mut hcx = self.tcx.create_stable_hashing_context();
47             let mut hasher = StableHasher::new();
48
49             hcx.while_hashing_hir_bodies(true, |hcx| {
50                 hcx.while_hashing_spans(false, |hcx| {
51                     body.hash_stable(hcx, &mut hasher);
52                 });
53             });
54
55             hasher.finish()
56         };
57
58         let lazy_body = self.lazy(body);
59         let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
60         let tables = self.tcx.typeck_tables_of(body_owner_def_id);
61         let lazy_tables = self.lazy(tables);
62
63         let mut visitor = NestedBodyCollector {
64             tcx: self.tcx,
65             bodies_found: Vec::new(),
66         };
67         visitor.visit_body(body);
68         let lazy_nested_bodies = self.lazy_seq_ref_from_slice(&visitor.bodies_found);
69
70         let rvalue_promotable_to_static =
71             self.tcx.const_is_rvalue_promotable_to_static(body_owner_def_id);
72
73         self.lazy(&Ast {
74             body: lazy_body,
75             tables: lazy_tables,
76             nested_bodies: lazy_nested_bodies,
77             rvalue_promotable_to_static,
78             stable_bodies_hash,
79         })
80     }
81 }
82
83 struct NestedBodyCollector<'a, 'tcx: 'a> {
84     tcx: TyCtxt<'a, 'tcx, 'tcx>,
85     bodies_found: Vec<&'tcx hir::Body>,
86 }
87
88 impl<'a, 'tcx: 'a> Visitor<'tcx> for NestedBodyCollector<'a, 'tcx> {
89     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
90         NestedVisitorMap::None
91     }
92
93     fn visit_nested_body(&mut self, body: hir::BodyId) {
94         let body = self.tcx.hir.body(body);
95         self.bodies_found.push(body);
96         self.visit_body(body);
97     }
98 }