diff options
Diffstat (limited to 'compiler/rustc_typeck/src/variance/mod.rs')
-rw-r--r-- | compiler/rustc_typeck/src/variance/mod.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/variance/mod.rs b/compiler/rustc_typeck/src/variance/mod.rs new file mode 100644 index 000000000..82103c5a0 --- /dev/null +++ b/compiler/rustc_typeck/src/variance/mod.rs @@ -0,0 +1,63 @@ +//! Module for inferring the variance of type and lifetime parameters. See the [rustc dev guide] +//! chapter for more info. +//! +//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html + +use rustc_arena::DroplessArena; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::DefId; +use rustc_middle::ty::query::Providers; +use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt}; + +/// Defines the `TermsContext` basically houses an arena where we can +/// allocate terms. +mod terms; + +/// Code to gather up constraints. +mod constraints; + +/// Code to solve constraints and write out the results. +mod solve; + +/// Code to write unit tests of variance. +pub mod test; + +/// Code for transforming variances. +mod xform; + +pub fn provide(providers: &mut Providers) { + *providers = Providers { variances_of, crate_variances, ..*providers }; +} + +fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> { + let arena = DroplessArena::default(); + let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &arena); + let constraints_cx = constraints::add_constraints_from_crate(terms_cx); + solve::solve_constraints(constraints_cx) +} + +fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { + // Skip items with no generics - there's nothing to infer in them. + if tcx.generics_of(item_def_id).count() == 0 { + return &[]; + } + + match tcx.def_kind(item_def_id) { + DefKind::Fn + | DefKind::AssocFn + | DefKind::Enum + | DefKind::Struct + | DefKind::Union + | DefKind::Variant + | DefKind::Ctor(..) => {} + _ => { + // Variance not relevant. + span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item") + } + } + + // Everything else must be inferred. + + let crate_map = tcx.crate_variances(()); + crate_map.variances.get(&item_def_id).copied().unwrap_or(&[]) +} |