@@ -96,29 +96,36 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
96
96
97
97
## Creating Types Programmatically
98
98
99
- Traits are often generic over a type e.g. ` Borrow<T> ` is generic over ` T ` , and rust allows us to implement a trait for
100
- a specific type. For example, we can implement ` Borrow<str> ` for a hypothetical type ` Foo ` . Let's suppose that we
101
- would like to find whether our type actually implements ` Borrow<[u8]> ` . To do so, we need to supply a type that
102
- represents ` [u8] ` , but ` [u8] ` is also a generic, it's a slice over ` u8 ` . We can create this type using Ty::new_slice
103
- method. The following code demonstrates how to do this:
99
+ Traits are often generic over a type parameter, e.g. ` Borrow<T> ` is generic
100
+ over ` T ` . Rust allows us to implement a trait for a specific type. For example,
101
+ we can implement ` Borrow<[u8]> ` for a hypothetical type ` Foo ` . Let's suppose
102
+ that we would like to find whether our type actually implements ` Borrow<[u8]> ` .
103
+
104
+ To do so, we can use the same ` implements_trait ` function as above, and supply
105
+ a parameter type that represents ` [u8] ` . Since ` [u8] ` is a specialization of
106
+ ` [T] ` , we can use the [ ` Ty::new_slice ` ] [ new_slice ] method to create a type
107
+ that represents ` [T] ` and supply ` u8 ` as a type parameter. The following code
108
+ demonstrates how to do this:
104
109
105
110
``` rust
106
111
107
112
use rustc_middle :: ty :: Ty ;
108
113
use clippy_utils :: ty :: implements_trait;
109
114
use rustc_span :: symbol :: sym;
110
115
111
- let ty = todo! ();
116
+ let ty = todo! (" Get the `Foo` type to check for a trait implementation " );
112
117
let borrow_id = cx . tcx. get_diagnostic_item (sym :: Borrow ). unwrap (); // avoid unwrap in real code
113
- if implements_trait (cx , ty , borrow_id , & [Ty :: new_slice (cx . tcx, cx . tcx. types. u8 ). into ()]) {
114
- todo! ()
118
+ let slice_bytes = Ty :: new_slice (cx . tcx, cx . tcx. types. u8 );
119
+ let generic_param = slice_bytes . into ();
120
+ if implements_trait (cx , ty , borrow_id , & [generic_param ]) {
121
+ todo! (" Rest of lint implementation" )
115
122
}
116
123
```
117
124
118
- Here, we use ` Ty::new_slice ` to create a type that represents ` [T] ` and supply ` u8 ` as a type parameter, and then we go
119
- on normally with ` implements_trait ` function. The [ Ty ] struct allows us to create types programmatically, and it's
120
- useful when we need to create types that we can't obtain through the usual means.
121
-
125
+ In essence, the [ ` Ty ` ] struct allows us to create types programmatically in a
126
+ representation that can be used by the compiler and the query engine. We then
127
+ use the ` rustc_middle::Ty ` of the type we are interested in, and query the
128
+ compiler to see if it indeed implements the trait we are interested in.
122
129
123
130
124
131
[ DefId ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
@@ -129,5 +136,6 @@ useful when we need to create types that we can't obtain through the usual means
129
136
[ symbol ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
130
137
[ symbol_index ] : https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html
131
138
[ TyCtxt ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
132
- [ Ty ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
139
+ [ `Ty` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
133
140
[ rust ] : https://github.com/rust-lang/rust
141
+ [ new_slice ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_slice
0 commit comments