about summary refs log tree commit diff
path: root/src/librustc_trans_utils/common.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc_trans_utils/common.rs')
-rw-r--r--src/librustc_trans_utils/common.rs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/librustc_trans_utils/common.rs b/src/librustc_trans_utils/common.rs
new file mode 100644
index 00000000000..47968afd70d
--- /dev/null
+++ b/src/librustc_trans_utils/common.rs
@@ -0,0 +1,92 @@
+// Copyright 2012-2014 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.
+
+#![allow(non_camel_case_types, non_snake_case)]
+
+//! Code that is useful in various trans modules.
+
+use rustc::hir::def_id::DefId;
+use rustc::hir::map::DefPathData;
+use rustc::traits;
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc::ty::subst::Substs;
+
+use syntax::attr;
+use syntax_pos::DUMMY_SP;
+
+pub fn type_is_sized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
+    ty.is_sized(tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
+}
+
+pub fn type_has_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
+    if type_is_sized(tcx, ty) {
+        return false;
+    }
+
+    let tail = tcx.struct_tail(ty);
+    match tail.sty {
+        ty::TyForeign(..) => false,
+        ty::TyStr | ty::TySlice(..) | ty::TyDynamic(..) => true,
+        _ => bug!("unexpected unsized tail: {:?}", tail.sty),
+    }
+}
+
+pub fn requests_inline<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    instance: &ty::Instance<'tcx>
+) -> bool {
+    if is_inline_instance(tcx, instance) {
+        return true
+    }
+    if let ty::InstanceDef::DropGlue(..) = instance.def {
+        // Drop glue wants to be instantiated at every translation
+        // unit, but without an #[inline] hint. We should make this
+        // available to normal end-users.
+        return true
+    }
+    attr::requests_inline(&instance.def.attrs(tcx)[..]) ||
+        tcx.is_const_fn(instance.def.def_id())
+}
+
+pub fn is_inline_instance<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    instance: &ty::Instance<'tcx>
+) -> bool {
+    let def_id = match instance.def {
+        ty::InstanceDef::Item(def_id) => def_id,
+        ty::InstanceDef::DropGlue(_, Some(_)) => return false,
+        _ => return true
+    };
+    match tcx.def_key(def_id).disambiguated_data.data {
+        DefPathData::StructCtor |
+        DefPathData::EnumVariant(..) |
+        DefPathData::ClosureExpr => true,
+        _ => false
+    }
+}
+
+/// Given a DefId and some Substs, produces the monomorphic item type.
+pub fn def_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                        def_id: DefId,
+                        substs: &'tcx Substs<'tcx>)
+                        -> Ty<'tcx>
+{
+    let ty = tcx.type_of(def_id);
+    tcx.trans_apply_param_substs(substs, &ty)
+}
+
+/// Return the substituted type of an instance.
+pub fn instance_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                             instance: &ty::Instance<'tcx>)
+                             -> Ty<'tcx>
+{
+    let ty = instance.def.def_ty(tcx);
+    tcx.trans_apply_param_substs(instance.substs, &ty)
+}