@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, AdtDef, GenericArgKind, Ty};
22
22
use rustc_span:: Span ;
23
23
24
24
mod certainty;
25
- use certainty:: { Certainty , Meet , join, meet} ;
25
+ use certainty:: { Certainty , Meet , TypeKind , join, meet} ;
26
26
27
27
pub fn expr_type_is_certain ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
28
28
expr_type_certainty ( cx, expr, false ) . is_certain ( )
@@ -46,11 +46,12 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>, in_arg: bool) -> C
46
46
} else {
47
47
Certainty :: Uncertain
48
48
} ;
49
- lhs. join_clearing_def_ids ( rhs)
49
+ lhs. join_clearing_types ( rhs)
50
50
} ,
51
51
52
52
ExprKind :: MethodCall ( method, receiver, args, _) => {
53
- let mut receiver_type_certainty = expr_type_certainty ( cx, receiver, false ) ;
53
+ let mut receiver_type_certainty = expr_type_certainty ( cx, receiver, false ) ?;
54
+
54
55
// Even if `receiver_type_certainty` is `Certain(Some(..))`, the `Self` type in the method
55
56
// identified by `type_dependent_def_id(..)` can differ. This can happen as a result of a `deref`,
56
57
// for example. So update the `DefId` in `receiver_type_certainty` (if any).
@@ -66,7 +67,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>, in_arg: bool) -> C
66
67
. chain ( args. iter ( ) . map ( |arg| expr_type_certainty ( cx, arg, true ) ) ) ,
67
68
)
68
69
} else {
69
- Certainty :: Uncertain
70
+ return Certainty :: Uncertain ;
70
71
} ;
71
72
lhs. join ( rhs)
72
73
} ,
@@ -117,12 +118,13 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>, in_arg: bool) -> C
117
118
_ => Certainty :: Uncertain ,
118
119
} ;
119
120
120
- let expr_ty = cx. typeck_results ( ) . expr_ty ( expr) ;
121
- if let Some ( def_id) = adt_def_id ( expr_ty) {
122
- certainty. with_def_id ( def_id)
123
- } else {
124
- certainty. clear_def_id ( )
125
- }
121
+ let result = match cx. typeck_results ( ) . expr_ty ( expr) . kind ( ) {
122
+ ty:: Adt ( adt_def, _) => certainty. with_def_id ( adt_def. did ( ) ) ,
123
+ ty:: Bool | ty:: Char | ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) => certainty. with_prim_ty ( ) ,
124
+ _ => certainty. clear_type ( ) ,
125
+ } ;
126
+
127
+ result
126
128
}
127
129
128
130
struct CertaintyVisitor < ' cx , ' tcx > {
@@ -209,7 +211,11 @@ fn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bo
209
211
. map_or ( Certainty :: Uncertain , |def_id| {
210
212
let generics = cx. tcx . generics_of ( def_id) ;
211
213
if generics. is_empty ( ) {
212
- Certainty :: Certain ( if resolves_to_type { Some ( def_id) } else { None } )
214
+ Certainty :: Certain ( if resolves_to_type {
215
+ Some ( TypeKind :: AdtDef ( def_id) )
216
+ } else {
217
+ None
218
+ } )
213
219
} else {
214
220
Certainty :: Uncertain
215
221
}
@@ -230,7 +236,7 @@ fn param_certainty(cx: &LateContext<'_>, param: &Param<'_>) -> Certainty {
230
236
let body_params = cx. tcx . hir_body_owned_by ( owner_did) . params ;
231
237
std:: iter:: zip ( body_params, inputs)
232
238
. find ( |( p, _) | p. hir_id == param. hir_id )
233
- . map_or ( Certainty :: Uncertain , |( _, ty) | type_certainty ( cx, ty) . clear_def_id ( ) )
239
+ . map_or ( Certainty :: Uncertain , |( _, ty) | type_certainty ( cx, ty) . clear_type ( ) )
234
240
}
235
241
236
242
fn path_segment_certainty (
@@ -263,7 +269,7 @@ fn path_segment_certainty(
263
269
. args
264
270
. map_or ( Certainty :: Uncertain , |args| generic_args_certainty ( cx, args) ) ;
265
271
// See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.
266
- let certainty = lhs. join_clearing_def_ids ( rhs) ;
272
+ let certainty = lhs. join_clearing_types ( rhs) ;
267
273
if resolves_to_type {
268
274
if let DefKind :: TyAlias = cx. tcx . def_kind ( def_id) {
269
275
adt_def_id ( cx. tcx . type_of ( def_id) . instantiate_identity ( ) )
@@ -279,9 +285,7 @@ fn path_segment_certainty(
279
285
}
280
286
} ,
281
287
282
- Res :: PrimTy ( _) | Res :: SelfTyParam { .. } | Res :: SelfTyAlias { .. } | Res :: SelfCtor ( _) => {
283
- Certainty :: Certain ( None )
284
- } ,
288
+ Res :: PrimTy ( _) => Certainty :: Certain ( Some ( TypeKind :: PrimTy ) ) ,
285
289
286
290
// `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.
287
291
Res :: Local ( hir_id) => match cx. tcx . parent_hir_node ( hir_id) {
@@ -299,13 +303,13 @@ fn path_segment_certainty(
299
303
if resolves_to_type {
300
304
certainty
301
305
} else {
302
- certainty. clear_def_id ( )
306
+ certainty. clear_type ( )
303
307
}
304
308
} ,
305
309
_ => Certainty :: Uncertain ,
306
310
} ,
307
311
308
- _ => Certainty :: Uncertain ,
312
+ _ => Certainty :: Certain ( None ) ,
309
313
} ;
310
314
debug_assert ! ( resolves_to_type || certainty. to_def_id( ) . is_none( ) ) ;
311
315
certainty
0 commit comments