1
+ use crate :: mir:: Mutability ;
1
2
use crate :: ty:: { self , Ty , TyCtxt } ;
2
3
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
3
4
use rustc_hir:: def_id:: DefId ;
27
28
UintSimplifiedType ( ty:: UintTy ) ,
28
29
FloatSimplifiedType ( ty:: FloatTy ) ,
29
30
AdtSimplifiedType ( D ) ,
31
+ ForeignSimplifiedType ( DefId ) ,
30
32
StrSimplifiedType ,
31
33
ArraySimplifiedType ,
32
- PtrSimplifiedType ,
34
+ SliceSimplifiedType ,
35
+ RefSimplifiedType ( Mutability ) ,
36
+ PtrSimplifiedType ( Mutability ) ,
33
37
NeverSimplifiedType ,
34
38
TupleSimplifiedType ( usize ) ,
35
39
/// A trait object, all of whose components are markers
42
46
OpaqueSimplifiedType ( D ) ,
43
47
FunctionSimplifiedType ( usize ) ,
44
48
ParameterSimplifiedType ,
45
- ForeignSimplifiedType ( DefId ) ,
49
+ }
50
+
51
+ #[ derive( PartialEq , Eq , Debug , Clone , Copy ) ]
52
+ pub enum SimplifyParams {
53
+ Yes ,
54
+ No ,
55
+ }
56
+
57
+ #[ derive( PartialEq , Eq , Debug , Clone , Copy ) ]
58
+ pub enum StripReferences {
59
+ Yes ,
60
+ No ,
46
61
}
47
62
48
63
/// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
57
72
pub fn simplify_type (
58
73
tcx : TyCtxt < ' _ > ,
59
74
ty : Ty < ' _ > ,
60
- can_simplify_params : bool ,
75
+ can_simplify_params : SimplifyParams ,
76
+ strip_references : StripReferences ,
61
77
) -> Option < SimplifiedType > {
62
78
match * ty. kind ( ) {
63
79
ty:: Bool => Some ( BoolSimplifiedType ) ,
@@ -67,19 +83,24 @@ pub fn simplify_type(
67
83
ty:: Float ( float_type) => Some ( FloatSimplifiedType ( float_type) ) ,
68
84
ty:: Adt ( def, _) => Some ( AdtSimplifiedType ( def. did ) ) ,
69
85
ty:: Str => Some ( StrSimplifiedType ) ,
70
- ty:: Array ( ..) | ty:: Slice ( _) => Some ( ArraySimplifiedType ) ,
71
- ty:: RawPtr ( _) => Some ( PtrSimplifiedType ) ,
86
+ ty:: Array ( ..) => Some ( ArraySimplifiedType ) ,
87
+ ty:: Slice ( ..) => Some ( SliceSimplifiedType ) ,
88
+ ty:: RawPtr ( ptr) => Some ( PtrSimplifiedType ( ptr. mutbl ) ) ,
72
89
ty:: Dynamic ( ref trait_info, ..) => match trait_info. principal_def_id ( ) {
73
90
Some ( principal_def_id) if !tcx. trait_is_auto ( principal_def_id) => {
74
91
Some ( TraitSimplifiedType ( principal_def_id) )
75
92
}
76
93
_ => Some ( MarkerTraitObjectSimplifiedType ) ,
77
94
} ,
78
- ty:: Ref ( _, ty, _) => {
79
- // since we introduce auto-refs during method lookup, we
80
- // just treat &T and T as equivalent from the point of
81
- // view of possibly unifying
82
- simplify_type ( tcx, ty, can_simplify_params)
95
+ ty:: Ref ( _, ty, mutbl) => {
96
+ if strip_references == StripReferences :: Yes {
97
+ // For diagnostics, when recommending similar impls we want to
98
+ // recommend impls even when there is a reference mismatch,
99
+ // so we treat &T and T equivalently in that case.
100
+ simplify_type ( tcx, ty, can_simplify_params, strip_references)
101
+ } else {
102
+ Some ( RefSimplifiedType ( mutbl) )
103
+ }
83
104
}
84
105
ty:: FnDef ( def_id, _) | ty:: Closure ( def_id, _) => Some ( ClosureSimplifiedType ( def_id) ) ,
85
106
ty:: Generator ( def_id, _, _) => Some ( GeneratorSimplifiedType ( def_id) ) ,
@@ -90,7 +111,7 @@ pub fn simplify_type(
90
111
ty:: Tuple ( ref tys) => Some ( TupleSimplifiedType ( tys. len ( ) ) ) ,
91
112
ty:: FnPtr ( ref f) => Some ( FunctionSimplifiedType ( f. skip_binder ( ) . inputs ( ) . len ( ) ) ) ,
92
113
ty:: Projection ( _) | ty:: Param ( _) => {
93
- if can_simplify_params {
114
+ if can_simplify_params == SimplifyParams :: Yes {
94
115
// In normalized types, projections don't unify with
95
116
// anything. when lazy normalization happens, this
96
117
// will change. It would still be nice to have a way
@@ -120,9 +141,12 @@ impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
120
141
UintSimplifiedType ( t) => UintSimplifiedType ( t) ,
121
142
FloatSimplifiedType ( t) => FloatSimplifiedType ( t) ,
122
143
AdtSimplifiedType ( d) => AdtSimplifiedType ( map ( d) ) ,
144
+ ForeignSimplifiedType ( d) => ForeignSimplifiedType ( d) ,
123
145
StrSimplifiedType => StrSimplifiedType ,
124
146
ArraySimplifiedType => ArraySimplifiedType ,
125
- PtrSimplifiedType => PtrSimplifiedType ,
147
+ SliceSimplifiedType => SliceSimplifiedType ,
148
+ RefSimplifiedType ( m) => RefSimplifiedType ( m) ,
149
+ PtrSimplifiedType ( m) => PtrSimplifiedType ( m) ,
126
150
NeverSimplifiedType => NeverSimplifiedType ,
127
151
MarkerTraitObjectSimplifiedType => MarkerTraitObjectSimplifiedType ,
128
152
TupleSimplifiedType ( n) => TupleSimplifiedType ( n) ,
@@ -133,7 +157,6 @@ impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
133
157
OpaqueSimplifiedType ( d) => OpaqueSimplifiedType ( map ( d) ) ,
134
158
FunctionSimplifiedType ( n) => FunctionSimplifiedType ( n) ,
135
159
ParameterSimplifiedType => ParameterSimplifiedType ,
136
- ForeignSimplifiedType ( d) => ForeignSimplifiedType ( d) ,
137
160
}
138
161
}
139
162
}
@@ -149,12 +172,13 @@ where
149
172
| CharSimplifiedType
150
173
| StrSimplifiedType
151
174
| ArraySimplifiedType
152
- | PtrSimplifiedType
175
+ | SliceSimplifiedType
153
176
| NeverSimplifiedType
154
177
| ParameterSimplifiedType
155
178
| MarkerTraitObjectSimplifiedType => {
156
179
// nothing to do
157
180
}
181
+ RefSimplifiedType ( m) | PtrSimplifiedType ( m) => m. hash_stable ( hcx, hasher) ,
158
182
IntSimplifiedType ( t) => t. hash_stable ( hcx, hasher) ,
159
183
UintSimplifiedType ( t) => t. hash_stable ( hcx, hasher) ,
160
184
FloatSimplifiedType ( t) => t. hash_stable ( hcx, hasher) ,
0 commit comments