97 lines
3.0 KiB
Rust
97 lines
3.0 KiB
Rust
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
|
|
|
|
use isolated_encoder::IsolatedEncoder;
|
|
use schema::*;
|
|
|
|
use rustc::hir;
|
|
use rustc::ty::{self, TyCtxt};
|
|
|
|
use rustc::ich::Fingerprint;
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
|
|
|
#[derive(RustcEncodable, RustcDecodable)]
|
|
pub struct Ast<'tcx> {
|
|
pub body: Lazy<hir::Body>,
|
|
pub tables: Lazy<ty::TypeckTables<'tcx>>,
|
|
pub nested_bodies: LazySeq<hir::Body>,
|
|
pub rvalue_promotable_to_static: bool,
|
|
pub stable_bodies_hash: Fingerprint,
|
|
}
|
|
|
|
impl_stable_hash_for!(struct Ast<'tcx> {
|
|
body,
|
|
tables,
|
|
nested_bodies,
|
|
rvalue_promotable_to_static,
|
|
stable_bodies_hash
|
|
});
|
|
|
|
impl<'a, 'b, 'tcx> IsolatedEncoder<'a, 'b, 'tcx> {
|
|
pub fn encode_body(&mut self, body_id: hir::BodyId) -> Lazy<Ast<'tcx>> {
|
|
let body = self.tcx.hir.body(body_id);
|
|
|
|
// In order to avoid having to hash hir::Bodies from extern crates, we
|
|
// hash them here, during export, and store the hash with metadata.
|
|
let stable_bodies_hash = {
|
|
let mut hcx = self.tcx.create_stable_hashing_context();
|
|
let mut hasher = StableHasher::new();
|
|
|
|
hcx.while_hashing_hir_bodies(true, |hcx| {
|
|
body.hash_stable(hcx, &mut hasher);
|
|
});
|
|
|
|
hasher.finish()
|
|
};
|
|
|
|
let lazy_body = self.lazy(body);
|
|
let body_owner_def_id = self.tcx.hir.body_owner_def_id(body_id);
|
|
let tables = self.tcx.typeck_tables_of(body_owner_def_id);
|
|
let lazy_tables = self.lazy(tables);
|
|
|
|
let mut visitor = NestedBodyCollector {
|
|
tcx: self.tcx,
|
|
bodies_found: Vec::new(),
|
|
};
|
|
visitor.visit_body(body);
|
|
let lazy_nested_bodies = self.lazy_seq_ref_from_slice(&visitor.bodies_found);
|
|
|
|
let rvalue_promotable_to_static =
|
|
self.tcx.const_is_rvalue_promotable_to_static(body_owner_def_id);
|
|
|
|
self.lazy(&Ast {
|
|
body: lazy_body,
|
|
tables: lazy_tables,
|
|
nested_bodies: lazy_nested_bodies,
|
|
rvalue_promotable_to_static,
|
|
stable_bodies_hash,
|
|
})
|
|
}
|
|
}
|
|
|
|
struct NestedBodyCollector<'a, 'tcx: 'a> {
|
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|
bodies_found: Vec<&'tcx hir::Body>,
|
|
}
|
|
|
|
impl<'a, 'tcx: 'a> Visitor<'tcx> for NestedBodyCollector<'a, 'tcx> {
|
|
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
|
|
NestedVisitorMap::None
|
|
}
|
|
|
|
fn visit_nested_body(&mut self, body: hir::BodyId) {
|
|
let body = self.tcx.hir.body(body);
|
|
self.bodies_found.push(body);
|
|
self.visit_body(body);
|
|
}
|
|
}
|