mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-14 00:47:16 +00:00
Resolve conflicts produced by GenericArgs
Addresses the move/zip of Lifetimes and Types vectors from hir::PathParameters into the args vector of GenericArgs
This commit is contained in:
parent
d9a80d2f84
commit
c83fd39e0e
9 changed files with 86 additions and 29 deletions
|
@ -119,12 +119,15 @@ fn check_fn_inner<'a, 'tcx>(
|
|||
.expect("a path must have at least one segment")
|
||||
.args;
|
||||
if let Some(ref params) = *params {
|
||||
for bound in ¶ms.lifetimes {
|
||||
if bound.name.name() != "'static" && !bound.is_elided() {
|
||||
return;
|
||||
}
|
||||
bounds_lts.push(bound);
|
||||
}
|
||||
params.args.iter().for_each(|param| match param {
|
||||
GenericArg::Lifetime(bound) => {
|
||||
if bound.name.name() != "'static" && !bound.is_elided() {
|
||||
return;
|
||||
}
|
||||
bounds_lts.push(bound);
|
||||
},
|
||||
_ => {},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,9 +236,9 @@ fn could_use_elision<'a, 'tcx: 'a>(
|
|||
fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet<RefLt> {
|
||||
let mut allowed_lts = HashSet::new();
|
||||
for par in named_generics.iter() {
|
||||
if let GenericParam::Lifetime(ref lt) = *par {
|
||||
if lt.bounds.is_empty() {
|
||||
allowed_lts.insert(RefLt::Named(lt.lifetime.name.name()));
|
||||
if let GenericParamKind::Lifetime { .. } = par.kind {
|
||||
if par.bounds.is_empty() {
|
||||
allowed_lts.insert(RefLt::Named(par.name.name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +302,11 @@ impl<'v, 't> RefVisitor<'v, 't> {
|
|||
|
||||
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
|
||||
if let Some(ref last_path_segment) = last_path_segment(qpath).args {
|
||||
if !last_path_segment.parenthesized && last_path_segment.lifetimes.is_empty() {
|
||||
if !last_path_segment.parenthesized
|
||||
&& !last_path_segment.args.iter().any(|arg| match arg {
|
||||
GenericArg::Lifetime(_) => true,
|
||||
GenericArg::Type(_) => false,
|
||||
}) {
|
||||
let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id);
|
||||
match self.cx.tables.qpath_def(qpath, hir_id) {
|
||||
Def::TyAlias(def_id) | Def::Struct(def_id) => {
|
||||
|
@ -431,9 +438,11 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
|
|||
}
|
||||
|
||||
fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl, generics: &'tcx Generics) {
|
||||
let hs = generics
|
||||
.lifetimes()
|
||||
.map(|lt| (lt.lifetime.name.name(), lt.lifetime.span))
|
||||
let hs = generics.params.iter()
|
||||
.filter_map(|par| match par.kind {
|
||||
GenericParamKind::Lifetime { .. } => Some((par.name.name(), par.span)),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
let mut checker = LifetimeChecker { map: hs };
|
||||
|
||||
|
|
|
@ -2101,8 +2101,14 @@ fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Gener
|
|||
if params.parenthesized {
|
||||
false
|
||||
} else {
|
||||
params.types.len() == 1
|
||||
&& (is_self_ty(¶ms.types[0]) || is_ty(&*params.types[0], self_ty))
|
||||
// FIXME(flip1995): messy, improve if there is a better option
|
||||
// in the compiler
|
||||
let types: Vec<_> = params.args.iter().filter_map(|arg| match arg {
|
||||
hir::GenericArg::Type(ty) => Some(ty),
|
||||
_ => None,
|
||||
}).collect();
|
||||
types.len() == 1
|
||||
&& (is_self_ty(&types[0]) || is_ty(&*types[0], self_ty))
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -219,7 +219,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
if let Some(elem_ty) = path.segments.iter()
|
||||
.find(|seg| seg.name == "Vec")
|
||||
.and_then(|ps| ps.args.as_ref())
|
||||
.map(|params| ¶ms.types[0]);
|
||||
.map(|params| params.args.iter().find_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
}).unwrap());
|
||||
then {
|
||||
let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_"));
|
||||
db.span_suggestion(input.span,
|
||||
|
|
|
@ -161,9 +161,14 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
|
|||
if_chain! {
|
||||
if let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node;
|
||||
if let Some(&PathSegment{args: Some(ref parameters), ..}) = path.segments.last();
|
||||
if parameters.types.len() == 1;
|
||||
then {
|
||||
ty_snippet = snippet_opt(cx, parameters.types[0].span);
|
||||
let types: Vec<_> = parameters.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
_ => None,
|
||||
}).collect();
|
||||
if types.len() == 1 {
|
||||
ty_snippet = snippet_opt(cx, types[0].span);
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(spans) = get_spans(cx, opt_body_id, idx, &[("clone", ".to_owned()")]) {
|
||||
|
@ -220,7 +225,8 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId, opt_body_id: Option<
|
|||
if let [ref bx] = *pp.segments;
|
||||
if let Some(ref params) = bx.args;
|
||||
if !params.parenthesized;
|
||||
if let [ref inner] = *params.types;
|
||||
if let [ref inner] = *params.args;
|
||||
if let GenericArg::Type(inner) = inner;
|
||||
then {
|
||||
let replacement = snippet_opt(cx, inner.span);
|
||||
if let Some(r) = replacement {
|
||||
|
|
|
@ -457,7 +457,10 @@ fn get_type_snippet(cx: &LateContext, path: &QPath, to_ref_ty: Ty) -> String {
|
|||
if_chain! {
|
||||
if let Some(ref params) = seg.args;
|
||||
if !params.parenthesized;
|
||||
if let Some(to_ty) = params.types.get(1);
|
||||
if let Some(to_ty) = params.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
}).nth(1);
|
||||
if let TyRptr(_, ref to_ty) = to_ty.node;
|
||||
then {
|
||||
return snippet(cx, to_ty.ty.span, &to_ref_ty.to_string()).to_string();
|
||||
|
|
|
@ -182,7 +182,10 @@ fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool
|
|||
if_chain! {
|
||||
if let Some(ref params) = last.args;
|
||||
if !params.parenthesized;
|
||||
if let Some(ty) = params.types.get(0);
|
||||
if let Some(ty) = params.args.iter().find_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
});
|
||||
if let TyPath(ref qpath) = ty.node;
|
||||
if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(ty.id)));
|
||||
if match_def_path(cx.tcx, did, path);
|
||||
|
@ -246,7 +249,11 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
|
|||
for ty in p.segments.iter().flat_map(|seg| {
|
||||
seg.args
|
||||
.as_ref()
|
||||
.map_or_else(|| [].iter(), |params| params.types.iter())
|
||||
.map_or_else(|| [].iter(), |params| params.args.iter())
|
||||
.filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
})
|
||||
}) {
|
||||
check_ty(cx, ty, is_local);
|
||||
}
|
||||
|
@ -254,14 +261,21 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
|
|||
QPath::Resolved(None, ref p) => for ty in p.segments.iter().flat_map(|seg| {
|
||||
seg.args
|
||||
.as_ref()
|
||||
.map_or_else(|| [].iter(), |params| params.types.iter())
|
||||
.map_or_else(|| [].iter(), |params| params.args.iter())
|
||||
.filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
})
|
||||
}) {
|
||||
check_ty(cx, ty, is_local);
|
||||
},
|
||||
QPath::TypeRelative(ref ty, ref seg) => {
|
||||
check_ty(cx, ty, is_local);
|
||||
if let Some(ref params) = seg.args {
|
||||
for ty in params.types.iter() {
|
||||
for ty in params.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
}) {
|
||||
check_ty(cx, ty, is_local);
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +304,8 @@ fn check_ty_rptr(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool, lt: &Lifeti
|
|||
if let [ref bx] = *path.segments;
|
||||
if let Some(ref params) = bx.args;
|
||||
if !params.parenthesized;
|
||||
if let [ref inner] = *params.types;
|
||||
if let [ref inner] = *params.args;
|
||||
if let GenericArg::Type(inner) = inner;
|
||||
then {
|
||||
if is_any_trait(inner) {
|
||||
// Ignore `Box<Any>` types, see #1884 for details.
|
||||
|
@ -1862,7 +1877,11 @@ impl<'tcx> ImplicitHasherType<'tcx> {
|
|||
/// Checks that `ty` is a target type without a BuildHasher.
|
||||
fn new<'a>(cx: &LateContext<'a, 'tcx>, hir_ty: &hir::Ty) -> Option<Self> {
|
||||
if let TyPath(QPath::Resolved(None, ref path)) = hir_ty.node {
|
||||
let params = &path.segments.last().as_ref()?.args.as_ref()?.types;
|
||||
let params: Vec<_> = path.segments.last().as_ref()?.args.as_ref()?
|
||||
.args.iter().filter_map(|arg| match arg {
|
||||
GenericArg::Type(ty) => Some(ty),
|
||||
GenericArg::Lifetime(_) => None,
|
||||
}).collect();
|
||||
let params_len = params.len();
|
||||
|
||||
let ty = hir_ty_to_ty(cx.tcx, hir_ty);
|
||||
|
|
|
@ -60,7 +60,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
|
|||
then {
|
||||
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
|
||||
let should_check = if let Some(ref params) = *parameters {
|
||||
!params.parenthesized && params.lifetimes.len() == 0
|
||||
!params.parenthesized && !params.args.iter().any(|arg| match arg {
|
||||
GenericArg::Lifetime(_) => true,
|
||||
GenericArg::Type(_) => false,
|
||||
})
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
|
|
@ -152,6 +152,14 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
left.ident.name == right.ident.name && self.eq_expr(&left.expr, &right.expr)
|
||||
}
|
||||
|
||||
fn eq_generic_arg(&mut self, left: &GenericArg, right: &GenericArg) -> bool {
|
||||
match (left, right) {
|
||||
(GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => self.eq_lifetime(l_lt, r_lt),
|
||||
(GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_lifetime(&mut self, left: &Lifetime, right: &Lifetime) -> bool {
|
||||
left.name == right.name
|
||||
}
|
||||
|
@ -203,8 +211,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
|
|||
|
||||
fn eq_path_parameters(&mut self, left: &GenericArgs, right: &GenericArgs) -> bool {
|
||||
if !(left.parenthesized || right.parenthesized) {
|
||||
over(&left.lifetimes, &right.lifetimes, |l, r| self.eq_lifetime(l, r))
|
||||
&& over(&left.types, &right.types, |l, r| self.eq_ty(l, r))
|
||||
over(&left.args, &right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work
|
||||
&& over(&left.bindings, &right.bindings, |l, r| self.eq_type_binding(l, r))
|
||||
} else if left.parenthesized && right.parenthesized {
|
||||
over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r))
|
||||
|
|
|
@ -100,6 +100,7 @@ impl<'a> Sugg<'a> {
|
|||
ast::ExprKind::ObsoleteInPlace(..) |
|
||||
ast::ExprKind::Unary(..) |
|
||||
ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
|
||||
ast::ExprKind::Async(..) |
|
||||
ast::ExprKind::Block(..) |
|
||||
ast::ExprKind::Break(..) |
|
||||
ast::ExprKind::Call(..) |
|
||||
|
|
Loading…
Reference in a new issue