]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | //! Module for inferring the variance of type and lifetime parameters. See the [rustc dev guide] |
0531ce1d XL |
2 | //! chapter for more info. |
3 | //! | |
ba9703b0 | 4 | //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html |
7453a54e | 5 | |
b7449926 | 6 | use hir::Node; |
dfeec247 XL |
7 | use rustc_hir as hir; |
8 | use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; | |
ba9703b0 XL |
9 | use rustc_middle::ty::query::Providers; |
10 | use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt}; | |
7453a54e SL |
11 | |
12 | /// Defines the `TermsContext` basically houses an arena where we can | |
13 | /// allocate terms. | |
14 | mod terms; | |
15 | ||
16 | /// Code to gather up constraints. | |
17 | mod constraints; | |
18 | ||
19 | /// Code to solve constraints and write out the results. | |
20 | mod solve; | |
21 | ||
7cac9316 XL |
22 | /// Code to write unit tests of variance. |
23 | pub mod test; | |
24 | ||
7453a54e SL |
25 | /// Code for transforming variances. |
26 | mod xform; | |
27 | ||
9fa01778 | 28 | pub fn provide(providers: &mut Providers<'_>) { |
dfeec247 | 29 | *providers = Providers { variances_of, crate_variances, ..*providers }; |
7cac9316 XL |
30 | } |
31 | ||
416331ca | 32 | fn crate_variances(tcx: TyCtxt<'_>, crate_num: CrateNum) -> &CrateVariancesMap<'_> { |
7cac9316 | 33 | assert_eq!(crate_num, LOCAL_CRATE); |
0bf4aa26 | 34 | let mut arena = arena::TypedArena::default(); |
7453a54e SL |
35 | let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena); |
36 | let constraints_cx = constraints::add_constraints_from_crate(terms_cx); | |
dc9dc135 | 37 | tcx.arena.alloc(solve::solve_constraints(constraints_cx)) |
7cac9316 XL |
38 | } |
39 | ||
416331ca | 40 | fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { |
9fa01778 | 41 | let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id"); |
041b39d2 XL |
42 | let unsupported = || { |
43 | // Variance not relevant. | |
dc9dc135 | 44 | span_bug!(tcx.hir().span(id), "asked to compute variance for wrong kind of item") |
041b39d2 | 45 | }; |
dc9dc135 | 46 | match tcx.hir().get(id) { |
e74abb32 | 47 | Node::Item(item) => match item.kind { |
dfeec247 XL |
48 | hir::ItemKind::Enum(..) |
49 | | hir::ItemKind::Struct(..) | |
50 | | hir::ItemKind::Union(..) | |
51 | | hir::ItemKind::Fn(..) => {} | |
7cac9316 | 52 | |
dfeec247 | 53 | _ => unsupported(), |
041b39d2 XL |
54 | }, |
55 | ||
e74abb32 | 56 | Node::TraitItem(item) => match item.kind { |
ba9703b0 | 57 | hir::TraitItemKind::Fn(..) => {} |
041b39d2 | 58 | |
dfeec247 | 59 | _ => unsupported(), |
041b39d2 XL |
60 | }, |
61 | ||
e74abb32 | 62 | Node::ImplItem(item) => match item.kind { |
ba9703b0 | 63 | hir::ImplItemKind::Fn(..) => {} |
041b39d2 | 64 | |
dfeec247 | 65 | _ => unsupported(), |
041b39d2 | 66 | }, |
7cac9316 | 67 | |
e74abb32 | 68 | Node::ForeignItem(item) => match item.kind { |
8faf50e0 | 69 | hir::ForeignItemKind::Fn(..) => {} |
041b39d2 | 70 | |
dfeec247 | 71 | _ => unsupported(), |
041b39d2 XL |
72 | }, |
73 | ||
532ac7d7 | 74 | Node::Variant(_) | Node::Ctor(..) => {} |
041b39d2 | 75 | |
dfeec247 | 76 | _ => unsupported(), |
041b39d2 XL |
77 | } |
78 | ||
79 | // Everything else must be inferred. | |
80 | ||
abe05a73 | 81 | let crate_map = tcx.crate_variances(LOCAL_CRATE); |
74b04a01 | 82 | crate_map.variances.get(&item_def_id).copied().unwrap_or(&[]) |
7453a54e | 83 | } |