Skip to main content

rustc_hir_analysis/variance/
dump.rs

1use std::fmt::Write;
2
3use rustc_hir::def_id::LocalDefId;
4use rustc_hir::find_attr;
5use rustc_middle::ty::{GenericArgs, TyCtxt};
6
7fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
8    let variances = tcx.variances_of(def_id);
9    let generics = GenericArgs::identity_for_item(tcx, def_id);
10    // 7 = 2-letter parameter + ": " + 1-letter variance + ", "
11    let mut ret = String::with_capacity(2 + 7 * variances.len());
12    ret.push('[');
13    for (arg, variance) in generics.iter().zip(variances.iter()) {
14        ret.write_fmt(format_args!("{0}: {1:?}, ", arg, variance))write!(ret, "{arg}: {variance:?}, ").unwrap();
15    }
16    // Remove trailing `, `.
17    if !variances.is_empty() {
18        ret.pop();
19        ret.pop();
20    }
21    ret.push(']');
22    ret
23}
24
25pub(crate) fn variances(tcx: TyCtxt<'_>) {
26    let crate_items = tcx.hir_crate_items(());
27
28    if {
        'done:
            {
            for i in tcx.hir_krate_attrs() {
                #[allow(unused_imports)]
                use rustc_hir::attrs::AttributeKind::*;
                let i: &rustc_hir::Attribute = i;
                match i {
                    rustc_hir::Attribute::Parsed(RustcVarianceOfOpaques) => {
                        break 'done Some(());
                    }
                    rustc_hir::Attribute::Unparsed(..) =>
                        {}
                        #[deny(unreachable_patterns)]
                        _ => {}
                }
            }
            None
        }
    }.is_some()find_attr!(tcx, crate, RustcVarianceOfOpaques) {
29        for id in crate_items.opaques() {
30            tcx.dcx().emit_err(crate::errors::VariancesOf {
31                span: tcx.def_span(id),
32                variances: format_variances(tcx, id),
33            });
34        }
35    }
36
37    for id in crate_items.free_items() {
38        if !{

        #[allow(deprecated)]
        {
            {
                'done:
                    {
                    for i in tcx.get_all_attrs(id.owner_id) {
                        #[allow(unused_imports)]
                        use rustc_hir::attrs::AttributeKind::*;
                        let i: &rustc_hir::Attribute = i;
                        match i {
                            rustc_hir::Attribute::Parsed(RustcVariance) => {
                                break 'done Some(());
                            }
                            rustc_hir::Attribute::Unparsed(..) =>
                                {}
                                #[deny(unreachable_patterns)]
                                _ => {}
                        }
                    }
                    None
                }
            }
        }
    }.is_some()find_attr!(tcx, id.owner_id, RustcVariance) {
39            continue;
40        }
41
42        tcx.dcx().emit_err(crate::errors::VariancesOf {
43            span: tcx.def_span(id.owner_id),
44            variances: format_variances(tcx, id.owner_id.def_id),
45        });
46    }
47}