mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 23:24:24 +00:00
Merge branch 'origin/master' into suspicious_map
This commit is contained in:
commit
5df84f2192
26 changed files with 155 additions and 176 deletions
14
PUBLISH.md
14
PUBLISH.md
|
@ -1,14 +0,0 @@
|
|||
Steps to publish a new Clippy version
|
||||
|
||||
- Bump `package.version` in `./Cargo.toml` (no need to manually bump `dependencies.clippy_lints.version`).
|
||||
- Write a changelog entry.
|
||||
- Run `./pre_publish.sh`
|
||||
- Review and commit all changed files
|
||||
- `git push`
|
||||
- Wait for Travis's approval.
|
||||
- Merge.
|
||||
- `cargo publish` in `./clippy_lints`.
|
||||
- `cargo publish` in the root directory.
|
||||
- `git pull`.
|
||||
- `git tag -s v0.0.X -m "v0.0.X"`.
|
||||
- `git push --tags`.
|
|
@ -1,11 +1,9 @@
|
|||
use if_chain::if_chain;
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint_pass, declare_tool_lint};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use crate::consts::{constant, Constant};
|
||||
use crate::utils::{in_macro_or_desugar, is_direct_expn_of, span_help_and_lint};
|
||||
use crate::utils::{in_macro_or_desugar, is_direct_expn_of, is_expn_of, span_help_and_lint};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
|
||||
|
@ -33,42 +31,39 @@ declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
let mut is_debug_assert = false;
|
||||
let debug_assert_not_in_macro_or_desugar = |span: Span| {
|
||||
is_debug_assert = true;
|
||||
// Check that `debug_assert!` itself is not inside a macro
|
||||
!in_macro_or_desugar(span)
|
||||
};
|
||||
if_chain! {
|
||||
if let Some(assert_span) = is_direct_expn_of(e.span, "assert");
|
||||
if !in_macro_or_desugar(assert_span)
|
||||
|| is_direct_expn_of(assert_span, "debug_assert")
|
||||
.map_or(false, debug_assert_not_in_macro_or_desugar);
|
||||
if let ExprKind::Unary(_, ref lit) = e.node;
|
||||
if let Some(bool_const) = constant(cx, cx.tables, lit);
|
||||
then {
|
||||
match bool_const.0 {
|
||||
Constant::Bool(true) => {
|
||||
let lint_assert_cb = |is_debug_assert: bool| {
|
||||
if let ExprKind::Unary(_, ref lit) = e.node {
|
||||
if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, lit) {
|
||||
if is_true {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
ASSERTIONS_ON_CONSTANTS,
|
||||
e.span,
|
||||
"`assert!(true)` will be optimized out by the compiler",
|
||||
"remove it"
|
||||
"remove it",
|
||||
);
|
||||
},
|
||||
Constant::Bool(false) if !is_debug_assert => {
|
||||
} else if !is_debug_assert {
|
||||
span_help_and_lint(
|
||||
cx,
|
||||
ASSERTIONS_ON_CONSTANTS,
|
||||
e.span,
|
||||
"`assert!(false)` should probably be replaced",
|
||||
"use `panic!()` or `unreachable!()`"
|
||||
"use `panic!()` or `unreachable!()`",
|
||||
);
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(debug_assert_span) = is_expn_of(e.span, "debug_assert") {
|
||||
if in_macro_or_desugar(debug_assert_span) {
|
||||
return;
|
||||
}
|
||||
lint_assert_cb(true);
|
||||
} else if let Some(assert_span) = is_direct_expn_of(e.span, "assert") {
|
||||
if in_macro_or_desugar(assert_span) {
|
||||
return;
|
||||
}
|
||||
lint_assert_cb(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,16 +298,16 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> FxHashMap<LocalI
|
|||
bindings_impl(cx, as_pat, map);
|
||||
}
|
||||
},
|
||||
PatKind::Struct(_, ref fields, _) => {
|
||||
for pat in fields {
|
||||
bindings_impl(cx, &pat.node.pat, map);
|
||||
}
|
||||
},
|
||||
PatKind::Tuple(ref fields, _) => {
|
||||
PatKind::Or(ref fields) | PatKind::Tuple(ref fields, _) => {
|
||||
for pat in fields {
|
||||
bindings_impl(cx, pat, map);
|
||||
}
|
||||
},
|
||||
PatKind::Struct(_, ref fields, _) => {
|
||||
for pat in fields {
|
||||
bindings_impl(cx, &pat.pat, map);
|
||||
}
|
||||
},
|
||||
PatKind::Slice(ref lhs, ref mid, ref rhs) => {
|
||||
for pat in lhs {
|
||||
bindings_impl(cx, pat, map);
|
||||
|
|
|
@ -31,8 +31,8 @@ declare_lint_pass!(DbgMacro => [DBG_MACRO]);
|
|||
|
||||
impl EarlyLintPass for DbgMacro {
|
||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) {
|
||||
if mac.node.path == sym!(dbg) {
|
||||
if let Some(sugg) = tts_span(mac.node.tts.clone()).and_then(|span| snippet_opt(cx, span)) {
|
||||
if mac.path == sym!(dbg) {
|
||||
if let Some(sugg) = tts_span(mac.tts.clone()).and_then(|span| snippet_opt(cx, span)) {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
DBG_MACRO,
|
||||
|
|
|
@ -445,7 +445,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
reg.register_early_lint_pass(box utils::internal_lints::ClippyLintsInternal);
|
||||
reg.register_late_lint_pass(box utils::internal_lints::CompilerLintFunctions::new());
|
||||
reg.register_late_lint_pass(box utils::internal_lints::LintWithoutLintPass::default());
|
||||
reg.register_late_lint_pass(box utils::internal_lints::OuterExpnInfoPass);
|
||||
reg.register_late_lint_pass(box utils::internal_lints::OuterExpnDataPass);
|
||||
reg.register_late_lint_pass(box utils::inspector::DeepCodeInspector);
|
||||
reg.register_late_lint_pass(box utils::author::Author);
|
||||
reg.register_late_lint_pass(box types::Types);
|
||||
|
@ -682,7 +682,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
utils::internal_lints::CLIPPY_LINTS_INTERNAL,
|
||||
utils::internal_lints::COMPILER_LINT_FUNCTIONS,
|
||||
utils::internal_lints::LINT_WITHOUT_LINT_PASS,
|
||||
utils::internal_lints::OUTER_EXPN_EXPN_INFO,
|
||||
utils::internal_lints::OUTER_EXPN_EXPN_DATA,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy::all", Some("clippy"), vec![
|
||||
|
|
|
@ -41,7 +41,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for matches with a two arms where an `if let else` will
|
||||
/// **What it does:** Checks for matches with two arms where an `if let else` will
|
||||
/// usually suffice.
|
||||
///
|
||||
/// **Why is this bad?** Just readability – `if let` nests less than a `match`.
|
||||
|
@ -76,7 +76,7 @@ declare_clippy_lint! {
|
|||
/// ```
|
||||
pub SINGLE_MATCH_ELSE,
|
||||
pedantic,
|
||||
"a match statement with a two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
|
||||
"a match statement with two arms where the second arm's pattern is a placeholder instead of a specific match pattern"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
|
|
|
@ -625,13 +625,17 @@ fn is_used(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
/// generated by `#[derive(...)]` or the like).
|
||||
fn in_attributes_expansion(expr: &Expr) -> bool {
|
||||
use syntax::ext::hygiene::MacroKind;
|
||||
expr.span.ctxt().outer_expn_info().map_or(false, |info| {
|
||||
if let ExpnKind::Macro(MacroKind::Attr, _) = info.kind {
|
||||
if expr.span.from_expansion() {
|
||||
let data = expr.span.ctxt().outer_expn_data();
|
||||
|
||||
if let ExpnKind::Macro(MacroKind::Attr, _) = data.kind {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether `res` is a variable defined outside a macro.
|
||||
|
|
|
@ -234,7 +234,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
|||
.name;
|
||||
|
||||
for field in pfields {
|
||||
if let PatKind::Wild = field.node.pat.node {
|
||||
if let PatKind::Wild = field.pat.node {
|
||||
wilds += 1;
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
|||
let mut normal = vec![];
|
||||
|
||||
for field in pfields {
|
||||
match field.node.pat.node {
|
||||
match field.pat.node {
|
||||
PatKind::Wild => {},
|
||||
_ => {
|
||||
if let Ok(n) = cx.sess().source_map().span_to_snippet(field.span) {
|
||||
|
@ -262,7 +262,7 @@ impl EarlyLintPass for MiscEarlyLints {
|
|||
}
|
||||
}
|
||||
for field in pfields {
|
||||
if let PatKind::Wild = field.node.pat.node {
|
||||
if let PatKind::Wild = field.pat.node {
|
||||
wilds -= 1;
|
||||
if wilds > 0 {
|
||||
span_lint(
|
||||
|
|
|
@ -131,8 +131,8 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
|
|||
PatKind::Ident(_, ident, _) => self.check_ident(ident),
|
||||
PatKind::Struct(_, ref fields, _) => {
|
||||
for field in fields {
|
||||
if !field.node.is_shorthand {
|
||||
self.visit_pat(&field.node.pat);
|
||||
if !field.is_shorthand {
|
||||
self.visit_pat(&field.pat);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -69,8 +69,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PanicUnimplemented {
|
|||
|
||||
fn get_outer_span(expr: &Expr) -> Span {
|
||||
if_chain! {
|
||||
if let Some(first) = expr.span.ctxt().outer_expn_info();
|
||||
if let Some(second) = first.call_site.ctxt().outer_expn_info();
|
||||
if expr.span.from_expansion();
|
||||
let first = expr.span.ctxt().outer_expn_data();
|
||||
if first.call_site.from_expansion();
|
||||
let second = first.call_site.ctxt().outer_expn_data();
|
||||
then {
|
||||
second.call_site
|
||||
} else {
|
||||
|
|
|
@ -147,10 +147,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Ranges {
|
|||
}) = higher::range(cx, expr);
|
||||
if let Some(y) = y_plus_one(end);
|
||||
then {
|
||||
let span = expr.span
|
||||
let span = if expr.span.from_expansion() {
|
||||
expr.span
|
||||
.ctxt()
|
||||
.outer_expn_info()
|
||||
.map_or(expr.span, |info| info.call_site);
|
||||
.outer_expn_data()
|
||||
.call_site
|
||||
} else {
|
||||
expr.span
|
||||
};
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
RANGE_PLUS_ONE,
|
||||
|
|
|
@ -317,7 +317,11 @@ fn attr_is_cfg(attr: &ast::Attribute) -> bool {
|
|||
|
||||
// get the def site
|
||||
fn get_def(span: Span) -> Option<Span> {
|
||||
span.ctxt().outer_expn_info().and_then(|info| Some(info.def_site))
|
||||
if span.from_expansion() {
|
||||
Some(span.ctxt().outer_expn_data().def_site)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// is this expr a `()` unit?
|
||||
|
|
|
@ -190,20 +190,20 @@ fn check_pat<'a, 'tcx>(
|
|||
if let Some(init_struct) = init {
|
||||
if let ExprKind::Struct(_, ref efields, _) = init_struct.node {
|
||||
for field in pfields {
|
||||
let name = field.node.ident.name;
|
||||
let name = field.ident.name;
|
||||
let efield = efields
|
||||
.iter()
|
||||
.find_map(|f| if f.ident.name == name { Some(&*f.expr) } else { None });
|
||||
check_pat(cx, &field.node.pat, efield, span, bindings);
|
||||
check_pat(cx, &field.pat, efield, span, bindings);
|
||||
}
|
||||
} else {
|
||||
for field in pfields {
|
||||
check_pat(cx, &field.node.pat, init, span, bindings);
|
||||
check_pat(cx, &field.pat, init, span, bindings);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for field in pfields {
|
||||
check_pat(cx, &field.node.pat, None, span, bindings);
|
||||
check_pat(cx, &field.pat, None, span, bindings);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -549,6 +549,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
|
|||
println!(" if {}.len() == {};", fields_pat, fields.len());
|
||||
println!(" // unimplemented: field checks");
|
||||
},
|
||||
PatKind::Or(ref fields) => {
|
||||
let fields_pat = self.next("fields");
|
||||
println!("Or(ref {}) = {};", fields_pat, current);
|
||||
println!(" if {}.len() == {};", fields_pat, fields.len());
|
||||
println!(" // unimplemented: field checks");
|
||||
},
|
||||
PatKind::TupleStruct(ref path, ref fields, skip_pos) => {
|
||||
let path_pat = self.next("path");
|
||||
let fields_pat = self.next("fields");
|
||||
|
|
|
@ -410,6 +410,12 @@ fn print_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat, indent: usize) {
|
|||
print_pat(cx, inner, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::PatKind::Or(ref fields) => {
|
||||
println!("{}Or", ind);
|
||||
for field in fields {
|
||||
print_pat(cx, field, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::PatKind::Struct(ref path, ref fields, ignore) => {
|
||||
println!("{}Struct", ind);
|
||||
println!(
|
||||
|
@ -420,11 +426,11 @@ fn print_pat(cx: &LateContext<'_, '_>, pat: &hir::Pat, indent: usize) {
|
|||
println!("{}ignore leftover fields: {}", ind, ignore);
|
||||
println!("{}fields:", ind);
|
||||
for field in fields {
|
||||
println!("{} field name: {}", ind, field.node.ident.name);
|
||||
if field.node.is_shorthand {
|
||||
println!("{} field name: {}", ind, field.ident.name);
|
||||
if field.is_shorthand {
|
||||
println!("{} in shorthand notation", ind);
|
||||
}
|
||||
print_pat(cx, &field.node.pat, indent + 1);
|
||||
print_pat(cx, &field.pat, indent + 1);
|
||||
}
|
||||
},
|
||||
hir::PatKind::TupleStruct(ref path, ref fields, opt_dots_position) => {
|
||||
|
|
|
@ -76,26 +76,26 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for calls to `cx.outer().expn_info()` and suggests to use
|
||||
/// the `cx.outer_expn_info()`
|
||||
/// **What it does:** Checks for calls to `cx.outer().expn_data()` and suggests to use
|
||||
/// the `cx.outer_expn_data()`
|
||||
///
|
||||
/// **Why is this bad?** `cx.outer_expn_info()` is faster and more concise.
|
||||
/// **Why is this bad?** `cx.outer_expn_data()` is faster and more concise.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// Bad:
|
||||
/// ```rust,ignore
|
||||
/// expr.span.ctxt().outer().expn_info()
|
||||
/// expr.span.ctxt().outer().expn_data()
|
||||
/// ```
|
||||
///
|
||||
/// Good:
|
||||
/// ```rust,ignore
|
||||
/// expr.span.ctxt().outer_expn_info()
|
||||
/// expr.span.ctxt().outer_expn_data()
|
||||
/// ```
|
||||
pub OUTER_EXPN_EXPN_INFO,
|
||||
pub OUTER_EXPN_EXPN_DATA,
|
||||
internal,
|
||||
"using `cx.outer_expn().expn_info()` instead of `cx.outer_expn_info()`"
|
||||
"using `cx.outer_expn().expn_data()` instead of `cx.outer_expn_data()`"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]);
|
||||
|
@ -180,11 +180,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
|
|||
// not able to capture the error.
|
||||
// Therefore, we need to climb the macro expansion tree and find the
|
||||
// actual span that invoked `declare_tool_lint!`:
|
||||
let lint_span = lint_span
|
||||
.ctxt()
|
||||
.outer_expn_info()
|
||||
.map(|ei| ei.call_site)
|
||||
.expect("unable to get call_site");
|
||||
let lint_span = lint_span.ctxt().outer_expn_data().call_site;
|
||||
|
||||
if !self.registered_lints.contains(lint_name) {
|
||||
span_lint(
|
||||
|
@ -278,17 +274,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct OuterExpnInfoPass;
|
||||
pub struct OuterExpnDataPass;
|
||||
|
||||
impl_lint_pass!(OuterExpnInfoPass => [OUTER_EXPN_EXPN_INFO]);
|
||||
impl_lint_pass!(OuterExpnDataPass => [OUTER_EXPN_EXPN_DATA]);
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnInfoPass {
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnDataPass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
let (method_names, arg_lists) = method_calls(expr, 2);
|
||||
let method_names: Vec<LocalInternedString> = method_names.iter().map(|s| s.as_str()).collect();
|
||||
let method_names: Vec<&str> = method_names.iter().map(std::convert::AsRef::as_ref).collect();
|
||||
if_chain! {
|
||||
if let ["expn_info", "outer_expn"] = method_names.as_slice();
|
||||
if let ["expn_data", "outer_expn"] = method_names.as_slice();
|
||||
let args = arg_lists[1];
|
||||
if args.len() == 1;
|
||||
let self_arg = &args[0];
|
||||
|
@ -297,11 +293,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnInfoPass {
|
|||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
OUTER_EXPN_EXPN_INFO,
|
||||
OUTER_EXPN_EXPN_DATA,
|
||||
expr.span.trim_start(self_arg.span).unwrap_or(expr.span),
|
||||
"usage of `outer_expn().expn_info()`",
|
||||
"usage of `outer_expn().expn_data()`",
|
||||
"try",
|
||||
".outer_expn_info()".to_string(),
|
||||
".outer_expn_data()".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -92,15 +92,15 @@ pub fn in_constant(cx: &LateContext<'_, '_>, id: HirId) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `expn_info` was expanded by any macro or desugaring
|
||||
/// Returns `true` if this `span` was expanded by any macro or desugaring
|
||||
pub fn in_macro_or_desugar(span: Span) -> bool {
|
||||
span.ctxt().outer_expn_info().is_some()
|
||||
span.from_expansion()
|
||||
}
|
||||
|
||||
/// Returns `true` if this `expn_info` was expanded by any macro.
|
||||
/// Returns `true` if this `span` was expanded by any macro.
|
||||
pub fn in_macro(span: Span) -> bool {
|
||||
if let Some(info) = span.ctxt().outer_expn_info() {
|
||||
if let ExpnKind::Desugaring(..) = info.kind {
|
||||
if span.from_expansion() {
|
||||
if let ExpnKind::Desugaring(..) = span.ctxt().outer_expn_data().kind {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
|
@ -686,12 +686,18 @@ pub fn is_adjusted(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
|||
/// See also `is_direct_expn_of`.
|
||||
pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
||||
loop {
|
||||
let span_name_span = span.ctxt().outer_expn_info().map(|ei| (ei.kind.descr(), ei.call_site));
|
||||
if span.from_expansion() {
|
||||
let data = span.ctxt().outer_expn_data();
|
||||
let mac_name = data.kind.descr();
|
||||
let new_span = data.call_site;
|
||||
|
||||
match span_name_span {
|
||||
Some((mac_name, new_span)) if mac_name.as_str() == name => return Some(new_span),
|
||||
None => return None,
|
||||
Some((_, new_span)) => span = new_span,
|
||||
if mac_name.as_str() == name {
|
||||
return Some(new_span);
|
||||
} else {
|
||||
span = new_span;
|
||||
}
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -706,11 +712,18 @@ pub fn is_expn_of(mut span: Span, name: &str) -> Option<Span> {
|
|||
/// `bar!` by
|
||||
/// `is_direct_expn_of`.
|
||||
pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
|
||||
let span_name_span = span.ctxt().outer_expn_info().map(|ei| (ei.kind.descr(), ei.call_site));
|
||||
if span.from_expansion() {
|
||||
let data = span.ctxt().outer_expn_data();
|
||||
let mac_name = data.kind.descr();
|
||||
let new_span = data.call_site;
|
||||
|
||||
match span_name_span {
|
||||
Some((mac_name, new_span)) if mac_name.as_str() == name => Some(new_span),
|
||||
_ => None,
|
||||
if mac_name.as_str() == name {
|
||||
Some(new_span)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,12 +791,12 @@ pub fn is_refutable(cx: &LateContext<'_, '_>, pat: &Pat) -> bool {
|
|||
PatKind::Box(ref pat) | PatKind::Ref(ref pat, _) => is_refutable(cx, pat),
|
||||
PatKind::Lit(..) | PatKind::Range(..) => true,
|
||||
PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
|
||||
PatKind::Tuple(ref pats, _) => are_refutable(cx, pats.iter().map(|pat| &**pat)),
|
||||
PatKind::Or(ref pats) | PatKind::Tuple(ref pats, _) => are_refutable(cx, pats.iter().map(|pat| &**pat)),
|
||||
PatKind::Struct(ref qpath, ref fields, _) => {
|
||||
if is_enum_variant(cx, qpath, pat.hir_id) {
|
||||
true
|
||||
} else {
|
||||
are_refutable(cx, fields.iter().map(|field| &*field.node.pat))
|
||||
are_refutable(cx, fields.iter().map(|field| &*field.pat))
|
||||
}
|
||||
},
|
||||
PatKind::TupleStruct(ref qpath, ref pats, _) => {
|
||||
|
|
|
@ -49,13 +49,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UselessVec {
|
|||
// report the error around the `vec!` not inside `<std macros>:`
|
||||
let span = arg.span
|
||||
.ctxt()
|
||||
.outer_expn_info()
|
||||
.map(|info| info.call_site)
|
||||
.expect("unable to get call_site")
|
||||
.outer_expn_data()
|
||||
.call_site
|
||||
.ctxt()
|
||||
.outer_expn_info()
|
||||
.map(|info| info.call_site)
|
||||
.expect("unable to get call_site");
|
||||
.outer_expn_data()
|
||||
.call_site;
|
||||
check_vec_macro(cx, &vec_args, span);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,9 +183,9 @@ declare_lint_pass!(Write => [
|
|||
|
||||
impl EarlyLintPass for Write {
|
||||
fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &Mac) {
|
||||
if mac.node.path == sym!(println) {
|
||||
if mac.path == sym!(println) {
|
||||
span_lint(cx, PRINT_STDOUT, mac.span, "use of `println!`");
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.node.tts, false) {
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.tts, false) {
|
||||
if fmt_str.contents.is_empty() {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
@ -198,9 +198,9 @@ impl EarlyLintPass for Write {
|
|||
);
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == sym!(print) {
|
||||
} else if mac.path == sym!(print) {
|
||||
span_lint(cx, PRINT_STDOUT, mac.span, "use of `print!`");
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.node.tts, false) {
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.tts, false) {
|
||||
if check_newlines(&fmt_str) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -211,7 +211,7 @@ impl EarlyLintPass for Write {
|
|||
err.multipart_suggestion(
|
||||
"use `println!` instead",
|
||||
vec![
|
||||
(mac.node.path.span, String::from("println")),
|
||||
(mac.path.span, String::from("println")),
|
||||
(fmt_str.newline_span(), String::new()),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -220,8 +220,8 @@ impl EarlyLintPass for Write {
|
|||
);
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == sym!(write) {
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.node.tts, true) {
|
||||
} else if mac.path == sym!(write) {
|
||||
if let (Some(fmt_str), _) = check_tts(cx, &mac.tts, true) {
|
||||
if check_newlines(&fmt_str) {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
|
@ -232,7 +232,7 @@ impl EarlyLintPass for Write {
|
|||
err.multipart_suggestion(
|
||||
"use `writeln!()` instead",
|
||||
vec![
|
||||
(mac.node.path.span, String::from("writeln")),
|
||||
(mac.path.span, String::from("writeln")),
|
||||
(fmt_str.newline_span(), String::new()),
|
||||
],
|
||||
Applicability::MachineApplicable,
|
||||
|
@ -241,8 +241,8 @@ impl EarlyLintPass for Write {
|
|||
)
|
||||
}
|
||||
}
|
||||
} else if mac.node.path == sym!(writeln) {
|
||||
if let (Some(fmt_str), expr) = check_tts(cx, &mac.node.tts, true) {
|
||||
} else if mac.path == sym!(writeln) {
|
||||
if let (Some(fmt_str), expr) = check_tts(cx, &mac.tts, true) {
|
||||
if fmt_str.contents.is_empty() {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let suggestion = expr.map_or_else(
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
./util/update_lints.py
|
||||
|
||||
# add all changed files
|
||||
git add .
|
||||
git commit -m "Bump the version"
|
||||
|
||||
set +e
|
||||
|
||||
echo "Running \`cargo fmt\`.."
|
||||
|
||||
cd clippy_lints && cargo fmt -- --write-mode=overwrite && cd ..
|
||||
cargo fmt -- --write-mode=overwrite
|
||||
|
||||
echo "Running tests to make sure \`cargo fmt\` did not break anything.."
|
||||
|
||||
cargo test
|
||||
|
||||
echo "If the tests passed, review and commit the formatting changes and remember to add a git tag."
|
|
@ -1,3 +0,0 @@
|
|||
M Cargo.toml
|
||||
M CHANGELOG.md
|
||||
M clippy_lints/Cargo.toml
|
|
@ -1676,7 +1676,7 @@ pub const ALL_LINTS: [Lint; 310] = [
|
|||
Lint {
|
||||
name: "single_match_else",
|
||||
group: "pedantic",
|
||||
desc: "a match statement with a two arms where the second arm\'s pattern is a placeholder instead of a specific match pattern",
|
||||
desc: "a match statement with two arms where the second arm\'s pattern is a placeholder instead of a specific match pattern",
|
||||
deprecation: None,
|
||||
module: "matches",
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
|
|||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_expr(&mut self, _cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
let _ = expr.span.ctxt().outer_expn().expn_info();
|
||||
let _ = expr.span.ctxt().outer_expn().expn_data();
|
||||
}
|
||||
}
|
||||
|
15
tests/ui/outer_expn_data.stderr
Normal file
15
tests/ui/outer_expn_data.stderr
Normal file
|
@ -0,0 +1,15 @@
|
|||
error: usage of `outer_expn().expn_data()`
|
||||
--> $DIR/outer_expn_data.rs:19:33
|
||||
|
|
||||
LL | let _ = expr.span.ctxt().outer_expn().expn_data();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.outer_expn_data()`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/outer_expn_data.rs:1:9
|
||||
|
|
||||
LL | #![deny(clippy::internal)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: `#[deny(clippy::outer_expn_expn_data)]` implied by `#[deny(clippy::internal)]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
error: usage of `outer_expn().expn_info()`
|
||||
--> $DIR/outer_expn_info.rs:19:33
|
||||
|
|
||||
LL | let _ = expr.span.ctxt().outer_expn().expn_info();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.outer_expn_info()`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/outer_expn_info.rs:1:9
|
||||
|
|
||||
LL | #![deny(clippy::internal)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
= note: `#[deny(clippy::outer_expn_expn_info)]` implied by `#[deny(clippy::internal)]`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
def main():
|
||||
print('Error: Please use `util/dev` to update lints')
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in a new issue