Fix 12969 and fix 9841
This commit is contained in:
parent
388de386f5
commit
c4c41d1352
@ -3,7 +3,8 @@
|
||||
use clippy_utils::sugg::has_enclosing_paren;
|
||||
use clippy_utils::ty::{implements_trait, is_manually_drop, peel_mid_ty_refs};
|
||||
use clippy_utils::{
|
||||
expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode,
|
||||
expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, peel_middle_ty_refs, DefinedTy,
|
||||
ExprUseNode,
|
||||
};
|
||||
use core::mem;
|
||||
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
|
||||
@ -1044,16 +1045,28 @@ fn report<'tcx>(
|
||||
return;
|
||||
}
|
||||
|
||||
let (prefix, precedence) = if let Some(mutability) = mutability
|
||||
&& !typeck.expr_ty(expr).is_ref()
|
||||
let ty = typeck.expr_ty(expr);
|
||||
|
||||
// `&&[T; N]`, or `&&..&[T; N]` (src) cannot coerce to `&[T]` (dst).
|
||||
if let ty::Ref(_, dst, _) = data.adjusted_ty.kind()
|
||||
&& dst.is_slice()
|
||||
{
|
||||
let prefix = match mutability {
|
||||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
};
|
||||
(prefix, PREC_PREFIX)
|
||||
} else {
|
||||
("", 0)
|
||||
let (src, n_src_refs) = peel_middle_ty_refs(ty);
|
||||
if n_src_refs >= 2 && src.is_array() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let (prefix, precedence) = match mutability {
|
||||
Some(mutability) if !ty.is_ref() => {
|
||||
let prefix = match mutability {
|
||||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
};
|
||||
(prefix, PREC_PREFIX)
|
||||
},
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", 0),
|
||||
_ => ("", 0),
|
||||
};
|
||||
span_lint_hir_and_then(
|
||||
cx,
|
||||
|
@ -2471,6 +2471,17 @@ pub fn peel_hir_ty_refs<'a>(mut ty: &'a hir::Ty<'a>) -> (&'a hir::Ty<'a>, usize)
|
||||
}
|
||||
}
|
||||
|
||||
/// Peels off all references on the type. Returns the underlying type and the number of references
|
||||
/// removed.
|
||||
pub fn peel_middle_ty_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {
|
||||
let mut count = 0;
|
||||
while let rustc_ty::Ref(_, dest_ty, _) = ty.kind() {
|
||||
ty = *dest_ty;
|
||||
count += 1;
|
||||
}
|
||||
(ty, count)
|
||||
}
|
||||
|
||||
/// Removes `AddrOf` operators (`&`) or deref operators (`*`), but only if a reference type is
|
||||
/// dereferenced. An overloaded deref such as `Vec` to slice would not be removed.
|
||||
pub fn peel_ref_operators<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
|
||||
|
@ -364,13 +364,17 @@ mod issue_12969 {
|
||||
fn bar() {
|
||||
let wrapped_bar = Wrapper("");
|
||||
|
||||
foo(wrapped_bar);
|
||||
foo(&wrapped_bar);
|
||||
}
|
||||
}
|
||||
|
||||
mod issue_9841 {
|
||||
fn takes_array_ref<T, const N: usize>(array: &&[T; N]) {
|
||||
takes_slice(array)
|
||||
takes_slice(*array)
|
||||
}
|
||||
|
||||
fn takes_array_ref_ref<T, const N: usize>(array: &&&[T; N]) {
|
||||
takes_slice(**array)
|
||||
}
|
||||
|
||||
fn takes_slice<T>(slice: &[T]) {
|
||||
|
@ -373,6 +373,10 @@ mod issue_9841 {
|
||||
takes_slice(*array)
|
||||
}
|
||||
|
||||
fn takes_array_ref_ref<T, const N: usize>(array: &&&[T; N]) {
|
||||
takes_slice(**array)
|
||||
}
|
||||
|
||||
fn takes_slice<T>(slice: &[T]) {
|
||||
todo!()
|
||||
}
|
||||
|
@ -275,13 +275,7 @@ error: deref which would be done by auto-deref
|
||||
--> tests/ui/explicit_auto_deref.rs:367:13
|
||||
|
|
||||
LL | foo(&*wrapped_bar);
|
||||
| ^^^^^^^^^^^^^ help: try: `wrapped_bar`
|
||||
| ^^^^^^^^^^^^^ help: try: `&wrapped_bar`
|
||||
|
||||
error: deref which would be done by auto-deref
|
||||
--> tests/ui/explicit_auto_deref.rs:373:21
|
||||
|
|
||||
LL | takes_slice(*array)
|
||||
| ^^^^^^ help: try: `array`
|
||||
|
||||
error: aborting due to 47 previous errors
|
||||
error: aborting due to 46 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user