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.
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.
12 * This module contains the code to convert from the wacky tcx data
13 * structures into the hair. The `builder` is generally ignorant of
14 * the tcx etc, and instead goes through the `Cx` for most of its
19 use rustc
::mir
::repr
::*;
21 use rustc
::middle
::const_val
::ConstVal
;
22 use rustc_const_eval
as const_eval
;
23 use rustc
::hir
::def_id
::DefId
;
24 use rustc
::infer
::InferCtxt
;
25 use rustc
::ty
::subst
::{Subst, Substs}
;
26 use rustc
::ty
::{self, Ty, TyCtxt}
;
27 use syntax
::parse
::token
;
29 use rustc_const_math
::{ConstInt, ConstUsize}
;
31 #[derive(Copy, Clone)]
32 pub struct Cx
<'a
, 'tcx
: 'a
> {
33 tcx
: &'a TyCtxt
<'tcx
>,
34 infcx
: &'a InferCtxt
<'a
, 'tcx
>,
37 impl<'a
,'tcx
> Cx
<'a
,'tcx
> {
38 pub fn new(infcx
: &'a InferCtxt
<'a
, 'tcx
>) -> Cx
<'a
, 'tcx
> {
46 impl<'a
,'tcx
:'a
> Cx
<'a
, 'tcx
> {
47 /// Normalizes `ast` into the appropriate `mirror` type.
48 pub fn mirror
<M
: Mirror
<'tcx
>>(&mut self, ast
: M
) -> M
::Output
{
52 pub fn usize_ty(&mut self) -> Ty
<'tcx
> {
56 pub fn usize_literal(&mut self, value
: u64) -> Literal
<'tcx
> {
57 match ConstUsize
::new(value
, self.tcx
.sess
.target
.uint_type
) {
58 Ok(val
) => Literal
::Value { value: ConstVal::Integral(ConstInt::Usize(val))}
,
59 Err(_
) => bug
!("usize literal out of range for target"),
63 pub fn bool_ty(&mut self) -> Ty
<'tcx
> {
67 pub fn unit_ty(&mut self) -> Ty
<'tcx
> {
71 pub fn str_literal(&mut self, value
: token
::InternedString
) -> Literal
<'tcx
> {
72 Literal
::Value { value: ConstVal::Str(value) }
75 pub fn true_literal(&mut self) -> Literal
<'tcx
> {
76 Literal
::Value { value: ConstVal::Bool(true) }
79 pub fn false_literal(&mut self) -> Literal
<'tcx
> {
80 Literal
::Value { value: ConstVal::Bool(false) }
83 pub fn const_eval_literal(&mut self, e
: &hir
::Expr
) -> Literal
<'tcx
> {
84 Literal
::Value { value: const_eval::eval_const_expr(self.tcx, e) }
87 pub fn try_const_eval_literal(&mut self, e
: &hir
::Expr
) -> Option
<Literal
<'tcx
>> {
88 let hint
= const_eval
::EvalHint
::ExprTypeChecked
;
89 const_eval
::eval_const_expr_partial(self.tcx
, e
, hint
, None
).ok().and_then(|v
| {
91 // All of these contain local IDs, unsuitable for storing in MIR.
92 ConstVal
::Struct(_
) | ConstVal
::Tuple(_
) |
93 ConstVal
::Array(..) | ConstVal
::Repeat(..) |
94 ConstVal
::Function(_
) => None
,
96 _
=> Some(Literal
::Value { value: v }
)
101 pub fn trait_method(&mut self,
105 params
: Vec
<Ty
<'tcx
>>)
106 -> (Ty
<'tcx
>, Literal
<'tcx
>) {
107 let method_name
= token
::intern(method_name
);
108 let substs
= Substs
::new_trait(params
, vec
![], self_ty
);
109 for trait_item
in self.tcx
.trait_items(trait_def_id
).iter() {
111 ty
::ImplOrTraitItem
::MethodTraitItem(ref method
) => {
112 if method
.name
== method_name
{
113 let method_ty
= self.tcx
.lookup_item_type(method
.def_id
);
114 let method_ty
= method_ty
.ty
.subst(self.tcx
, &substs
);
115 return (method_ty
, Literal
::Item
{
116 def_id
: method
.def_id
,
117 substs
: self.tcx
.mk_substs(substs
),
121 ty
::ImplOrTraitItem
::ConstTraitItem(..) |
122 ty
::ImplOrTraitItem
::TypeTraitItem(..) => {}
126 bug
!("found no method `{}` in `{:?}`", method_name
, trait_def_id
);
129 pub fn num_variants(&mut self, adt_def
: ty
::AdtDef
<'tcx
>) -> usize {
130 adt_def
.variants
.len()
133 pub fn all_fields(&mut self, adt_def
: ty
::AdtDef
<'tcx
>, variant_index
: usize) -> Vec
<Field
> {
134 (0..adt_def
.variants
[variant_index
].fields
.len())
139 pub fn needs_drop(&mut self, ty
: Ty
<'tcx
>) -> bool
{
140 self.tcx
.type_needs_drop_given_env(ty
, &self.infcx
.parameter_environment
)
143 pub fn tcx(&self) -> &'a TyCtxt
<'tcx
> {