@@ -2,7 +2,9 @@ use super::implicit_clone::is_clone_like;
2
2
use super :: unnecessary_iter_cloned:: { self , is_into_iter} ;
3
3
use clippy_utils:: diagnostics:: span_lint_and_sugg;
4
4
use clippy_utils:: source:: snippet_opt;
5
- use clippy_utils:: ty:: { get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs} ;
5
+ use clippy_utils:: ty:: {
6
+ contains_ty, get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs,
7
+ } ;
6
8
use clippy_utils:: { fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item} ;
7
9
use rustc_errors:: Applicability ;
8
10
use rustc_hir:: { def_id:: DefId , BorrowKind , Expr , ExprKind } ;
@@ -114,7 +116,12 @@ fn check_addr_of_expr(
114
116
parent. span,
115
117
& format!( "unnecessary use of `{}`" , method_name) ,
116
118
"use" ,
117
- format!( "{:&>width$}{}" , "" , receiver_snippet, width = n_target_refs - n_receiver_refs) ,
119
+ format!(
120
+ "{:&>width$}{}" ,
121
+ "" ,
122
+ receiver_snippet,
123
+ width = n_target_refs - n_receiver_refs
124
+ ) ,
118
125
Applicability :: MachineApplicable ,
119
126
) ;
120
127
return true ;
@@ -182,20 +189,10 @@ fn check_into_iter_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name:
182
189
if let Some ( item_ty) = get_iterator_item_ty( cx, parent_ty) ;
183
190
if let Some ( receiver_snippet) = snippet_opt( cx, receiver. span) ;
184
191
then {
185
- if unnecessary_iter_cloned:: check_for_loop_iter(
186
- cx,
187
- parent,
188
- method_name,
189
- receiver,
190
- true ,
191
- ) {
192
+ if unnecessary_iter_cloned:: check_for_loop_iter( cx, parent, method_name, receiver, true ) {
192
193
return true ;
193
194
}
194
- let cloned_or_copied = if is_copy( cx, item_ty) {
195
- "copied"
196
- } else {
197
- "cloned"
198
- } ;
195
+ let cloned_or_copied = if is_copy( cx, item_ty) { "copied" } else { "cloned" } ;
199
196
// The next suggestion may be incorrect because the removal of the `to_owned`-like
200
197
// function could cause the iterator to hold a reference to a resource that is used
201
198
// mutably. See https://github.com/rust-lang/rust-clippy/issues/8148.
@@ -243,18 +240,19 @@ fn check_other_call_arg<'tcx>(
243
240
if if trait_predicate. def_id( ) == deref_trait_id {
244
241
if let [ projection_predicate] = projection_predicates[ ..] {
245
242
let normalized_ty =
246
- cx. tcx. subst_and_normalize_erasing_regions( call_substs, cx. param_env, projection_predicate. term) ;
243
+ cx. tcx
244
+ . subst_and_normalize_erasing_regions( call_substs, cx. param_env, projection_predicate. term) ;
247
245
implements_trait( cx, receiver_ty, deref_trait_id, & [ ] )
248
- && get_associated_type( cx, receiver_ty, deref_trait_id,
249
- "Target" ) . map_or( false , |ty| ty:: Term :: Ty ( ty) == normalized_ty)
246
+ && get_associated_type( cx, receiver_ty, deref_trait_id, "Target" )
247
+ . map_or( false , |ty| ty:: Term :: Ty ( ty) == normalized_ty)
250
248
} else {
251
249
false
252
250
}
253
251
} else if trait_predicate. def_id( ) == as_ref_trait_id {
254
252
let composed_substs = compose_substs(
255
253
cx,
256
254
& trait_predicate. trait_ref. substs. iter( ) . skip( 1 ) . collect:: <Vec <_>>( ) [ ..] ,
257
- call_substs
255
+ call_substs,
258
256
) ;
259
257
implements_trait( cx, receiver_ty, as_ref_trait_id, & composed_substs)
260
258
} else {
@@ -264,6 +262,12 @@ fn check_other_call_arg<'tcx>(
264
262
// `Target = T`.
265
263
if n_refs > 0 || is_copy( cx, receiver_ty) || trait_predicate. def_id( ) != deref_trait_id;
266
264
let n_refs = max( n_refs, if is_copy( cx, receiver_ty) { 0 } else { 1 } ) ;
265
+ // If the trait is `AsRef` and the input type variable `T` occurs in the output type, then
266
+ // `T` must not be instantiated with a reference
267
+ // (https://github.com/rust-lang/rust-clippy/issues/8507).
268
+ if ( n_refs == 0 && !receiver_ty. is_ref( ) )
269
+ || trait_predicate. def_id( ) != as_ref_trait_id
270
+ || !contains_ty( fn_sig. output( ) , input) ;
267
271
if let Some ( receiver_snippet) = snippet_opt( cx, receiver. span) ;
268
272
then {
269
273
span_lint_and_sugg(
@@ -339,11 +343,7 @@ fn get_input_traits_and_projections<'tcx>(
339
343
if let Some ( arg) = substs. iter( ) . next( ) ;
340
344
if let GenericArgKind :: Type ( arg_ty) = arg. unpack( ) ;
341
345
if arg_ty == input;
342
- then {
343
- true
344
- } else {
345
- false
346
- }
346
+ then { true } else { false }
347
347
}
348
348
} ;
349
349
match predicate. kind ( ) . skip_binder ( ) {
0 commit comments