]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/tcx/mod.rs
Remove random Idents outside of libsyntax
[rust.git] / src / librustc_mir / tcx / mod.rs
1 // Copyright 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 hair::*;
12 use repr::*;
13 use std::fmt::{Debug, Formatter, Error};
14 use std::hash::{Hash, Hasher};
15 use std::rc::Rc;
16
17 use self::rustc::middle::def_id::DefId;
18 use self::rustc::middle::infer::InferCtxt;
19 use self::rustc::middle::region::CodeExtent;
20 use self::rustc::middle::subst::{self, Subst, Substs};
21 use self::rustc::middle::ty::{self, Ty};
22 use self::rustc_front::hir;
23 use self::syntax::ast;
24 use self::syntax::codemap::Span;
25 use self::syntax::parse::token::{self, special_idents, InternedString};
26
27 extern crate rustc;
28 extern crate rustc_front;
29 extern crate syntax;
30
31 #[derive(Copy, Clone)]
32 pub struct Cx<'a,'tcx:'a> {
33     pub tcx: &'a ty::ctxt<'tcx>,
34     pub infcx: &'a InferCtxt<'a,'tcx>,
35 }
36
37 impl<'a,'tcx> Cx<'a,'tcx> {
38     pub fn new(infcx: &'a InferCtxt<'a,'tcx>) -> Cx<'a,'tcx> {
39         Cx { tcx: infcx.tcx, infcx: infcx }
40     }
41 }
42
43 pub use self::pattern::PatNode;
44
45 impl<'a,'tcx:'a> Hair for Cx<'a, 'tcx> {
46     type VarId = ast::NodeId;
47     type DefId = DefId;
48     type AdtDef = ty::AdtDef<'tcx>;
49     type Name = ast::Name;
50     type InternedString = InternedString;
51     type Bytes = Rc<Vec<u8>>;
52     type Span = Span;
53     type Projection = ty::ProjectionTy<'tcx>;
54     type Substs = &'tcx subst::Substs<'tcx>;
55     type ClosureSubsts = &'tcx ty::ClosureSubsts<'tcx>;
56     type Ty = Ty<'tcx>;
57     type Region = ty::Region;
58     type CodeExtent = CodeExtent;
59     type Pattern = PatNode<'tcx>;
60     type Expr = &'tcx hir::Expr;
61     type Stmt = &'tcx hir::Stmt;
62     type Block = &'tcx hir::Block;
63     type InlineAsm = &'tcx hir::InlineAsm;
64
65     fn unit_ty(&mut self) -> Ty<'tcx> {
66         self.tcx.mk_nil()
67     }
68
69     fn usize_ty(&mut self) -> Ty<'tcx> {
70         self.tcx.types.usize
71     }
72
73     fn bool_ty(&mut self) -> Ty<'tcx> {
74         self.tcx.types.bool
75     }
76
77     fn partial_eq(&mut self, ty: Ty<'tcx>) -> ItemRef<Self> {
78         let eq_def_id = self.tcx.lang_items.eq_trait().unwrap();
79         self.cmp_method_ref(eq_def_id, "eq", ty)
80     }
81
82     fn partial_le(&mut self, ty: Ty<'tcx>) -> ItemRef<Self> {
83         let ord_def_id = self.tcx.lang_items.ord_trait().unwrap();
84         self.cmp_method_ref(ord_def_id, "le", ty)
85     }
86
87     fn num_variants(&mut self, adt_def: ty::AdtDef<'tcx>) -> usize {
88         adt_def.variants.len()
89     }
90
91     fn fields(&mut self, adt_def: ty::AdtDef<'tcx>, variant_index: usize) -> Vec<Field<Self>> {
92         adt_def.variants[variant_index]
93             .fields
94             .iter()
95             .enumerate()
96             .map(|(index, field)| {
97                 if field.name == special_idents::unnamed_field.name {
98                     Field::Indexed(index)
99                 } else {
100                     Field::Named(field.name)
101                 }
102             })
103             .collect()
104     }
105
106     fn needs_drop(&mut self, ty: Ty<'tcx>, span: Self::Span) -> bool {
107         if self.infcx.type_moves_by_default(ty, span) {
108             // FIXME(#21859) we should do an add'l check here to determine if
109             // any dtor will execute, but the relevant fn
110             // (`type_needs_drop`) is currently factored into
111             // `librustc_trans`, so we can't easily do so.
112             true
113         } else {
114             // if type implements Copy, cannot require drop
115             false
116         }
117     }
118
119     fn span_bug(&mut self, span: Self::Span, message: &str) -> ! {
120         self.tcx.sess.span_bug(span, message)
121     }
122 }
123
124 impl<'a,'tcx:'a> Cx<'a,'tcx> {
125     fn cmp_method_ref(&mut self,
126                       trait_def_id: DefId,
127                       method_name: &str,
128                       arg_ty: Ty<'tcx>)
129                       -> ItemRef<Cx<'a,'tcx>> {
130         let method_name = token::intern(method_name);
131         let substs = Substs::new_trait(vec![arg_ty], vec![], arg_ty);
132         for trait_item in self.tcx.trait_items(trait_def_id).iter() {
133             match *trait_item {
134                 ty::ImplOrTraitItem::MethodTraitItem(ref method) => {
135                     if method.name == method_name {
136                         let method_ty = self.tcx.lookup_item_type(method.def_id);
137                         let method_ty = method_ty.ty.subst(self.tcx, &substs);
138                         return ItemRef {
139                             ty: method_ty,
140                             def_id: method.def_id,
141                             substs: self.tcx.mk_substs(substs),
142                         };
143                     }
144                 }
145                 ty::ImplOrTraitItem::ConstTraitItem(..) |
146                 ty::ImplOrTraitItem::TypeTraitItem(..) => {
147                 }
148             }
149         }
150
151         self.tcx.sess.bug(
152             &format!("found no method `{}` in `{:?}`", method_name, trait_def_id));
153     }
154 }
155
156 // We only need this impl so that we do deriving for things that are
157 // defined relative to the `Hair` trait. See `Hair` trait for more
158 // details.
159 impl<'a,'tcx> PartialEq for Cx<'a,'tcx> {
160     fn eq(&self, _: &Cx<'a,'tcx>) -> bool {
161         panic!("Cx should never ACTUALLY be compared for equality")
162     }
163 }
164
165 impl<'a,'tcx> Eq for Cx<'a,'tcx> { }
166
167 impl<'a,'tcx> Hash for Cx<'a,'tcx> {
168     fn hash<H: Hasher>(&self, _: &mut H) {
169         panic!("Cx should never ACTUALLY be hashed")
170     }
171 }
172
173 impl<'a,'tcx> Debug for Cx<'a,'tcx> {
174     fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
175         write!(fmt, "Tcx")
176     }
177 }
178
179 mod block;
180 mod expr;
181 mod pattern;
182 mod to_ref;
183