]> git.proxmox.com Git - rustc.git/blame - src/librustc/ty/fast_reject.rs
New upstream version 1.25.0+dfsg1
[rustc.git] / src / librustc / ty / fast_reject.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 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
54a0048b 11use hir::def_id::DefId;
ea8adc8c
XL
12use ich::StableHashingContext;
13use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
14 HashStable};
15use std::fmt::Debug;
16use std::hash::Hash;
17use std::mem;
b039eaaf 18use syntax::ast;
ea8adc8c 19use ty::{self, Ty, TyCtxt};
1a4d82fc 20
ea8adc8c 21use self::SimplifiedTypeGen::*;
1a4d82fc 22
ea8adc8c
XL
23pub type SimplifiedType = SimplifiedTypeGen<DefId>;
24
25/// See `simplify_type`
26///
27/// Note that we keep this type generic over the type of identifier it uses
28/// because we sometimes need to use SimplifiedTypeGen values as stable sorting
29/// keys (in which case we use a DefPathHash as id-type) but in the general case
30/// the non-stable but fast to construct DefId-version is the better choice.
31#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
32pub enum SimplifiedTypeGen<D>
33 where D: Copy + Debug + Ord + Eq + Hash
34{
1a4d82fc
JJ
35 BoolSimplifiedType,
36 CharSimplifiedType,
b039eaaf
SL
37 IntSimplifiedType(ast::IntTy),
38 UintSimplifiedType(ast::UintTy),
39 FloatSimplifiedType(ast::FloatTy),
ea8adc8c 40 AdtSimplifiedType(D),
1a4d82fc 41 StrSimplifiedType,
c30ab7b3 42 ArraySimplifiedType,
1a4d82fc 43 PtrSimplifiedType,
5bcae85e 44 NeverSimplifiedType,
c34b1796 45 TupleSimplifiedType(usize),
ea8adc8c
XL
46 TraitSimplifiedType(D),
47 ClosureSimplifiedType(D),
48 GeneratorSimplifiedType(D),
2c00a5a8 49 GeneratorWitnessSimplifiedType(usize),
ea8adc8c 50 AnonSimplifiedType(D),
c34b1796 51 FunctionSimplifiedType(usize),
1a4d82fc 52 ParameterSimplifiedType,
abe05a73 53 ForeignSimplifiedType(DefId),
1a4d82fc
JJ
54}
55
56/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
57/// The idea is to get something simple that we can use to quickly decide if two types could unify
58/// during method lookup.
59///
60/// If `can_simplify_params` is false, then we will fail to simplify type parameters entirely. This
61/// is useful when those type parameters would be instantiated with fresh type variables, since
62/// then we can't say much about whether two types would unify. Put another way,
63/// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
64/// are to be considered bound.
a7813a04
XL
65pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
66 ty: Ty,
67 can_simplify_params: bool)
68 -> Option<SimplifiedType>
1a4d82fc
JJ
69{
70 match ty.sty {
62682a34
SL
71 ty::TyBool => Some(BoolSimplifiedType),
72 ty::TyChar => Some(CharSimplifiedType),
73 ty::TyInt(int_type) => Some(IntSimplifiedType(int_type)),
74 ty::TyUint(uint_type) => Some(UintSimplifiedType(uint_type)),
75 ty::TyFloat(float_type) => Some(FloatSimplifiedType(float_type)),
9e0c209e 76 ty::TyAdt(def, _) => Some(AdtSimplifiedType(def.did)),
62682a34 77 ty::TyStr => Some(StrSimplifiedType),
c30ab7b3 78 ty::TyArray(..) | ty::TySlice(_) => Some(ArraySimplifiedType),
62682a34 79 ty::TyRawPtr(_) => Some(PtrSimplifiedType),
476ff2be
SL
80 ty::TyDynamic(ref trait_info, ..) => {
81 trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
1a4d82fc 82 }
62682a34 83 ty::TyRef(_, mt) => {
1a4d82fc
JJ
84 // since we introduce auto-refs during method lookup, we
85 // just treat &T and T as equivalent from the point of
86 // view of possibly unifying
87 simplify_type(tcx, mt.ty, can_simplify_params)
88 }
041b39d2 89 ty::TyFnDef(def_id, _) |
62682a34 90 ty::TyClosure(def_id, _) => {
85aaf69f 91 Some(ClosureSimplifiedType(def_id))
1a4d82fc 92 }
ea8adc8c
XL
93 ty::TyGenerator(def_id, _, _) => {
94 Some(GeneratorSimplifiedType(def_id))
95 }
2c00a5a8
XL
96 ty::TyGeneratorWitness(ref tys) => {
97 Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len()))
98 }
5bcae85e 99 ty::TyNever => Some(NeverSimplifiedType),
8bb4bdeb 100 ty::TyTuple(ref tys, _) => {
1a4d82fc
JJ
101 Some(TupleSimplifiedType(tys.len()))
102 }
041b39d2 103 ty::TyFnPtr(ref f) => {
8bb4bdeb 104 Some(FunctionSimplifiedType(f.skip_binder().inputs().len()))
1a4d82fc 105 }
e9174d1e 106 ty::TyProjection(_) | ty::TyParam(_) => {
1a4d82fc 107 if can_simplify_params {
e9174d1e
SL
108 // In normalized types, projections don't unify with
109 // anything. when lazy normalization happens, this
110 // will change. It would still be nice to have a way
111 // to deal with known-not-to-unify-with-anything
112 // projections (e.g. the likes of <__S as Encoder>::Error).
1a4d82fc
JJ
113 Some(ParameterSimplifiedType)
114 } else {
115 None
116 }
117 }
5bcae85e
SL
118 ty::TyAnon(def_id, _) => {
119 Some(AnonSimplifiedType(def_id))
120 }
abe05a73
XL
121 ty::TyForeign(def_id) => {
122 Some(ForeignSimplifiedType(def_id))
123 }
62682a34 124 ty::TyInfer(_) | ty::TyError => None,
1a4d82fc
JJ
125 }
126}
ea8adc8c
XL
127
128impl<D: Copy + Debug + Ord + Eq + Hash> SimplifiedTypeGen<D> {
129 pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U>
130 where F: Fn(D) -> U,
131 U: Copy + Debug + Ord + Eq + Hash,
132 {
133 match self {
134 BoolSimplifiedType => BoolSimplifiedType,
135 CharSimplifiedType => CharSimplifiedType,
136 IntSimplifiedType(t) => IntSimplifiedType(t),
137 UintSimplifiedType(t) => UintSimplifiedType(t),
138 FloatSimplifiedType(t) => FloatSimplifiedType(t),
139 AdtSimplifiedType(d) => AdtSimplifiedType(map(d)),
140 StrSimplifiedType => StrSimplifiedType,
141 ArraySimplifiedType => ArraySimplifiedType,
142 PtrSimplifiedType => PtrSimplifiedType,
143 NeverSimplifiedType => NeverSimplifiedType,
144 TupleSimplifiedType(n) => TupleSimplifiedType(n),
145 TraitSimplifiedType(d) => TraitSimplifiedType(map(d)),
146 ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)),
147 GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)),
2c00a5a8 148 GeneratorWitnessSimplifiedType(n) => GeneratorWitnessSimplifiedType(n),
ea8adc8c
XL
149 AnonSimplifiedType(d) => AnonSimplifiedType(map(d)),
150 FunctionSimplifiedType(n) => FunctionSimplifiedType(n),
151 ParameterSimplifiedType => ParameterSimplifiedType,
abe05a73 152 ForeignSimplifiedType(d) => ForeignSimplifiedType(d),
ea8adc8c
XL
153 }
154 }
155}
156
157impl<'gcx, D> HashStable<StableHashingContext<'gcx>> for SimplifiedTypeGen<D>
158 where D: Copy + Debug + Ord + Eq + Hash +
159 HashStable<StableHashingContext<'gcx>>,
160{
161 fn hash_stable<W: StableHasherResult>(&self,
162 hcx: &mut StableHashingContext<'gcx>,
163 hasher: &mut StableHasher<W>) {
164 mem::discriminant(self).hash_stable(hcx, hasher);
165 match *self {
166 BoolSimplifiedType |
167 CharSimplifiedType |
168 StrSimplifiedType |
169 ArraySimplifiedType |
170 PtrSimplifiedType |
171 NeverSimplifiedType |
172 ParameterSimplifiedType => {
173 // nothing to do
174 }
175 IntSimplifiedType(t) => t.hash_stable(hcx, hasher),
176 UintSimplifiedType(t) => t.hash_stable(hcx, hasher),
177 FloatSimplifiedType(t) => t.hash_stable(hcx, hasher),
178 AdtSimplifiedType(d) => d.hash_stable(hcx, hasher),
179 TupleSimplifiedType(n) => n.hash_stable(hcx, hasher),
180 TraitSimplifiedType(d) => d.hash_stable(hcx, hasher),
181 ClosureSimplifiedType(d) => d.hash_stable(hcx, hasher),
182 GeneratorSimplifiedType(d) => d.hash_stable(hcx, hasher),
2c00a5a8 183 GeneratorWitnessSimplifiedType(n) => n.hash_stable(hcx, hasher),
ea8adc8c
XL
184 AnonSimplifiedType(d) => d.hash_stable(hcx, hasher),
185 FunctionSimplifiedType(n) => n.hash_stable(hcx, hasher),
abe05a73 186 ForeignSimplifiedType(d) => d.hash_stable(hcx, hasher),
ea8adc8c
XL
187 }
188 }
189}