]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/middle/lang_items.rs
Auto merge of #97176 - kraktus:cmd_debug, r=the8472
[rust.git] / compiler / rustc_middle / src / middle / lang_items.rs
1 //! Detecting language items.
2 //!
3 //! Language items are items that represent concepts intrinsic to the language
4 //! itself. Examples are:
5 //!
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.
9
10 use crate::ty::{self, TyCtxt};
11
12 use rustc_hir::def_id::DefId;
13 use rustc_hir::LangItem;
14 use rustc_span::Span;
15 use rustc_target::spec::PanicStrategy;
16
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(|err| {
22             if let Some(span) = span {
23                 self.sess.span_fatal(span, err.to_string())
24             } else {
25                 self.sess.fatal(err.to_string())
26             }
27         })
28     }
29
30     /// Given a [`DefId`] of a [`Fn`], [`FnMut`] or [`FnOnce`] traits,
31     /// returns a corresponding [`ty::ClosureKind`].
32     /// For any other [`DefId`] return `None`.
33     pub fn fn_trait_kind_from_def_id(self, id: DefId) -> Option<ty::ClosureKind> {
34         let items = self.lang_items();
35         match Some(id) {
36             x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
37             x if x == items.fn_mut_trait() => Some(ty::ClosureKind::FnMut),
38             x if x == items.fn_once_trait() => Some(ty::ClosureKind::FnOnce),
39             _ => None,
40         }
41     }
42
43     /// Returns `true` if `id` is a `DefId` of [`Fn`], [`FnMut`] or [`FnOnce`] traits.
44     pub fn is_fn_trait(self, id: DefId) -> bool {
45         self.fn_trait_kind_from_def_id(id).is_some()
46     }
47 }
48
49 /// Returns `true` if the specified `lang_item` must be present for this
50 /// compilation.
51 ///
52 /// Not all lang items are always required for each compilation, particularly in
53 /// the case of panic=abort. In these situations some lang items are injected by
54 /// crates and don't actually need to be defined in libstd.
55 pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
56     // If we're not compiling with unwinding, we won't actually need these
57     // symbols. Other panic runtimes ensure that the relevant symbols are
58     // available to link things together, but they're never exercised.
59     match tcx.sess.panic_strategy() {
60         PanicStrategy::Abort => {
61             lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
62         }
63         PanicStrategy::Unwind => true,
64     }
65 }