about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src/variance/mod.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-27 10:45:57 +0000
committerbors <bors@rust-lang.org>2022-09-27 10:45:57 +0000
commit57ee5cf5a93923dae9c98bffb11545fc3a31368d (patch)
treeabd98065e805dca388767b651ae60673397fea9d /compiler/rustc_hir_analysis/src/variance/mod.rs
parentd9297d22ad9edc2b56f0dd8734c1187a0c88be69 (diff)
parent1fc86a63f451b81606e4787692517dc613f333db (diff)
downloadrust-57ee5cf5a93923dae9c98bffb11545fc3a31368d.tar.gz
rust-57ee5cf5a93923dae9c98bffb11545fc3a31368d.zip
Auto merge of #102306 - lcnr:rustc_hir_analysis, r=compiler-errors
rename rustc_typeck to rustc_hir_analysis

first part of https://github.com/rust-lang/compiler-team/issues/529

r? `@compiler-errors`
Diffstat (limited to 'compiler/rustc_hir_analysis/src/variance/mod.rs')
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs63
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
new file mode 100644
index 00000000000..82103c5a03b
--- /dev/null
+++ b/compiler/rustc_hir_analysis/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(&[])
+}