From fbb69dea9156d73d2e73361aab8164bb1c0074e6 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Sun, 16 Apr 2023 20:42:40 +0200 Subject: [PATCH 1/2] 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. --- book/src/SUMMARY.md | 1 + book/src/development/README.md | 22 ++++++++++++++++++++++ book/src/development/lint_passes.md | 24 +----------------------- book/src/development/type_checking.md | 24 +++++++++++++++--------- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index cbd73376dfa0..3f1a822eb950 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -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) diff --git a/book/src/development/README.md b/book/src/development/README.md index 616e6d182b72..8f09f66f5958 100644 --- a/book/src/development/README.md +++ b/book/src/development/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 diff --git a/book/src/development/lint_passes.md b/book/src/development/lint_passes.md index 058b9fa32335..c41b6ea0de8f 100644 --- a/book/src/development/lint_passes.md +++ b/book/src/development/lint_passes.md @@ -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= --pass=late --category= ``` -## 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 diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md index 5ce434b99a1a..e4398885be0d 100644 --- a/book/src/development/type_checking.md +++ b/book/src/development/type_checking.md @@ -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,20 @@ 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. Don't use `hir_ty_to_ty` inside of bodies, +because this can cause ICEs. ## Useful Links @@ -130,6 +135,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 From b842e99ddf9776a480ca911702195922b2603c3b Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Sun, 16 Apr 2023 21:08:59 +0200 Subject: [PATCH 2/2] Make warning about hir_ty_to_ty more visible --- book/src/development/type_checking.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md index e4398885be0d..225de8495662 100644 --- a/book/src/development/type_checking.md +++ b/book/src/development/type_checking.md @@ -119,8 +119,9 @@ an `u32`. As far as `hir::Ty` is concerned those might be different types. But a understands that they're the same type, in-depth lifetimes, etc... 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. Don't use `hir_ty_to_ty` inside of bodies, -because this can cause ICEs. +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