Fix `redundant_closure_for_method_calls` suggestion
Fixes#7746. The issue turns out to be more general than raw pointers. The `redundant_closure_for_method_calls` lint produces incorrect suggestions when the method is associated with a type that must be enclosed in angle brackets or must be written with generic arguments substituted. For example:
```rust
fn main() {
// Clippy's suggestion: [T; N]::as_slice
// Correct suggestion: <[u8; 3]>::as_slice
let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);
array_opt.map(|a| a.as_slice());
// Clippy's suggestion: [T]::len
// Correct suggestion: <[u8]>::len
let slice_opt: Option<&[u8]> = Some(b"slice");
slice_opt.map(|s| s.len());
// Clippy's suggestion: *const T::is_null
// Correct suggestion: <*const usize>::is_null
let ptr_opt: Option<*const usize> = Some(&487);
ptr_opt.map(|p| p.is_null());
// Clippy's suggestion: dyn TestTrait::method_on_dyn
// Correct suggestion: <dyn TestTrait>::method_on_dyn
let test_struct = TestStruct {};
let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct);
dyn_opt.map(|d| d.method_on_dyn());
}
// For the trait object example:
trait TestTrait {}
struct TestStruct {}
impl TestTrait for TestStruct {}
impl dyn TestTrait + '_ {
fn method_on_dyn(&self) -> bool {
false
}
}
```
The issue also affects references and tuples, though I had to patch the standard library with non-trait methods for those types to test that. Just in case, I also included handling for `!`, since it appeared to be possible to call methods on it with angle brackets. I just couldn't verify the resulting suggestion, since dead-code analysis eliminates the code first.
This is my first exposure to Rust compiler internals, so please let me know if I'm taking the wrong approach here!
changelog: [`redundant_closure_for_method_calls`]: add angle brackets and substitute generic arguments in suggestion when needed