Skip to content
/ rustc Public
forked from rust-lang/rust

Commit

Permalink
Auto merge of rust-lang#5674 - ThibsG:DocTypeDefinesMethod, r=yaahc,p…
Browse files Browse the repository at this point in the history
…hansch,flip1995

Add doc for checking if type defines specific method

This PR adds documentation on how:
- check if a type defines a specific method
- check an expr is calling a specific method

closes: rust-lang#3843

changelog: none
  • Loading branch information
bors committed Jun 6, 2020
2 parents e6f05ad + 9e89ba9 commit 5699672
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions doc/common_tools_writing_lints.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ You may need following tooltips to catch up with common operations.

- [Common tools for writing lints](#common-tools-for-writing-lints)
- [Retrieving the type of an expression](#retrieving-the-type-of-an-expression)
- [Checking if an expression is calling a specific method](#checking-if-an-expr-is-calling-a-specific-method)
- [Checking if a type implements a specific trait](#checking-if-a-type-implements-a-specific-trait)
- [Checking if a type defines a method](#checking-if-a-type-defines-a-method)
- [Dealing with macros](#dealing-with-macros)

Useful Rustc dev guide links:
Expand Down Expand Up @@ -49,6 +51,26 @@ Two noticeable items here:
- `tables` is [`TypeckTables`][TypeckTables] and is created by type checking step,
it includes useful information such as types of expressions, ways to resolve methods and so on.

# Checking if an expr is calling a specific method

Starting with an `expr`, you can check whether it is calling a specific method `some_method`:

```rust
impl LateLintPass<'_, '_> for MyStructLint {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr<'_>) {
if_chain! {
// Check our expr is calling a method
if let hir::ExprKind::MethodCall(path, _, _args) = &expr.kind;
// Check the name of this method is `some_method`
if path.ident.name == sym!(some_method);
then {
// ...
}
}
}
}
```

# Checking if a type implements a specific trait

There are two ways to do this, depending if the target trait is part of lang items.
Expand Down Expand Up @@ -83,6 +105,32 @@ A list of defined paths for Clippy can be found in [paths.rs][paths]

We access lang items through the type context `tcx`. `tcx` is of type [`TyCtxt`][TyCtxt] and is defined in the `rustc_middle` crate.

# Checking if a type defines a specific method

To check if our type defines a method called `some_method`:

```rust
use crate::utils::{is_type_diagnostic_item, return_ty};

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MyTypeImpl {
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem<'_>) {
if_chain! {
// Check if item is a method/function
if let ImplItemKind::Fn(ref signature, _) = impl_item.kind;
// Check the method is named `some_method`
if impl_item.ident.name == sym!(some_method);
// We can also check it has a parameter `self`
if signature.decl.implicit_self.has_implicit_self();
// We can go further and even check if its return type is `String`
if is_type_diagnostic_item(cx, return_ty(cx, impl_item.hir_id), sym!(string_type));
then {
// ...
}
}
}
}
```

# Dealing with macros

There are several helpers in Clippy's utils to deal with macros:
Expand Down

0 comments on commit 5699672

Please sign in to comment.