rustc_hir_analysis/variance/
dump.rs1use std::fmt::Write;
2
3use rustc_hir::attrs::AttributeKind;
4use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
5use rustc_hir::find_attr;
6use rustc_middle::ty::{GenericArgs, TyCtxt};
7
8fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
9 let variances = tcx.variances_of(def_id);
10 let generics = GenericArgs::identity_for_item(tcx, def_id);
11 let mut ret = String::with_capacity(2 + 7 * variances.len());
13 ret.push('[');
14 for (arg, variance) in generics.iter().zip(variances.iter()) {
15 ret.write_fmt(format_args!("{0}: {1:?}, ", arg, variance))write!(ret, "{arg}: {variance:?}, ").unwrap();
16 }
17 if !variances.is_empty() {
19 ret.pop();
20 ret.pop();
21 }
22 ret.push(']');
23 ret
24}
25
26pub(crate) fn variances(tcx: TyCtxt<'_>) {
27 let crate_items = tcx.hir_crate_items(());
28
29 if {
{
'done:
{
for i in tcx.get_all_attrs(CRATE_DEF_ID) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcVarianceOfOpaques)
=> {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcVarianceOfOpaques) {
30 for id in crate_items.opaques() {
31 tcx.dcx().emit_err(crate::errors::VariancesOf {
32 span: tcx.def_span(id),
33 variances: format_variances(tcx, id),
34 });
35 }
36 }
37
38 for id in crate_items.free_items() {
39 if !{
{
'done:
{
for i in tcx.get_all_attrs(id.owner_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcVariance)
=> {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(tcx.get_all_attrs(id.owner_id), AttributeKind::RustcVariance) {
40 continue;
41 }
42
43 tcx.dcx().emit_err(crate::errors::VariancesOf {
44 span: tcx.def_span(id.owner_id),
45 variances: format_variances(tcx, id.owner_id.def_id),
46 });
47 }
48}