]> git.proxmox.com Git - rustc.git/blob - src/librustc_typeck/variance/mod.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / librustc_typeck / variance / mod.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Module for inferring the variance of type and lifetime
12 //! parameters. See README.md for details.
13
14 use arena;
15 use rustc::dep_graph::DepKind;
16 use rustc::hir;
17 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
18 use rustc::ty::{self, CrateVariancesMap, TyCtxt};
19 use rustc::ty::maps::Providers;
20 use std::rc::Rc;
21
22 /// Defines the `TermsContext` basically houses an arena where we can
23 /// allocate terms.
24 mod terms;
25
26 /// Code to gather up constraints.
27 mod constraints;
28
29 /// Code to solve constraints and write out the results.
30 mod solve;
31
32 /// Code to write unit tests of variance.
33 pub mod test;
34
35 /// Code for transforming variances.
36 mod xform;
37
38 pub fn provide(providers: &mut Providers) {
39 *providers = Providers {
40 variances_of,
41 crate_variances,
42 ..*providers
43 };
44 }
45
46 fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
47 -> Rc<CrateVariancesMap> {
48 assert_eq!(crate_num, LOCAL_CRATE);
49 let mut arena = arena::TypedArena::new();
50 let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena);
51 let constraints_cx = constraints::add_constraints_from_crate(terms_cx);
52 Rc::new(solve::solve_constraints(constraints_cx))
53 }
54
55 fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
56 -> Rc<Vec<ty::Variance>> {
57 let id = tcx.hir.as_local_node_id(item_def_id).expect("expected local def-id");
58 let unsupported = || {
59 // Variance not relevant.
60 span_bug!(tcx.hir.span(id), "asked to compute variance for wrong kind of item")
61 };
62 match tcx.hir.get(id) {
63 hir::map::NodeItem(item) => match item.node {
64 hir::ItemEnum(..) |
65 hir::ItemStruct(..) |
66 hir::ItemUnion(..) |
67 hir::ItemFn(..) => {}
68
69 _ => unsupported()
70 },
71
72 hir::map::NodeTraitItem(item) => match item.node {
73 hir::TraitItemKind::Method(..) => {}
74
75 _ => unsupported()
76 },
77
78 hir::map::NodeImplItem(item) => match item.node {
79 hir::ImplItemKind::Method(..) => {}
80
81 _ => unsupported()
82 },
83
84 hir::map::NodeForeignItem(item) => match item.node {
85 hir::ForeignItemFn(..) => {}
86
87 _ => unsupported()
88 },
89
90 hir::map::NodeVariant(_) | hir::map::NodeStructCtor(_) => {}
91
92 _ => unsupported()
93 }
94
95 // Everything else must be inferred.
96
97 let crate_map = tcx.crate_variances(LOCAL_CRATE);
98 let dep_node = item_def_id.to_dep_node(tcx, DepKind::ItemVarianceConstraints);
99 tcx.dep_graph.read(dep_node);
100
101 crate_map.variances.get(&item_def_id)
102 .unwrap_or(&crate_map.empty_variance)
103 .clone()
104 }
105