mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 14:38:46 +00:00
Auto merge of #10653 - flip1995:book-type_passes_corrections, r=llogiq
Book: Improve type checking and lint passes chapters - Adds the lint passes chapter to the index. - Moves additional reading material for beginners to the front page of the development section. - Clarify some details in `hir::Ty` vs `ty::Ty`. `@blyxyas` I started reviewing the chapters that were already merged. Great work. I liked the additional reading chapter so much, that I moved it front and center. Other than that I only had some minor corrections to make. Please review. r? `@llogiq` changelog: none
This commit is contained in:
commit
a34e75be59
4 changed files with 40 additions and 32 deletions
|
@ -13,6 +13,7 @@
|
|||
- [Development](development/README.md)
|
||||
- [Basics](development/basics.md)
|
||||
- [Adding Lints](development/adding_lints.md)
|
||||
- [Lint Passes](development/lint_passes.md)
|
||||
- [Type Checking](development/type_checking.md)
|
||||
- [Common Tools](development/common_tools_writing_lints.md)
|
||||
- [Infrastructure](development/infrastructure/README.md)
|
||||
|
|
|
@ -13,6 +13,24 @@ If this is your first time contributing to Clippy, you should first read the
|
|||
[Basics docs](basics.md). This will explain the basics on how to get the source
|
||||
code and how to compile and test the code.
|
||||
|
||||
## Additional Readings for Beginners
|
||||
|
||||
If a dear reader of this documentation has never taken a class on compilers
|
||||
and interpreters, it might be confusing as to why AST level deals with only
|
||||
the language's syntax. And some readers might not even understand what lexing,
|
||||
parsing, and AST mean.
|
||||
|
||||
This documentation serves by no means as a crash course on compilers or language design.
|
||||
And for details specifically related to Rust, the [Rustc Development Guide][rustc_dev_guide]
|
||||
is a far better choice to peruse.
|
||||
|
||||
The [Syntax and AST][ast] chapter and the [High-Level IR][hir] chapter are
|
||||
great introduction to the concepts mentioned in this chapter.
|
||||
|
||||
Some readers might also find the [introductory chapter][map_of_territory] of
|
||||
Robert Nystrom's _Crafting Interpreters_ a helpful overview of compiled and
|
||||
interpreted languages before jumping back to the Rustc guide.
|
||||
|
||||
## Writing code
|
||||
|
||||
If you have done the basic setup, it's time to start hacking.
|
||||
|
@ -37,6 +55,10 @@ book](../lints.md).
|
|||
> - Triage procedure
|
||||
> - Bors and Homu
|
||||
|
||||
[ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html
|
||||
[hir]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||
[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/
|
||||
[map_of_territory]: https://craftinginterpreters.com/a-map-of-the-territory.html
|
||||
[clippy_rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md
|
||||
[rfc_stability]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#stability-guarantees
|
||||
[rfc_lint_cats]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Lint passes
|
||||
|
||||
Before working on the logic of a new lint, there is an important decision
|
||||
that every Clippy developers must make: to use
|
||||
that every Clippy developer must make: to use
|
||||
[`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].
|
||||
|
||||
In short, the `LateLintPass` has access to type and symbol information while the
|
||||
|
@ -107,30 +107,8 @@ that use `LateLintPass`:
|
|||
$ cargo dev new_lint --name=<your_new_lint> --pass=late --category=<your_category_choice>
|
||||
```
|
||||
|
||||
## Additional Readings for Beginners
|
||||
|
||||
If a dear reader of this documentation has never taken a class on compilers
|
||||
and interpreters, it might be confusing as to why AST level deals with only
|
||||
the language's syntax. And some readers might not even understand what lexing,
|
||||
parsing, and AST mean.
|
||||
|
||||
This documentation serves by no means as a crash course on compilers or language design.
|
||||
And for details specifically related to Rust, the [Rustc Development Guide][rustc_dev_guide]
|
||||
is a far better choice to peruse.
|
||||
|
||||
The [Syntax and AST][ast] chapter and the [High-Level IR][hir] chapter are
|
||||
great introduction to the concepts mentioned in this chapter.
|
||||
|
||||
Some readers might also find the [introductory chapter][map_of_territory] of
|
||||
Robert Nystrom's _Crafting Interpreters_ a helpful overview of compiled and
|
||||
interpreted languages before jumping back to the Rustc guide.
|
||||
|
||||
[ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html
|
||||
[early_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.EarlyContext.html
|
||||
[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
|
||||
[hir]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||
[late_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html
|
||||
[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
|
||||
[lexing_and_parsing]: https://rustc-dev-guide.rust-lang.org/overview.html#lexing-and-parsing
|
||||
[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/
|
||||
[map_of_territory]: https://craftinginterpreters.com/a-map-of-the-territory.html
|
||||
|
|
|
@ -51,7 +51,7 @@ impl LateLintPass<'_> for MyStructLint {
|
|||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
// Get type of `expr`
|
||||
let ty = cx.typeck_results().expr_ty(expr);
|
||||
|
||||
|
||||
// Check if the `Ty` of this expression is of character type
|
||||
if ty.is_char() {
|
||||
println!("Our expression is a char!");
|
||||
|
@ -70,18 +70,18 @@ pub fn is_char(self) -> bool {
|
|||
}
|
||||
```
|
||||
|
||||
Indeed, we just discovered `Ty`'s [`kind` method][kind], which provides us
|
||||
Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us
|
||||
with [`TyKind`][TyKind] of a `Ty`.
|
||||
|
||||
## `TyKind`
|
||||
|
||||
`TyKind` defines the kinds of types in Rust's type system.
|
||||
Peeking into [`TyKind` documentation][TyKind], we will see that it is an
|
||||
enum of 27 variants, including items such as `Bool`, `Int`, `Ref`, etc.
|
||||
enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc.
|
||||
|
||||
### `kind` Usage
|
||||
|
||||
The `TyKind` of `Ty` can be returned by calling [`Ty.kind` method][kind].
|
||||
The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind].
|
||||
We often use this method to perform pattern matching in Clippy.
|
||||
|
||||
For instance, if we want to check for a `struct`, we could examine if the
|
||||
|
@ -107,15 +107,21 @@ impl LateLintPass<'_> for MyStructLint {
|
|||
We've been talking about [`ty::Ty`][middle_ty] this whole time without addressing [`hir::Ty`][hir_ty], but the latter
|
||||
is also important to understand.
|
||||
|
||||
`hir::Ty` would represent *what* an user wrote, while `ty::Ty` would understand the meaning of it (because it has more
|
||||
information).
|
||||
`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more
|
||||
information. Example:
|
||||
|
||||
**Example: `fn foo(x: u32) -> u32 { x }`**
|
||||
```rust
|
||||
fn foo(x: u32) -> u32 { x }
|
||||
```
|
||||
|
||||
Here the HIR sees the types without "thinking" about them, it knows that the function takes an `u32` and returns
|
||||
an `u32`. But at the `ty::Ty` level the compiler understands that they're the same type, in-depth lifetimes, etc...
|
||||
an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
|
||||
understands that they're the same type, in-depth lifetimes, etc...
|
||||
|
||||
you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function to convert from a `hir::Ty` to a `ty::Ty`
|
||||
To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
|
||||
outside of bodies the [`TypeckResults::node_type()`][node_type] method.
|
||||
|
||||
> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
|
||||
|
||||
## Useful Links
|
||||
|
||||
|
@ -130,6 +136,7 @@ in this chapter:
|
|||
[Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt
|
||||
[AdtDef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adt/struct.AdtDef.html
|
||||
[expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty
|
||||
[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type
|
||||
[is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char
|
||||
[is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1831-1834
|
||||
[kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind
|
||||
|
|
Loading…
Add table
Reference in a new issue