@@ -4,7 +4,6 @@ use rustc::middle::ty;
4
4
use rustc:: middle:: subst:: { Subst , TypeSpace } ;
5
5
use std:: iter;
6
6
use std:: borrow:: Cow ;
7
- use std:: collections:: HashSet ;
8
7
9
8
use utils:: { snippet, span_lint, match_path, match_type, walk_ptrs_ty_depth,
10
9
walk_ptrs_ty} ;
@@ -13,69 +12,8 @@ use utils::{OPTION_PATH, RESULT_PATH, STRING_PATH};
13
12
use self :: SelfKind :: * ;
14
13
use self :: OutType :: * ;
15
14
16
- use rustc:: middle:: def_id:: DefId ;
17
-
18
- use rustc:: middle:: ty:: TypeFlags ;
19
-
20
15
#[ derive( Clone ) ]
21
- pub struct MethodsPass { types_implementing_debug : Option < HashSet < DefId > > }
22
-
23
- impl MethodsPass {
24
- pub fn new ( ) -> MethodsPass {
25
- MethodsPass { types_implementing_debug : None }
26
- }
27
-
28
- fn get_debug_impls ( & mut self , cx : & LateContext ) -> Option < & HashSet < DefId > > {
29
- if self . types_implementing_debug . is_none ( ) {
30
- let debug = match cx. tcx . lang_items . debug_trait ( ) {
31
- Some ( debug) => debug,
32
- None => return None
33
- } ;
34
- let debug_def = cx. tcx . lookup_trait_def ( debug) ;
35
- let mut impls = HashSet :: new ( ) ;
36
- debug_def. for_each_impl ( cx. tcx , |d| {
37
- let o_self_ty = & cx. tcx . impl_trait_ref ( d)
38
- . map ( |x| x. substs )
39
- . and_then ( |x| x. self_ty ( ) ) ;
40
- let self_ty = match * o_self_ty {
41
- Some ( self_type) => self_type,
42
- None => return
43
- } ;
44
- let self_ty_def_id = self_ty. ty_to_def_id ( ) ;
45
- if let Some ( self_ty_def_id) = self_ty_def_id {
46
- let has_params = self_ty. flags . get ( ) . contains ( TypeFlags :: HAS_PARAMS ) ;
47
- if !has_params {
48
- impls. insert ( self_ty_def_id) ;
49
- }
50
- }
51
- } ) ;
52
- self . types_implementing_debug = Some ( impls) ;
53
- }
54
- self . types_implementing_debug . as_ref ( )
55
- }
56
-
57
- // This checks whether a given type is known to implement Debug. It's
58
- // conservative, i.e. it should not return false positives, but will return
59
- // false negatives.
60
- fn has_debug_impl ( & mut self , ty : ty:: Ty , cx : & LateContext ) -> bool {
61
- let debug_impls = match self . get_debug_impls ( cx) {
62
- Some ( debug_impls) => debug_impls,
63
- None => return false
64
- } ;
65
- match walk_ptrs_ty ( ty) . sty {
66
- ty:: TyBool | ty:: TyChar | ty:: TyInt ( ..) | ty:: TyUint ( ..)
67
- | ty:: TyFloat ( ..) | ty:: TyStr => true ,
68
- ty:: TyTuple ( ref v) if v. is_empty ( ) => true ,
69
- ty:: TyStruct ( ..) | ty:: TyEnum ( ..) => {
70
- match ty. ty_to_def_id ( ) {
71
- Some ( ref ty_def_id) => debug_impls. contains ( ty_def_id) ,
72
- None => false
73
- }
74
- } ,
75
- _ => false
76
- }
77
- }
78
- }
16
+ pub struct MethodsPass ;
79
17
80
18
declare_lint ! ( pub OPTION_UNWRAP_USED , Allow ,
81
19
"using `Option.unwrap()`, which should at least get a better message using `expect()`" ) ;
@@ -144,7 +82,7 @@ impl LateLintPass for MethodsPass {
144
82
&& match_type ( cx, cx. tcx . expr_ty ( & inner_args[ 0 ] ) , & RESULT_PATH ) {
145
83
let result_type = cx. tcx . expr_ty ( & inner_args[ 0 ] ) ;
146
84
if let Some ( error_type) = get_error_type ( cx, result_type) {
147
- if self . has_debug_impl ( error_type, cx) {
85
+ if has_debug_impl ( error_type, cx) {
148
86
span_lint ( cx, OK_EXPECT , expr. span ,
149
87
"called `ok().expect()` on a Result \
150
88
value. You can call `expect` directly
@@ -212,6 +150,27 @@ fn get_error_type<'a>(cx: &LateContext, ty: ty::Ty<'a>) -> Option<ty::Ty<'a>> {
212
150
None
213
151
}
214
152
153
+ // This checks whether a given type is known to implement Debug. It's
154
+ // conservative, i.e. it should not return false positives, but will return
155
+ // false negatives.
156
+ fn has_debug_impl < ' a , ' b > ( ty : ty:: Ty < ' a > , cx : & LateContext < ' b , ' a > ) -> bool {
157
+ let ty = walk_ptrs_ty ( ty) ;
158
+ let debug = match cx. tcx . lang_items . debug_trait ( ) {
159
+ Some ( debug) => debug,
160
+ None => return false
161
+ } ;
162
+ let debug_def = cx. tcx . lookup_trait_def ( debug) ;
163
+ let mut debug_impl_exists = false ;
164
+ debug_def. for_each_relevant_impl ( cx. tcx , ty, |d| {
165
+ let self_ty = & cx. tcx . impl_trait_ref ( d) . and_then ( |im| im. substs . self_ty ( ) ) ;
166
+ if let Some ( self_ty) = * self_ty {
167
+ if !self_ty. flags . get ( ) . contains ( ty:: TypeFlags :: HAS_PARAMS ) {
168
+ debug_impl_exists = true ;
169
+ }
170
+ }
171
+ } ) ;
172
+ debug_impl_exists
173
+ }
215
174
216
175
const CONVENTIONS : [ ( & ' static str , & ' static [ SelfKind ] ) ; 5 ] = [
217
176
( "into_" , & [ ValueSelf ] ) ,
0 commit comments