Improve LanguageItems api
This commit is contained in:
parent
5e97720429
commit
99de57ae13
3 changed files with 43 additions and 28 deletions
|
@ -36,6 +36,44 @@ macro_rules! expand_group {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// All of the language items, defined or not.
|
||||||
|
/// Defined lang items can come from the current crate or its dependencies.
|
||||||
|
#[derive(HashStable_Generic, Debug)]
|
||||||
|
pub struct LanguageItems {
|
||||||
|
/// Mappings from lang items to their possibly found [`DefId`]s.
|
||||||
|
/// The index corresponds to the order in [`LangItem`].
|
||||||
|
pub items: Vec<Option<DefId>>,
|
||||||
|
/// Lang items that were not found during collection.
|
||||||
|
pub missing: Vec<LangItem>,
|
||||||
|
/// Mapping from [`LangItemGroup`] discriminants to all
|
||||||
|
/// [`DefId`]s of lang items in that group.
|
||||||
|
pub groups: [Vec<DefId>; NUM_GROUPS],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LanguageItems {
|
||||||
|
pub fn get(&self, item: LangItem) -> Option<DefId> {
|
||||||
|
self.items[item as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, item: LangItem, def_id: DefId) {
|
||||||
|
self.items[item as usize] = Some(def_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
|
||||||
|
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
|
||||||
|
/// returns an error encapsulating the `LangItem`.
|
||||||
|
pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
|
||||||
|
self.get(it).ok_or_else(|| LangItemError(it))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter<'a>(&'a self) -> impl Iterator<Item = (LangItem, DefId)> + 'a {
|
||||||
|
self.items
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(i, id)| id.map(|id| (LangItem::from_u32(i as u32).unwrap(), id)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The actual lang items defined come at the end of this file in one handy table.
|
// The actual lang items defined come at the end of this file in one handy table.
|
||||||
// So you probably just want to nip down to the end.
|
// So you probably just want to nip down to the end.
|
||||||
macro_rules! language_item_table {
|
macro_rules! language_item_table {
|
||||||
|
@ -82,20 +120,6 @@ macro_rules! language_item_table {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// All of the language items, defined or not.
|
|
||||||
/// Defined lang items can come from the current crate or its dependencies.
|
|
||||||
#[derive(HashStable_Generic, Debug)]
|
|
||||||
pub struct LanguageItems {
|
|
||||||
/// Mappings from lang items to their possibly found [`DefId`]s.
|
|
||||||
/// The index corresponds to the order in [`LangItem`].
|
|
||||||
pub items: Vec<Option<DefId>>,
|
|
||||||
/// Lang items that were not found during collection.
|
|
||||||
pub missing: Vec<LangItem>,
|
|
||||||
/// Mapping from [`LangItemGroup`] discriminants to all
|
|
||||||
/// [`DefId`]s of lang items in that group.
|
|
||||||
pub groups: [Vec<DefId>; NUM_GROUPS],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LanguageItems {
|
impl LanguageItems {
|
||||||
/// Construct an empty collection of lang items and no missing ones.
|
/// Construct an empty collection of lang items and no missing ones.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -114,13 +138,6 @@ macro_rules! language_item_table {
|
||||||
&*self.items
|
&*self.items
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
|
|
||||||
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
|
|
||||||
/// returns an error encapsulating the `LangItem`.
|
|
||||||
pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
|
|
||||||
self.items[it as usize].ok_or_else(|| LangItemError(it))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the [`DefId`]s of all lang items in a group.
|
/// Returns the [`DefId`]s of all lang items in a group.
|
||||||
pub fn group(&self, group: LangItemGroup) -> &[DefId] {
|
pub fn group(&self, group: LangItemGroup) -> &[DefId] {
|
||||||
self.groups[group as usize].as_ref()
|
self.groups[group as usize].as_ref()
|
||||||
|
|
|
@ -380,13 +380,11 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for item in tcx.lang_items().items().iter() {
|
for (_, def_id) in tcx.lang_items().iter() {
|
||||||
if let Some(def_id) = *item {
|
|
||||||
if let Some(def_id) = def_id.as_local() {
|
if let Some(def_id) = def_id.as_local() {
|
||||||
reachable_context.worklist.push(def_id);
|
reachable_context.worklist.push(def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
{
|
{
|
||||||
// Some methods from non-exported (completely private) trait impls still have to be
|
// Some methods from non-exported (completely private) trait impls still have to be
|
||||||
// reachable if they are called from inlinable code. Generally, it's not known until
|
// reachable if they are called from inlinable code. Generally, it's not known until
|
||||||
|
|
|
@ -974,7 +974,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
// useful for less general traits.
|
// useful for less general traits.
|
||||||
if peeled
|
if peeled
|
||||||
&& !self.tcx.trait_is_auto(def_id)
|
&& !self.tcx.trait_is_auto(def_id)
|
||||||
&& !self.tcx.lang_items().items().contains(&Some(def_id))
|
&& !self.tcx.lang_items().iter().any(|(_, id)| id == def_id)
|
||||||
{
|
{
|
||||||
let trait_ref = trait_pred.to_poly_trait_ref();
|
let trait_ref = trait_pred.to_poly_trait_ref();
|
||||||
let impl_candidates =
|
let impl_candidates =
|
||||||
|
@ -1898,7 +1898,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
let def_id = trait_ref.def_id();
|
let def_id = trait_ref.def_id();
|
||||||
if impl_candidates.is_empty() {
|
if impl_candidates.is_empty() {
|
||||||
if self.tcx.trait_is_auto(def_id)
|
if self.tcx.trait_is_auto(def_id)
|
||||||
|| self.tcx.lang_items().items().contains(&Some(def_id))
|
|| self.tcx.lang_items().iter().any(|(_, id)| id == def_id)
|
||||||
|| self.tcx.get_diagnostic_name(def_id).is_some()
|
|| self.tcx.get_diagnostic_name(def_id).is_some()
|
||||||
{
|
{
|
||||||
// Mentioning implementers of `Copy`, `Debug` and friends is not useful.
|
// Mentioning implementers of `Copy`, `Debug` and friends is not useful.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue