mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
Fix #8507
This commit is contained in:
parent
ce841fe73b
commit
1a95590faf
4 changed files with 112 additions and 2 deletions
|
@ -2,7 +2,9 @@ use super::implicit_clone::is_clone_like;
|
||||||
use super::unnecessary_iter_cloned::{self, is_into_iter};
|
use super::unnecessary_iter_cloned::{self, is_into_iter};
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::ty::{get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs};
|
use clippy_utils::ty::{
|
||||||
|
contains_ty, get_associated_type, get_iterator_item_ty, implements_trait, is_copy, peel_mid_ty_refs,
|
||||||
|
};
|
||||||
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item};
|
use clippy_utils::{fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind};
|
use rustc_hir::{def_id::DefId, BorrowKind, Expr, ExprKind};
|
||||||
|
@ -260,6 +262,12 @@ fn check_other_call_arg<'tcx>(
|
||||||
// `Target = T`.
|
// `Target = T`.
|
||||||
if n_refs > 0 || is_copy(cx, receiver_ty) || trait_predicate.def_id() != deref_trait_id;
|
if n_refs > 0 || is_copy(cx, receiver_ty) || trait_predicate.def_id() != deref_trait_id;
|
||||||
let n_refs = max(n_refs, if is_copy(cx, receiver_ty) { 0 } else { 1 });
|
let n_refs = max(n_refs, if is_copy(cx, receiver_ty) { 0 } else { 1 });
|
||||||
|
// If the trait is `AsRef` and the input type variable `T` occurs in the output type, then
|
||||||
|
// `T` must not be instantiated with a reference
|
||||||
|
// (https://github.com/rust-lang/rust-clippy/issues/8507).
|
||||||
|
if (n_refs == 0 && !receiver_ty.is_ref())
|
||||||
|
|| trait_predicate.def_id() != as_ref_trait_id
|
||||||
|
|| !contains_ty(fn_sig.output(), input);
|
||||||
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
|
if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
|
||||||
then {
|
then {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
|
|
@ -212,3 +212,51 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_string(_: &String) {}
|
fn require_string(_: &String) {}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/8507
|
||||||
|
mod issue_8507 {
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
struct Opaque<P>(P);
|
||||||
|
|
||||||
|
pub trait Abstracted {}
|
||||||
|
|
||||||
|
impl<P> Abstracted for Opaque<P> {}
|
||||||
|
|
||||||
|
fn build<P>(p: P) -> Opaque<P>
|
||||||
|
where
|
||||||
|
P: AsRef<str>,
|
||||||
|
{
|
||||||
|
Opaque(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not lint.
|
||||||
|
fn test_str(s: &str) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(s.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not lint.
|
||||||
|
fn test_x(x: super::X) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Y(&'static str);
|
||||||
|
|
||||||
|
impl AsRef<str> for Y {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Y {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.0.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should lint because Y is copy.
|
||||||
|
fn test_y(y: Y) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -212,3 +212,51 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_string(_: &String) {}
|
fn require_string(_: &String) {}
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust-clippy/issues/8507
|
||||||
|
mod issue_8507 {
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
struct Opaque<P>(P);
|
||||||
|
|
||||||
|
pub trait Abstracted {}
|
||||||
|
|
||||||
|
impl<P> Abstracted for Opaque<P> {}
|
||||||
|
|
||||||
|
fn build<P>(p: P) -> Opaque<P>
|
||||||
|
where
|
||||||
|
P: AsRef<str>,
|
||||||
|
{
|
||||||
|
Opaque(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not lint.
|
||||||
|
fn test_str(s: &str) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(s.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should not lint.
|
||||||
|
fn test_x(x: super::X) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
struct Y(&'static str);
|
||||||
|
|
||||||
|
impl AsRef<str> for Y {
|
||||||
|
fn as_ref(&self) -> &str {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Y {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.0.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should lint because Y is copy.
|
||||||
|
fn test_y(y: Y) -> Box<dyn Abstracted> {
|
||||||
|
Box::new(build(y.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -491,5 +491,11 @@ LL - let path = match get_file_path(&t) {
|
||||||
LL + let path = match get_file_path(t) {
|
LL + let path = match get_file_path(t) {
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 76 previous errors
|
error: unnecessary use of `to_string`
|
||||||
|
--> $DIR/unnecessary_to_owned.rs:260:24
|
||||||
|
|
|
||||||
|
LL | Box::new(build(y.to_string()))
|
||||||
|
| ^^^^^^^^^^^^^ help: use: `y`
|
||||||
|
|
||||||
|
error: aborting due to 77 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue