use alloc::borrow::ToOwned;
use alloc::boxed::Box;
use alloc::format;
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use crate::rustc_hir::def::DefKind;
use crate::rustc_hir::def_id::LocalDefId;
use crate::rustc_middle::ty::{self, CrateClausesMap, GenericArgKind, TyCtxt, Upcast};
use crate::rustc_span::Span;
pub(crate) mod dump;
mod explicit;
mod implicit_infer;
mod utils;
pub(super) fn inferred_outlives_of(
tcx: TyCtxt<'_>,
item_def_id: LocalDefId,
) -> &[(ty::Clause<'_>, Span)] {
match tcx.def_kind(item_def_id) {
DefKind::Struct | DefKind::Enum | DefKind::Union => {
let crate_map = tcx.inferred_outlives_crate(());
crate_map.clauses.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
}
DefKind::TyAlias if tcx.type_alias_is_checked(item_def_id) => {
let crate_map = tcx.inferred_outlives_crate(());
crate_map.clauses.get(&item_def_id.to_def_id()).copied().unwrap_or(&[])
}
DefKind::AnonConst if tcx.features().generic_const_exprs() => {
let id = tcx.local_def_id_to_hir_id(item_def_id);
if tcx.hir_opt_const_param_default_param_def_id(id).is_some() {
let item_def_id = tcx.hir_get_parent_item(id);
tcx.inferred_outlives_of(item_def_id)
} else {
&[]
}
}
_ => &[],
}
}
pub(super) fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CrateClausesMap<'_> {
let global_inferred_outlives = implicit_infer::infer_clauses(tcx);
let clauses = global_inferred_outlives
.iter()
.map(|(&def_id, set)| {
let clauses =
&*tcx.arena.alloc_from_iter(set.as_ref().skip_binder().iter().filter_map(
|(ty::OutlivesClause(arg1, region2), &span)| {
match arg1.kind() {
GenericArgKind::Type(ty1) => Some((
ty::ClauseKind::TypeOutlives(ty::OutlivesClause(ty1, *region2))
.upcast(tcx),
span,
)),
GenericArgKind::Lifetime(region1) => Some((
ty::ClauseKind::RegionOutlives(ty::OutlivesClause(
region1, *region2,
))
.upcast(tcx),
span,
)),
GenericArgKind::Const(_) => {
None
}
}
},
));
(def_id, clauses)
})
.collect();
ty::CrateClausesMap { clauses }
}