summary refs log tree commit diff
path: root/src/librustc_metadata/tls_context.rs
blob: 23142ca80ef0ecc695c088650263b15c5d2eb26c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// 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.

// This module provides implementations for the thread-local encoding and
// decoding context traits in rustc::middle::cstore::tls.

use rbml::opaque::Encoder as OpaqueEncoder;
use rbml::opaque::Decoder as OpaqueDecoder;
use rustc::middle::cstore::tls;
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt};

use decoder::{self, Cmd};
use encoder;
use tydecode::TyDecoder;
use tyencode;

impl<'a, 'tcx: 'a> tls::EncodingContext<'tcx> for encoder::EncodeContext<'a, 'tcx> {

    fn tcx<'s>(&'s self) -> TyCtxt<'s, 'tcx, 'tcx> {
        self.tcx
    }

    fn encode_ty(&self, encoder: &mut OpaqueEncoder, t: ty::Ty<'tcx>) {
        tyencode::enc_ty(encoder.cursor, &self.ty_str_ctxt(), t);
    }

    fn encode_substs(&self, encoder: &mut OpaqueEncoder, substs: &Substs<'tcx>) {
        tyencode::enc_substs(encoder.cursor, &self.ty_str_ctxt(), substs);
    }
}

pub struct DecodingContext<'a, 'tcx: 'a> {
    pub crate_metadata: Cmd<'a>,
    pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
}

impl<'a, 'tcx: 'a> tls::DecodingContext<'tcx> for DecodingContext<'a, 'tcx> {

    fn tcx<'s>(&'s self) -> TyCtxt<'s, 'tcx, 'tcx> {
        self.tcx
    }

    fn decode_ty(&self, decoder: &mut OpaqueDecoder) -> ty::Ty<'tcx> {
        let def_id_convert = &mut |did| {
            decoder::translate_def_id(self.crate_metadata, did)
        };

        let starting_position = decoder.position();

        let mut ty_decoder = TyDecoder::new(
            self.crate_metadata.data.as_slice(),
            self.crate_metadata.cnum,
            starting_position,
            self.tcx,
            def_id_convert);

        let ty = ty_decoder.parse_ty();

        let end_position = ty_decoder.position();

        // We can just reuse the tydecode implementation for parsing types, but
        // we have to make sure to leave the rbml reader at the position just
        // after the type.
        decoder.advance(end_position - starting_position);
        ty
    }

    fn decode_substs(&self, decoder: &mut OpaqueDecoder) -> Substs<'tcx> {
        let def_id_convert = &mut |did| {
            decoder::translate_def_id(self.crate_metadata, did)
        };

        let starting_position = decoder.position();

        let mut ty_decoder = TyDecoder::new(
            self.crate_metadata.data.as_slice(),
            self.crate_metadata.cnum,
            starting_position,
            self.tcx,
            def_id_convert);

        let substs = ty_decoder.parse_substs();

        let end_position = ty_decoder.position();

        decoder.advance(end_position - starting_position);
        substs
    }

    fn translate_def_id(&self, def_id: DefId) -> DefId {
        decoder::translate_def_id(self.crate_metadata, def_id)
    }
}