rustc_hir_analysis/variance/
terms.rs1use std::fmt;
13
14use rustc_arena::DroplessArena;
15use rustc_hir::def::DefKind;
16use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
17use rustc_middle::ty::{self, TyCtxt};
18use tracing::debug;
19
20use self::VarianceTerm::*;
21
22pub(crate) type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
23
24#[derive(#[automatically_derived]
impl ::core::marker::Copy for InferredIndex { }Copy, #[automatically_derived]
impl ::core::clone::Clone for InferredIndex {
#[inline]
fn clone(&self) -> InferredIndex {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for InferredIndex {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "InferredIndex",
&&self.0)
}
}Debug)]
25pub(crate) struct InferredIndex(pub usize);
26
27#[derive(#[automatically_derived]
impl<'a> ::core::marker::Copy for VarianceTerm<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::clone::Clone for VarianceTerm<'a> {
#[inline]
fn clone(&self) -> VarianceTerm<'a> {
let _: ::core::clone::AssertParamIsClone<ty::Variance>;
let _: ::core::clone::AssertParamIsClone<VarianceTermPtr<'a>>;
let _: ::core::clone::AssertParamIsClone<VarianceTermPtr<'a>>;
let _: ::core::clone::AssertParamIsClone<InferredIndex>;
*self
}
}Clone)]
28pub(crate) enum VarianceTerm<'a> {
29 ConstantTerm(ty::Variance),
30 TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
31 InferredTerm(InferredIndex),
32}
33
34impl<'a> fmt::Debug for VarianceTerm<'a> {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match *self {
37 ConstantTerm(c1) => f.write_fmt(format_args!("{0:?}", c1))write!(f, "{c1:?}"),
38 TransformTerm(v1, v2) => f.write_fmt(format_args!("({0:?} × {1:?})", v1, v2))write!(f, "({v1:?} \u{00D7} {v2:?})"),
39 InferredTerm(id) => f.write_fmt(format_args!("[{0}]", { let InferredIndex(i) = id; i }))write!(f, "[{}]", {
40 let InferredIndex(i) = id;
41 i
42 }),
43 }
44 }
45}
46
47pub(crate) struct TermsContext<'a, 'tcx> {
50 pub tcx: TyCtxt<'tcx>,
51 pub arena: &'a DroplessArena,
52
53 pub lang_items: Vec<(LocalDefId, Vec<ty::Variance>)>,
57
58 pub inferred_starts: LocalDefIdMap<InferredIndex>,
61
62 pub inferred_terms: Vec<VarianceTermPtr<'a>>,
64}
65
66pub(crate) fn determine_parameters_to_be_inferred<'a, 'tcx>(
67 tcx: TyCtxt<'tcx>,
68 arena: &'a DroplessArena,
69) -> TermsContext<'a, 'tcx> {
70 let mut terms_cx = TermsContext {
71 tcx,
72 arena,
73 inferred_starts: Default::default(),
74 inferred_terms: ::alloc::vec::Vec::new()vec![],
75
76 lang_items: lang_items(tcx),
77 };
78
79 let crate_items = tcx.hir_crate_items(());
84
85 for def_id in crate_items.definitions() {
86 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/variance/terms.rs:86",
"rustc_hir_analysis::variance::terms",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/variance/terms.rs"),
::tracing_core::__macro_support::Option::Some(86u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::variance::terms"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("add_inferreds for item {0:?}",
def_id) as &dyn Value))])
});
} else { ; }
};debug!("add_inferreds for item {:?}", def_id);
87
88 let def_kind = tcx.def_kind(def_id);
89
90 match def_kind {
91 DefKind::Struct | DefKind::Union | DefKind::Enum => {
92 terms_cx.add_inferreds_for_item(def_id);
93
94 let adt = tcx.adt_def(def_id);
95 for variant in adt.variants() {
96 if let Some(ctor_def_id) = variant.ctor_def_id() {
97 terms_cx.add_inferreds_for_item(ctor_def_id.expect_local());
98 }
99 }
100 }
101 DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
102 DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
103 terms_cx.add_inferreds_for_item(def_id)
104 }
105 _ => {}
106 }
107 }
108
109 terms_cx
110}
111
112fn lang_items(tcx: TyCtxt<'_>) -> Vec<(LocalDefId, Vec<ty::Variance>)> {
113 let lang_items = tcx.lang_items();
114 let all = [
115 (lang_items.phantom_data(), <[_]>::into_vec(::alloc::boxed::box_new([ty::Covariant]))vec![ty::Covariant]),
116 (lang_items.unsafe_cell_type(), <[_]>::into_vec(::alloc::boxed::box_new([ty::Invariant]))vec![ty::Invariant]),
117 ];
118
119 all.into_iter() .filter_map(|(d, v)| {
121 let def_id = d?.as_local()?; Some((def_id, v))
123 })
124 .collect()
125}
126
127impl<'a, 'tcx> TermsContext<'a, 'tcx> {
128 fn add_inferreds_for_item(&mut self, def_id: LocalDefId) {
129 let tcx = self.tcx;
130 let count = tcx.generics_of(def_id).count();
131
132 if count == 0 {
133 return;
134 }
135
136 let start = self.inferred_terms.len();
138 let newly_added = self.inferred_starts.insert(def_id, InferredIndex(start)).is_none();
139 if !newly_added { ::core::panicking::panic("assertion failed: newly_added") };assert!(newly_added);
140
141 let arena = self.arena;
146 self.inferred_terms.extend(
147 (start..(start + count)).map(|i| &*arena.alloc(InferredTerm(InferredIndex(i)))),
148 );
149 }
150}