1 //! Detecting language items.
3 //! Language items are items that represent concepts intrinsic to the language
4 //! itself. Examples are:
6 //! * Traits that specify "kinds"; e.g., `Sync`, `Send`.
7 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
8 //! * Functions called by the compiler itself.
10 use crate::ty::{self, TyCtxt};
12 use rustc_hir::def_id::DefId;
13 use rustc_hir::LangItem;
15 use rustc_target::spec::PanicStrategy;
17 impl<'tcx> TyCtxt<'tcx> {
18 /// Returns the `DefId` for a given `LangItem`.
19 /// If not found, fatally aborts compilation.
20 pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
21 self.lang_items().require(lang_item).unwrap_or_else(|msg| {
22 if let Some(span) = span {
23 self.sess.span_fatal(span, &msg)
30 pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option<ty::ClosureKind> {
31 let items = self.lang_items();
33 x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
34 x if x == items.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
35 x if x == items.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
40 pub fn is_weak_lang_item(self, item_def_id: DefId) -> bool {
41 self.lang_items().is_weak_lang_item(item_def_id)
45 /// Returns `true` if the specified `lang_item` must be present for this
48 /// Not all lang items are always required for each compilation, particularly in
49 /// the case of panic=abort. In these situations some lang items are injected by
50 /// crates and don't actually need to be defined in libstd.
51 pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
52 // If we're not compiling with unwinding, we won't actually need these
53 // symbols. Other panic runtimes ensure that the relevant symbols are
54 // available to link things together, but they're never exercised.
55 match tcx.sess.panic_strategy() {
56 PanicStrategy::Abort => {
57 lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
59 PanicStrategy::Unwind => true,