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.
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.
11 use rustc
::hir
::intravisit
::{Visitor, NestedVisitorMap}
;
13 use isolated_encoder
::IsolatedEncoder
;
17 use rustc
::ty
::{self, TyCtxt}
;
19 use rustc
::ich
::Fingerprint
;
20 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
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
,
31 impl_stable_hash_for
!(struct Ast
<'tcx
> {
35 rvalue_promotable_to_static
,
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
);
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();
49 hcx
.while_hashing_hir_bodies(true, |hcx
| {
50 body
.hash_stable(hcx
, &mut hasher
);
56 let lazy_body
= self.lazy(body
);
57 let body_owner_def_id
= self.tcx
.hir
.body_owner_def_id(body_id
);
58 let tables
= self.tcx
.typeck_tables_of(body_owner_def_id
);
59 let lazy_tables
= self.lazy(tables
);
61 let mut visitor
= NestedBodyCollector
{
63 bodies_found
: Vec
::new(),
65 visitor
.visit_body(body
);
66 let lazy_nested_bodies
= self.lazy_seq_ref_from_slice(&visitor
.bodies_found
);
68 let rvalue_promotable_to_static
=
69 self.tcx
.const_is_rvalue_promotable_to_static(body_owner_def_id
);
74 nested_bodies
: lazy_nested_bodies
,
75 rvalue_promotable_to_static
,
81 struct NestedBodyCollector
<'a
, 'tcx
: 'a
> {
82 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
83 bodies_found
: Vec
<&'tcx hir
::Body
>,
86 impl<'a
, 'tcx
: 'a
> Visitor
<'tcx
> for NestedBodyCollector
<'a
, 'tcx
> {
87 fn nested_visit_map
<'this
>(&'this
mut self) -> NestedVisitorMap
<'this
, 'tcx
> {
88 NestedVisitorMap
::None
91 fn visit_nested_body(&mut self, body
: hir
::BodyId
) {
92 let body
= self.tcx
.hir
.body(body
);
93 self.bodies_found
.push(body
);
94 self.visit_body(body
);