Skip to content

Commit d4618e0

Browse files
authored
Merge pull request #2871 from flip1995/gen_gen_nightly
The Great Generics Generalisation: Clippy edition
2 parents 5f5fa08 + 203ad28 commit d4618e0

23 files changed

+179
-104
lines changed

clippy_lints/src/attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
207207
}
208208

209209
fn is_relevant_item(tcx: TyCtxt, item: &Item) -> bool {
210-
if let ItemFn(_, _, _, _, _, eid) = item.node {
210+
if let ItemFn(_, _, _, eid) = item.node {
211211
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
212212
} else {
213213
true

clippy_lints/src/eval_order_dependence.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
124124
impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
125125
fn visit_expr(&mut self, e: &'tcx Expr) {
126126
match e.node {
127-
ExprAgain(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
127+
ExprContinue(_) | ExprBreak(_, _) | ExprRet(_) => self.report_diverging_sub_expr(e),
128128
ExprCall(ref func, _) => {
129129
let typ = self.cx.tables.expr_ty(func);
130130
match typ.sty {

clippy_lints/src/functions.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
9292
};
9393

9494
let unsafety = match kind {
95-
hir::intravisit::FnKind::ItemFn(_, _, unsafety, _, _, _, _) => unsafety,
96-
hir::intravisit::FnKind::Method(_, sig, _, _) => sig.unsafety,
95+
hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _, _) => unsafety,
96+
hir::intravisit::FnKind::Method(_, sig, _, _) => sig.header.unsafety,
9797
hir::intravisit::FnKind::Closure(_) => return,
9898
};
9999

100100
// don't warn for implementations, it's not their fault
101101
if !is_impl {
102102
// don't lint extern functions decls, it's not their fault either
103103
match kind {
104-
hir::intravisit::FnKind::Method(_, &hir::MethodSig { abi: Abi::Rust, .. }, _, _) |
105-
hir::intravisit::FnKind::ItemFn(_, _, _, _, Abi::Rust, _, _) => self.check_arg_number(cx, decl, span),
104+
hir::intravisit::FnKind::Method(_, &hir::MethodSig { header: hir::FnHeader { abi: Abi::Rust, .. }, .. }, _, _) |
105+
hir::intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _, _) => self.check_arg_number(cx, decl, span),
106106
_ => {},
107107
}
108108
}
@@ -113,13 +113,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
113113
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
114114
if let hir::TraitItemKind::Method(ref sig, ref eid) = item.node {
115115
// don't lint extern functions decls, it's not their fault
116-
if sig.abi == Abi::Rust {
116+
if sig.header.abi == Abi::Rust {
117117
self.check_arg_number(cx, &sig.decl, item.span);
118118
}
119119

120120
if let hir::TraitMethod::Provided(eid) = *eid {
121121
let body = cx.tcx.hir.body(eid);
122-
self.check_raw_ptr(cx, sig.unsafety, &sig.decl, body, item.id);
122+
self.check_raw_ptr(cx, sig.header.unsafety, &sig.decl, body, item.id);
123123
}
124124
}
125125
}

clippy_lints/src/lifetimes.rs

+31-17
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl LintPass for LifetimePass {
5959

6060
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
6161
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
62-
if let ItemFn(ref decl, _, _, _, ref generics, id) = item.node {
62+
if let ItemFn(ref decl, _, ref generics, id) = item.node {
6363
check_fn_inner(cx, decl, Some(id), generics, item.span);
6464
}
6565
}
@@ -101,23 +101,31 @@ fn check_fn_inner<'a, 'tcx>(
101101
}
102102

103103
let mut bounds_lts = Vec::new();
104-
for typ in generics.ty_params() {
104+
let types = generics.params.iter().filter_map(|param| match param.kind {
105+
GenericParamKind::Type { .. } => Some(param),
106+
GenericParamKind::Lifetime { .. } => None,
107+
});
108+
for typ in types {
105109
for bound in &typ.bounds {
106110
let mut visitor = RefVisitor::new(cx);
107-
walk_ty_param_bound(&mut visitor, bound);
111+
walk_param_bound(&mut visitor, bound);
108112
if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
109113
return;
110114
}
111-
if let TraitTyParamBound(ref trait_ref, _) = *bound {
115+
if let GenericBound::Trait(ref trait_ref, _) = *bound {
112116
let params = &trait_ref
113117
.trait_ref
114118
.path
115119
.segments
116120
.last()
117121
.expect("a path must have at least one segment")
118-
.parameters;
122+
.args;
119123
if let Some(ref params) = *params {
120-
for bound in &params.lifetimes {
124+
let lifetimes = params.args.iter().filter_map(|arg| match arg {
125+
GenericArg::Lifetime(lt) => Some(lt),
126+
GenericArg::Type(_) => None,
127+
});
128+
for bound in lifetimes {
121129
if bound.name.name() != "'static" && !bound.is_elided() {
122130
return;
123131
}
@@ -230,9 +238,9 @@ fn could_use_elision<'a, 'tcx: 'a>(
230238
fn allowed_lts_from(named_generics: &[GenericParam]) -> HashSet<RefLt> {
231239
let mut allowed_lts = HashSet::new();
232240
for par in named_generics.iter() {
233-
if let GenericParam::Lifetime(ref lt) = *par {
234-
if lt.bounds.is_empty() {
235-
allowed_lts.insert(RefLt::Named(lt.lifetime.name.name()));
241+
if let GenericParamKind::Lifetime { .. } = par.kind {
242+
if par.bounds.is_empty() {
243+
allowed_lts.insert(RefLt::Named(par.name.name()));
236244
}
237245
}
238246
}
@@ -295,8 +303,12 @@ impl<'v, 't> RefVisitor<'v, 't> {
295303
}
296304

297305
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
298-
if let Some(ref last_path_segment) = last_path_segment(qpath).parameters {
299-
if !last_path_segment.parenthesized && last_path_segment.lifetimes.is_empty() {
306+
if let Some(ref last_path_segment) = last_path_segment(qpath).args {
307+
if !last_path_segment.parenthesized
308+
&& !last_path_segment.args.iter().any(|arg| match arg {
309+
GenericArg::Lifetime(_) => true,
310+
GenericArg::Type(_) => false,
311+
}) {
300312
let hir_id = self.cx.tcx.hir.node_to_hir_id(ty.id);
301313
match self.cx.tables.qpath_def(qpath, hir_id) {
302314
Def::TyAlias(def_id) | Def::Struct(def_id) => {
@@ -335,7 +347,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
335347
TyImplTraitExistential(exist_ty_id, _, _) => {
336348
if let ItemExistential(ref exist_ty) = self.cx.tcx.hir.expect_item(exist_ty_id.id).node {
337349
for bound in &exist_ty.bounds {
338-
if let RegionTyParamBound(_) = *bound {
350+
if let GenericBound::Outlives(_) = *bound {
339351
self.record(&None);
340352
}
341353
}
@@ -377,7 +389,7 @@ fn has_where_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, where_clause: &
377389
let allowed_lts = allowed_lts_from(&pred.bound_generic_params);
378390
// now walk the bounds
379391
for bound in pred.bounds.iter() {
380-
walk_ty_param_bound(&mut visitor, bound);
392+
walk_param_bound(&mut visitor, bound);
381393
}
382394
// and check that all lifetimes are allowed
383395
match visitor.into_vec() {
@@ -418,7 +430,7 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
418430
// don't want to spuriously remove them
419431
// `'b` in `'a: 'b` is useless unless used elsewhere in
420432
// a non-lifetime bound
421-
if param.is_type_param() {
433+
if let GenericParamKind::Type { .. } = param.kind {
422434
walk_generic_param(self, param)
423435
}
424436
}
@@ -428,9 +440,11 @@ impl<'tcx> Visitor<'tcx> for LifetimeChecker {
428440
}
429441

430442
fn report_extra_lifetimes<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, func: &'tcx FnDecl, generics: &'tcx Generics) {
431-
let hs = generics
432-
.lifetimes()
433-
.map(|lt| (lt.lifetime.name.name(), lt.lifetime.span))
443+
let hs = generics.params.iter()
444+
.filter_map(|par| match par.kind {
445+
GenericParamKind::Lifetime { .. } => Some((par.name.name(), par.span)),
446+
_ => None,
447+
})
434448
.collect();
435449
let mut checker = LifetimeChecker { map: hs };
436450

clippy_lints/src/loops.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ fn never_loop_expr(expr: &Expr, main_loop_id: NodeId) -> NeverLoopResult {
640640
}
641641
},
642642
ExprBlock(ref b, _) => never_loop_block(b, main_loop_id),
643-
ExprAgain(d) => {
643+
ExprContinue(d) => {
644644
let id = d.target_id
645645
.expect("target id can only be missing in the presence of compilation errors");
646646
if id == main_loop_id {

clippy_lints/src/map_clone.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn expr_eq_name(expr: &Expr, id: ast::Name) -> bool {
104104
let arg_segment = [
105105
PathSegment {
106106
name: id,
107-
parameters: None,
107+
args: None,
108108
infer_types: true,
109109
},
110110
];

clippy_lints/src/methods.rs

+31-22
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::fmt;
77
use std::iter;
88
use syntax::ast;
99
use syntax::codemap::{Span, BytePos};
10-
use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self,
10+
use crate::utils::{get_arg_name, get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, is_expn_of, is_self,
1111
is_self_ty, iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method,
1212
match_type, method_chain_args, match_var, return_ty, remove_blocks, same_tys, single_segment_path, snippet,
1313
span_lint, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
@@ -336,7 +336,7 @@ declare_clippy_lint! {
336336
///
337337
/// **Known problems:** If the function has side-effects, not calling it will
338338
/// change the semantic of the program, but you shouldn't rely on that anyway.
339-
///
339+
///
340340
/// **Example:**
341341
/// ```rust
342342
/// foo.expect(&format("Err {}: {}", err_code, err_msg))
@@ -1020,7 +1020,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n
10201020
}
10211021
}
10221022
};
1023-
1023+
10241024
snippet(cx, a.span, "..").into_owned()
10251025
}
10261026

@@ -1077,7 +1077,7 @@ fn lint_expect_fun_call(cx: &LateContext, expr: &hir::Expr, method_span: Span, n
10771077
}
10781078

10791079
let sugg: Cow<_> = snippet(cx, arg.span, "..");
1080-
1080+
10811081
span_lint_and_sugg(
10821082
cx,
10831083
EXPECT_FUN_CALL,
@@ -2091,26 +2091,35 @@ impl SelfKind {
20912091

20922092
fn is_as_ref_or_mut_trait(ty: &hir::Ty, self_ty: &hir::Ty, generics: &hir::Generics, name: &[&str]) -> bool {
20932093
single_segment_ty(ty).map_or(false, |seg| {
2094-
generics.ty_params().any(|param| {
2095-
param.name == seg.name && param.bounds.iter().any(|bound| {
2096-
if let hir::TyParamBound::TraitTyParamBound(ref ptr, ..) = *bound {
2097-
let path = &ptr.trait_ref.path;
2098-
match_path(path, name) && path.segments.last().map_or(false, |s| {
2099-
if let Some(ref params) = s.parameters {
2100-
if params.parenthesized {
2101-
false
2094+
generics.params.iter().any(|param| match param.kind {
2095+
hir::GenericParamKind::Type { .. } => {
2096+
param.name.name() == seg.name && param.bounds.iter().any(|bound| {
2097+
if let hir::GenericBound::Trait(ref ptr, ..) = *bound {
2098+
let path = &ptr.trait_ref.path;
2099+
match_path(path, name) && path.segments.last().map_or(false, |s| {
2100+
if let Some(ref params) = s.args {
2101+
if params.parenthesized {
2102+
false
2103+
} else {
2104+
// FIXME(flip1995): messy, improve if there is a better option
2105+
// in the compiler
2106+
let types: Vec<_> = params.args.iter().filter_map(|arg| match arg {
2107+
hir::GenericArg::Type(ty) => Some(ty),
2108+
_ => None,
2109+
}).collect();
2110+
types.len() == 1
2111+
&& (is_self_ty(&types[0]) || is_ty(&*types[0], self_ty))
2112+
}
21022113
} else {
2103-
params.types.len() == 1
2104-
&& (is_self_ty(&params.types[0]) || is_ty(&*params.types[0], self_ty))
2114+
false
21052115
}
2106-
} else {
2107-
false
2108-
}
2109-
})
2110-
} else {
2111-
false
2112-
}
2113-
})
2116+
})
2117+
} else {
2118+
false
2119+
}
2120+
})
2121+
},
2122+
_ => false,
21142123
})
21152124
})
21162125
}

clippy_lints/src/misc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool {
558558
.ctxt()
559559
.outer()
560560
.expn_info()
561-
.map_or(false, |info| matches!(info.callee.format, ExpnFormat::MacroAttribute(_)))
561+
.map_or(false, |info| matches!(info.format, ExpnFormat::MacroAttribute(_)))
562562
}
563563

564564
/// Test whether `def` is a variable defined outside a macro.

clippy_lints/src/misc_early.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,13 @@ impl LintPass for MiscEarly {
189189
impl EarlyLintPass for MiscEarly {
190190
fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
191191
for param in &gen.params {
192-
if let GenericParam::Type(ref ty) = *param {
193-
let name = ty.ident.name.as_str();
192+
if let GenericParamKind::Type { .. } = param.kind {
193+
let name = param.ident.name.as_str();
194194
if constants::BUILTIN_TYPES.contains(&&*name) {
195195
span_lint(
196196
cx,
197197
BUILTIN_TYPE_SHADOW,
198-
ty.ident.span,
198+
param.ident.span,
199199
&format!("This generic shadows the built-in type `{}`", name),
200200
);
201201
}
@@ -296,7 +296,7 @@ impl EarlyLintPass for MiscEarly {
296296
}
297297
match expr.node {
298298
ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
299-
if let ExprKind::Closure(_, _, ref decl, ref block, _) = closure.node {
299+
if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.node {
300300
span_lint_and_then(
301301
cx,
302302
REDUNDANT_CLOSURE_CALL,
@@ -327,7 +327,7 @@ impl EarlyLintPass for MiscEarly {
327327
if_chain! {
328328
if let StmtKind::Local(ref local) = w[0].node;
329329
if let Option::Some(ref t) = local.init;
330-
if let ExprKind::Closure(_, _, _, _, _) = t.node;
330+
if let ExprKind::Closure(..) = t.node;
331331
if let PatKind::Ident(_, ident, _) = local.pat.node;
332332
if let StmtKind::Semi(ref second) = w[1].node;
333333
if let ExprKind::Assign(_, ref call) = second.node;

clippy_lints/src/needless_pass_by_value.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
7272
}
7373

7474
match kind {
75-
FnKind::ItemFn(.., abi, _, attrs) => {
76-
if abi != Abi::Rust {
75+
FnKind::ItemFn(.., header, _, attrs) => {
76+
if header.abi != Abi::Rust {
7777
return;
7878
}
7979
for a in attrs {
@@ -218,8 +218,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
218218
if let TyPath(QPath::Resolved(_, ref path)) = input.node;
219219
if let Some(elem_ty) = path.segments.iter()
220220
.find(|seg| seg.name == "Vec")
221-
.and_then(|ps| ps.parameters.as_ref())
222-
.map(|params| &params.types[0]);
221+
.and_then(|ps| ps.args.as_ref())
222+
.map(|params| params.args.iter().find_map(|arg| match arg {
223+
GenericArg::Type(ty) => Some(ty),
224+
GenericArg::Lifetime(_) => None,
225+
}).unwrap());
223226
then {
224227
let slice_ty = format!("&[{}]", snippet(cx, elem_ty.span, "_"));
225228
db.span_suggestion(input.span,

clippy_lints/src/new_without_default.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
9999
if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node {
100100
let name = impl_item.name;
101101
let id = impl_item.id;
102-
if sig.constness == hir::Constness::Const {
102+
if sig.header.constness == hir::Constness::Const {
103103
// can't be implemented by default
104104
return;
105105
}
106-
if impl_item.generics.params.iter().any(|gen| gen.is_type_param()) {
106+
if impl_item.generics.params.iter().any(|gen| match gen.kind {
107+
hir::GenericParamKind::Type { .. } => true,
108+
_ => false
109+
}) {
107110
// when the result of `new()` depends on a type parameter we should not require
108111
// an
109112
// impl of `Default`

clippy_lints/src/non_expressive_names.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
312312

313313
impl EarlyLintPass for NonExpressiveNames {
314314
fn check_item(&mut self, cx: &EarlyContext, item: &Item) {
315-
if let ItemKind::Fn(ref decl, _, _, _, _, ref blk) = item.node {
315+
if let ItemKind::Fn(ref decl, _, _, ref blk) = item.node {
316316
do_check(self, cx, &item.attrs, decl, blk);
317317
}
318318
}

0 commit comments

Comments
 (0)