@@ -96,29 +96,36 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
9696
9797## Creating Types Programmatically
9898
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:
104109
105110``` rust
106111
107112use rustc_middle :: ty :: Ty ;
108113use clippy_utils :: ty :: implements_trait;
109114use rustc_span :: symbol :: sym;
110115
111- let ty = todo! ();
116+ let ty = todo! (" Get the `Foo` type to check for a trait implementation " );
112117let 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" )
115122}
116123```
117124
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.
122129
123130
124131[ 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
129136[ symbol ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
130137[ symbol_index ] : https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html
131138[ 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
133140[ 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