summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_middle/src/middle/lang_items.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/middle/lang_items.rs')
-rw-r--r--compiler/rustc_middle/src/middle/lang_items.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs
new file mode 100644
index 000000000..cc9706f2d
--- /dev/null
+++ b/compiler/rustc_middle/src/middle/lang_items.rs
@@ -0,0 +1,61 @@
+//! Detecting language items.
+//!
+//! Language items are items that represent concepts intrinsic to the language
+//! itself. Examples are:
+//!
+//! * Traits that specify "kinds"; e.g., `Sync`, `Send`.
+//! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
+//! * Functions called by the compiler itself.
+
+use crate::ty::{self, TyCtxt};
+
+use rustc_hir::def_id::DefId;
+use rustc_hir::LangItem;
+use rustc_span::Span;
+use rustc_target::spec::PanicStrategy;
+
+impl<'tcx> TyCtxt<'tcx> {
+ /// Returns the `DefId` for a given `LangItem`.
+ /// If not found, fatally aborts compilation.
+ pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
+ self.lang_items().require(lang_item).unwrap_or_else(|msg| {
+ if let Some(span) = span {
+ self.sess.span_fatal(span, &msg)
+ } else {
+ self.sess.fatal(&msg)
+ }
+ })
+ }
+
+ pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option<ty::ClosureKind> {
+ let items = self.lang_items();
+ match Some(id) {
+ x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
+ x if x == items.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
+ x if x == items.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
+ _ => None,
+ }
+ }
+
+ pub fn is_weak_lang_item(self, item_def_id: DefId) -> bool {
+ self.lang_items().is_weak_lang_item(item_def_id)
+ }
+}
+
+/// Returns `true` if the specified `lang_item` must be present for this
+/// compilation.
+///
+/// Not all lang items are always required for each compilation, particularly in
+/// the case of panic=abort. In these situations some lang items are injected by
+/// crates and don't actually need to be defined in libstd.
+pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
+ // If we're not compiling with unwinding, we won't actually need these
+ // symbols. Other panic runtimes ensure that the relevant symbols are
+ // available to link things together, but they're never exercised.
+ match tcx.sess.panic_strategy() {
+ PanicStrategy::Abort => {
+ lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
+ }
+ PanicStrategy::Unwind => true,
+ }
+}