Skip to content

Commit ff36923

Browse files
committed
Move lang_items definitions to librustc_lang_items.
1 parent a056817 commit ff36923

File tree

11 files changed

+372
-288
lines changed

11 files changed

+372
-288
lines changed

src/librustc/ich/impls_hir.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ impl<'ctx> rustc_hir::HashStableContext for StableHashingContext<'ctx> {
107107
}
108108
}
109109

110+
impl<'ctx> rustc_lang_items::HashStableContext for StableHashingContext<'ctx> {}
111+
110112
impl<'a> ToStableHashKey<StableHashingContext<'a>> for DefId {
111113
type KeyType = DefPathHash;
112114

@@ -251,12 +253,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
251253
}
252254
}
253255

254-
impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::lang_items::LangItem {
255-
fn hash_stable(&self, _: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
256-
::std::hash::Hash::hash(self, hasher);
257-
}
258-
}
259-
260256
impl<'a> HashStable<StableHashingContext<'a>> for hir::TraitCandidate {
261257
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
262258
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {

src/librustc/middle/lang_items.rs

Lines changed: 56 additions & 268 deletions
Large diffs are not rendered by default.

src/librustc/middle/weak_lang_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>,
4646
}
4747

4848
pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
49-
lang_items::extract(attrs).and_then(|(name, _)| {
49+
rustc_lang_items::lang_items::extract(attrs).and_then(|(name, _)| {
5050
$(if name == sym::$name {
5151
Some(sym::$sym)
5252
} else)* {

src/librustc/traits/select.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16341634
obligation: &TraitObligation<'tcx>,
16351635
candidates: &mut SelectionCandidateSet<'tcx>,
16361636
) -> Result<(), SelectionError<'tcx>> {
1637-
let kind = match self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()) {
1637+
let kind = match self.tcx().fn_trait_lang_item(obligation.predicate.def_id()) {
16381638
Some(k) => k,
16391639
None => {
16401640
return Ok(());
@@ -1677,7 +1677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16771677
candidates: &mut SelectionCandidateSet<'tcx>,
16781678
) -> Result<(), SelectionError<'tcx>> {
16791679
// We provide impl of all fn traits for fn pointers.
1680-
if self.tcx().lang_items().fn_trait_kind(obligation.predicate.def_id()).is_none() {
1680+
if self.tcx().fn_trait_lang_item(obligation.predicate.def_id()).is_none() {
16811681
return Ok(());
16821682
}
16831683

@@ -2889,8 +2889,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28892889

28902890
let kind = self
28912891
.tcx()
2892-
.lang_items()
2893-
.fn_trait_kind(obligation.predicate.def_id())
2892+
.fn_trait_lang_item(obligation.predicate.def_id())
28942893
.unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
28952894

28962895
// Okay to skip binder because the substs on closure types never

src/librustc/ty/instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ fn resolve_associated_item<'tcx>(
450450
substs: generator_data.substs,
451451
}),
452452
traits::VtableClosure(closure_data) => {
453-
let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap();
453+
let trait_closure_kind = tcx.fn_trait_lang_item(trait_id).unwrap();
454454
Some(Instance::resolve_closure(
455455
tcx,
456456
closure_data.closure_def_id,

src/librustc/ty/print/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ pub trait PrettyPrinter<'tcx>:
724724
let mut resugared = false;
725725

726726
// Special-case `Fn(...) -> ...` and resugar it.
727-
let fn_trait_kind = self.tcx().lang_items().fn_trait_kind(principal.def_id);
727+
let fn_trait_kind = self.tcx().fn_trait_lang_item(principal.def_id);
728728
if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
729729
if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
730730
let mut projections = predicates.projection_bounds();

src/librustc_lang_items/lang_items.rs

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
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+
pub use self::LangItem::*;
11+
12+
use crate::Target;
13+
14+
use rustc_data_structures::fx::FxHashMap;
15+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
16+
use rustc_hir::def_id::DefId;
17+
use rustc_macros::HashStable_Generic;
18+
use rustc_span::symbol::{sym, Symbol};
19+
use rustc_span::Span;
20+
use syntax::ast;
21+
22+
use lazy_static::lazy_static;
23+
24+
// The actual lang items defined come at the end of this file in one handy table.
25+
// So you probably just want to nip down to the end.
26+
macro_rules! language_item_table {
27+
(
28+
$( $variant:ident, $name:expr, $method:ident, $target:path; )*
29+
) => {
30+
31+
enum_from_u32! {
32+
/// A representation of all the valid language items in Rust.
33+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
34+
pub enum LangItem {
35+
$($variant,)*
36+
}
37+
}
38+
39+
impl LangItem {
40+
/// Returns the `name` in `#[lang = "$name"]`.
41+
/// For example, `LangItem::EqTraitLangItem`,
42+
/// that is `#[lang = "eq"]` would result in `"eq"`.
43+
pub fn name(self) -> &'static str {
44+
match self {
45+
$( $variant => $name, )*
46+
}
47+
}
48+
}
49+
50+
#[derive(HashStable_Generic)]
51+
pub struct LanguageItems {
52+
/// Mappings from lang items to their possibly found `DefId`s.
53+
/// The index corresponds to the order in `LangItem`.
54+
pub items: Vec<Option<DefId>>,
55+
/// Lang items that were not found during collection.
56+
pub missing: Vec<LangItem>,
57+
}
58+
59+
impl LanguageItems {
60+
/// Construct an empty collection of lang items and no missing ones.
61+
pub fn new() -> Self {
62+
fn init_none(_: LangItem) -> Option<DefId> { None }
63+
64+
Self {
65+
items: vec![$(init_none($variant)),*],
66+
missing: Vec::new(),
67+
}
68+
}
69+
70+
/// Returns the mappings to the possibly found `DefId`s for each lang item.
71+
pub fn items(&self) -> &[Option<DefId>] {
72+
&*self.items
73+
}
74+
75+
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
76+
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
77+
/// returns an error message as a string.
78+
pub fn require(&self, it: LangItem) -> Result<DefId, String> {
79+
self.items[it as usize].ok_or_else(|| format!("requires `{}` lang_item", it.name()))
80+
}
81+
82+
$(
83+
/// Returns the corresponding `DefId` for the lang item
84+
#[doc = $name]
85+
/// if it exists.
86+
#[allow(dead_code)]
87+
pub fn $method(&self) -> Option<DefId> {
88+
self.items[$variant as usize]
89+
}
90+
)*
91+
}
92+
93+
lazy_static! {
94+
/// A mapping from the name of the lang item to its order and the form it must be of.
95+
pub static ref ITEM_REFS: FxHashMap<&'static str, (usize, Target)> = {
96+
let mut item_refs = FxHashMap::default();
97+
$( item_refs.insert($name, ($variant as usize, $target)); )*
98+
item_refs
99+
};
100+
}
101+
102+
// End of the macro
103+
}
104+
}
105+
106+
impl<CTX> HashStable<CTX> for LangItem {
107+
fn hash_stable(&self, _: &mut CTX, hasher: &mut StableHasher) {
108+
::std::hash::Hash::hash(self, hasher);
109+
}
110+
}
111+
112+
/// Extracts the first `lang = "$name"` out of a list of attributes.
113+
/// The attributes `#[panic_handler]` and `#[alloc_error_handler]`
114+
/// are also extracted out when found.
115+
pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
116+
attrs.iter().find_map(|attr| {
117+
Some(match attr {
118+
_ if attr.check_name(sym::lang) => (attr.value_str()?, attr.span),
119+
_ if attr.check_name(sym::panic_handler) => (sym::panic_impl, attr.span),
120+
_ if attr.check_name(sym::alloc_error_handler) => (sym::oom, attr.span),
121+
_ => return None,
122+
})
123+
})
124+
}
125+
126+
language_item_table! {
127+
// Variant name, Name, Method name, Target;
128+
BoolImplItem, "bool", bool_impl, Target::Impl;
129+
CharImplItem, "char", char_impl, Target::Impl;
130+
StrImplItem, "str", str_impl, Target::Impl;
131+
SliceImplItem, "slice", slice_impl, Target::Impl;
132+
SliceU8ImplItem, "slice_u8", slice_u8_impl, Target::Impl;
133+
StrAllocImplItem, "str_alloc", str_alloc_impl, Target::Impl;
134+
SliceAllocImplItem, "slice_alloc", slice_alloc_impl, Target::Impl;
135+
SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl, Target::Impl;
136+
ConstPtrImplItem, "const_ptr", const_ptr_impl, Target::Impl;
137+
MutPtrImplItem, "mut_ptr", mut_ptr_impl, Target::Impl;
138+
I8ImplItem, "i8", i8_impl, Target::Impl;
139+
I16ImplItem, "i16", i16_impl, Target::Impl;
140+
I32ImplItem, "i32", i32_impl, Target::Impl;
141+
I64ImplItem, "i64", i64_impl, Target::Impl;
142+
I128ImplItem, "i128", i128_impl, Target::Impl;
143+
IsizeImplItem, "isize", isize_impl, Target::Impl;
144+
U8ImplItem, "u8", u8_impl, Target::Impl;
145+
U16ImplItem, "u16", u16_impl, Target::Impl;
146+
U32ImplItem, "u32", u32_impl, Target::Impl;
147+
U64ImplItem, "u64", u64_impl, Target::Impl;
148+
U128ImplItem, "u128", u128_impl, Target::Impl;
149+
UsizeImplItem, "usize", usize_impl, Target::Impl;
150+
F32ImplItem, "f32", f32_impl, Target::Impl;
151+
F64ImplItem, "f64", f64_impl, Target::Impl;
152+
F32RuntimeImplItem, "f32_runtime", f32_runtime_impl, Target::Impl;
153+
F64RuntimeImplItem, "f64_runtime", f64_runtime_impl, Target::Impl;
154+
155+
SizedTraitLangItem, "sized", sized_trait, Target::Trait;
156+
UnsizeTraitLangItem, "unsize", unsize_trait, Target::Trait;
157+
// trait injected by #[derive(PartialEq)], (i.e. "Partial EQ").
158+
StructuralPeqTraitLangItem, "structural_peq", structural_peq_trait, Target::Trait;
159+
// trait injected by #[derive(Eq)], (i.e. "Total EQ"; no, I will not apologize).
160+
StructuralTeqTraitLangItem, "structural_teq", structural_teq_trait, Target::Trait;
161+
CopyTraitLangItem, "copy", copy_trait, Target::Trait;
162+
CloneTraitLangItem, "clone", clone_trait, Target::Trait;
163+
SyncTraitLangItem, "sync", sync_trait, Target::Trait;
164+
FreezeTraitLangItem, "freeze", freeze_trait, Target::Trait;
165+
166+
DropTraitLangItem, "drop", drop_trait, Target::Trait;
167+
168+
CoerceUnsizedTraitLangItem, "coerce_unsized", coerce_unsized_trait, Target::Trait;
169+
DispatchFromDynTraitLangItem,"dispatch_from_dyn", dispatch_from_dyn_trait, Target::Trait;
170+
171+
AddTraitLangItem, "add", add_trait, Target::Trait;
172+
SubTraitLangItem, "sub", sub_trait, Target::Trait;
173+
MulTraitLangItem, "mul", mul_trait, Target::Trait;
174+
DivTraitLangItem, "div", div_trait, Target::Trait;
175+
RemTraitLangItem, "rem", rem_trait, Target::Trait;
176+
NegTraitLangItem, "neg", neg_trait, Target::Trait;
177+
NotTraitLangItem, "not", not_trait, Target::Trait;
178+
BitXorTraitLangItem, "bitxor", bitxor_trait, Target::Trait;
179+
BitAndTraitLangItem, "bitand", bitand_trait, Target::Trait;
180+
BitOrTraitLangItem, "bitor", bitor_trait, Target::Trait;
181+
ShlTraitLangItem, "shl", shl_trait, Target::Trait;
182+
ShrTraitLangItem, "shr", shr_trait, Target::Trait;
183+
AddAssignTraitLangItem, "add_assign", add_assign_trait, Target::Trait;
184+
SubAssignTraitLangItem, "sub_assign", sub_assign_trait, Target::Trait;
185+
MulAssignTraitLangItem, "mul_assign", mul_assign_trait, Target::Trait;
186+
DivAssignTraitLangItem, "div_assign", div_assign_trait, Target::Trait;
187+
RemAssignTraitLangItem, "rem_assign", rem_assign_trait, Target::Trait;
188+
BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait, Target::Trait;
189+
BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait, Target::Trait;
190+
BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait, Target::Trait;
191+
ShlAssignTraitLangItem, "shl_assign", shl_assign_trait, Target::Trait;
192+
ShrAssignTraitLangItem, "shr_assign", shr_assign_trait, Target::Trait;
193+
IndexTraitLangItem, "index", index_trait, Target::Trait;
194+
IndexMutTraitLangItem, "index_mut", index_mut_trait, Target::Trait;
195+
196+
UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type, Target::Struct;
197+
VaListTypeLangItem, "va_list", va_list, Target::Struct;
198+
199+
DerefTraitLangItem, "deref", deref_trait, Target::Trait;
200+
DerefMutTraitLangItem, "deref_mut", deref_mut_trait, Target::Trait;
201+
ReceiverTraitLangItem, "receiver", receiver_trait, Target::Trait;
202+
203+
FnTraitLangItem, "fn", fn_trait, Target::Trait;
204+
FnMutTraitLangItem, "fn_mut", fn_mut_trait, Target::Trait;
205+
FnOnceTraitLangItem, "fn_once", fn_once_trait, Target::Trait;
206+
207+
FutureTraitLangItem, "future_trait", future_trait, Target::Trait;
208+
GeneratorStateLangItem, "generator_state", gen_state, Target::Enum;
209+
GeneratorTraitLangItem, "generator", gen_trait, Target::Trait;
210+
UnpinTraitLangItem, "unpin", unpin_trait, Target::Trait;
211+
PinTypeLangItem, "pin", pin_type, Target::Struct;
212+
213+
// Don't be fooled by the naming here: this lang item denotes `PartialEq`, not `Eq`.
214+
EqTraitLangItem, "eq", eq_trait, Target::Trait;
215+
PartialOrdTraitLangItem, "partial_ord", partial_ord_trait, Target::Trait;
216+
217+
// A number of panic-related lang items. The `panic` item corresponds to
218+
// divide-by-zero and various panic cases with `match`. The
219+
// `panic_bounds_check` item is for indexing arrays.
220+
//
221+
// The `begin_unwind` lang item has a predefined symbol name and is sort of
222+
// a "weak lang item" in the sense that a crate is not required to have it
223+
// defined to use it, but a final product is required to define it
224+
// somewhere. Additionally, there are restrictions on crates that use a weak
225+
// lang item, but do not have it defined.
226+
PanicFnLangItem, "panic", panic_fn, Target::Fn;
227+
PanicBoundsCheckFnLangItem, "panic_bounds_check", panic_bounds_check_fn, Target::Fn;
228+
PanicInfoLangItem, "panic_info", panic_info, Target::Struct;
229+
PanicLocationLangItem, "panic_location", panic_location, Target::Struct;
230+
PanicImplLangItem, "panic_impl", panic_impl, Target::Fn;
231+
// Libstd panic entry point. Necessary for const eval to be able to catch it
232+
BeginPanicFnLangItem, "begin_panic", begin_panic_fn, Target::Fn;
233+
234+
ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn, Target::Fn;
235+
BoxFreeFnLangItem, "box_free", box_free_fn, Target::Fn;
236+
DropInPlaceFnLangItem, "drop_in_place", drop_in_place_fn, Target::Fn;
237+
OomLangItem, "oom", oom, Target::Fn;
238+
AllocLayoutLangItem, "alloc_layout", alloc_layout, Target::Struct;
239+
240+
StartFnLangItem, "start", start_fn, Target::Fn;
241+
242+
EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn;
243+
EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn;
244+
EhCatchTypeinfoLangItem, "eh_catch_typeinfo", eh_catch_typeinfo, Target::Static;
245+
246+
OwnedBoxLangItem, "owned_box", owned_box, Target::Struct;
247+
248+
PhantomDataItem, "phantom_data", phantom_data, Target::Struct;
249+
250+
ManuallyDropItem, "manually_drop", manually_drop, Target::Struct;
251+
252+
MaybeUninitLangItem, "maybe_uninit", maybe_uninit, Target::Union;
253+
254+
// Align offset for stride != 1; must not panic.
255+
AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn;
256+
257+
TerminationTraitLangItem, "termination", termination, Target::Trait;
258+
259+
Arc, "arc", arc, Target::Struct;
260+
Rc, "rc", rc, Target::Struct;
261+
}

src/librustc_lang_items/lib.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
macro_rules! enum_from_u32 {
2+
($(#[$attr:meta])* pub enum $name:ident {
3+
$($variant:ident = $e:expr,)*
4+
}) => {
5+
$(#[$attr])*
6+
pub enum $name {
7+
$($variant = $e),*
8+
}
9+
10+
impl $name {
11+
pub fn from_u32(u: u32) -> Option<$name> {
12+
$(if u == $name::$variant as u32 {
13+
return Some($name::$variant)
14+
})*
15+
None
16+
}
17+
}
18+
};
19+
($(#[$attr:meta])* pub enum $name:ident {
20+
$($variant:ident,)*
21+
}) => {
22+
$(#[$attr])*
23+
pub enum $name {
24+
$($variant,)*
25+
}
26+
27+
impl $name {
28+
pub fn from_u32(u: u32) -> Option<$name> {
29+
$(if u == $name::$variant as u32 {
30+
return Some($name::$variant)
31+
})*
32+
None
33+
}
34+
}
35+
}
36+
}
37+
38+
pub mod lang_items;
139
mod target;
240

41+
pub use lang_items::{LangItem, LanguageItems};
342
pub use target::{MethodKind, Target};
43+
44+
pub trait HashStableContext: rustc_hir::HashStableContext {}

src/librustc_mir/shim.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
4040
),
4141
ty::InstanceDef::FnPtrShim(def_id, ty) => {
4242
let trait_ = tcx.trait_of_item(def_id).unwrap();
43-
let adjustment = match tcx.lang_items().fn_trait_kind(trait_) {
43+
let adjustment = match tcx.fn_trait_lang_item(trait_) {
4444
Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
4545
Some(ty::ClosureKind::FnMut) | Some(ty::ClosureKind::Fn) => Adjustment::Deref,
4646
None => bug!("fn pointer {:?} is not an fn", ty),

0 commit comments

Comments
 (0)