@@ -4,7 +4,8 @@ You may need following tooltips to catch up with common operations.
44
55- [ Common tools for writing lints] ( #common-tools-for-writing-lints )
66 - [ Retrieving the type of an expression] ( #retrieving-the-type-of-an-expression )
7- - [ Checking if an expression is calling a specific method] ( #checking-if-an-expr-is-calling-a-specific-method )
7+ - [ Checking if an expr is calling a specific method] ( #checking-if-an-expr-is-calling-a-specific-method )
8+ - [ Checking for a specific type] ( #checking-for-a-specific-type )
89 - [ Checking if a type implements a specific trait] ( #checking-if-a-type-implements-a-specific-trait )
910 - [ Checking if a type defines a specific method] ( #checking-if-a-type-defines-a-specific-method )
1011 - [ Dealing with macros] ( #dealing-with-macros )
@@ -15,7 +16,7 @@ Useful Rustc dev guide links:
1516- [ Type checking] ( https://rustc-dev-guide.rust-lang.org/type-checking.html )
1617- [ Ty module] ( https://rustc-dev-guide.rust-lang.org/ty.html )
1718
18- # Retrieving the type of an expression
19+ ## Retrieving the type of an expression
1920
2021Sometimes you may want to retrieve the type ` Ty ` of an expression ` Expr ` , for example to answer following questions:
2122
@@ -54,7 +55,7 @@ Two noticeable items here:
5455 created by type checking step, it includes useful information such as types
5556 of expressions, ways to resolve methods and so on.
5657
57- # Checking if an expr is calling a specific method
58+ ## Checking if an expr is calling a specific method
5859
5960Starting with an ` expr ` , you can check whether it is calling a specific method ` some_method ` :
6061
@@ -63,9 +64,11 @@ impl LateLintPass<'_> for MyStructLint {
6364 fn check_expr (& mut self , cx : & LateContext <'tcx >, expr : & 'tcx hir :: Expr <'_ >) {
6465 if_chain! {
6566 // Check our expr is calling a method
66- if let hir :: ExprKind :: MethodCall (path , _ , _args , _ ) = & expr . kind;
67+ if let hir :: ExprKind :: MethodCall (path , _ , [ _self_arg , .. ] , _ ) = & expr . kind;
6768 // Check the name of this method is `some_method`
6869 if path . ident. name == sym! (some_method );
70+ // Optionally, check the type of the self argument.
71+ // - See "Checking for a specific type"
6972 then {
7073 // ...
7174 }
@@ -74,7 +77,45 @@ impl LateLintPass<'_> for MyStructLint {
7477}
7578```
7679
77- # Checking if a type implements a specific trait
80+ ## Checking for a specific type
81+
82+ There are three ways to check if an expression type is a specific type we want to check for.
83+ All of these methods only check for the base type, generic arguments have to be checked separately.
84+
85+ ``` rust
86+ use clippy_utils :: ty :: {is_type_diagnostic_item, is_type_lang_item};
87+ use clippy_utils :: {paths, match_def_path};
88+ use rustc_span :: symbol :: sym;
89+ use rustc_hir :: LangItem ;
90+
91+ impl LateLintPass <'_ > for MyStructLint {
92+ fn check_expr (& mut self , cx : & LateContext <'_ >, expr : & Expr <'_ >) {
93+ // Getting the expression type
94+ let ty = cx . typeck_results (). expr_ty (expr );
95+
96+ // 1. Using diagnostic items
97+ // The last argument is the diagnostic item to check for
98+ if is_type_diagnostic_item (cx , ty , sym :: Option ) {
99+ // The type is an `Option`
100+ }
101+
102+ // 2. Using lang items
103+ if is_type_lang_item (cx , ty , LangItem :: RangeFull ) {
104+ // The type is a full range like `.drain(..)`
105+ }
106+
107+ // 3. Using the type path
108+ // This method should be avoided if possible
109+ if match_def_path (cx , def_id , & paths :: RESULT ) {
110+ // The type is a `core::result::Result`
111+ }
112+ }
113+ }
114+ ```
115+
116+ Prefer using diagnostic items and lang items where possible.
117+
118+ ## Checking if a type implements a specific trait
78119
79120There are three ways to do this, depending on if the target trait has a diagnostic item, lang item or neither.
80121
@@ -102,6 +143,7 @@ impl LateLintPass<'_> for MyStructLint {
102143
103144 // 3. Using the type path with the expression
104145 // we use `match_trait_method` function from Clippy's utils
146+ // (This method should be avoided if possible)
105147 if match_trait_method (cx , expr , & paths :: INTO ) {
106148 // `expr` implements `Into` trait
107149 }
@@ -114,7 +156,7 @@ impl LateLintPass<'_> for MyStructLint {
114156We access lang items through the type context ` tcx ` . ` tcx ` is of type [ ` TyCtxt ` ] [ TyCtxt ] and is defined in the ` rustc_middle ` crate.
115157A list of defined paths for Clippy can be found in [ paths.rs] [ paths ]
116158
117- # Checking if a type defines a specific method
159+ ## Checking if a type defines a specific method
118160
119161To check if our type defines a method called ` some_method ` :
120162
@@ -140,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
140182}
141183```
142184
143- # Dealing with macros
185+ ## Dealing with macros
144186
145187There are several helpers in [ ` clippy_utils ` ] [ utils ] to deal with macros:
146188
0 commit comments