Skip to content

Commit 6e07247

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents 141b9c2 + d88b9b7 commit 6e07247

File tree

98 files changed

+2744
-637
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+2744
-637
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1672,10 +1672,12 @@ Released 2018-09-13
16721672
[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
16731673
[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
16741674
[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic
1675+
[`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip
16751676
[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap
16761677
[`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names
16771678
[`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone
16781679
[`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
1680+
[`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_err_ignore
16791681
[`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten
16801682
[`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity
16811683
[`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or
@@ -1755,6 +1757,7 @@ Released 2018-09-13
17551757
[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
17561758
[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional
17571759
[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic
1760+
[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn
17581761
[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params
17591762
[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap
17601763
[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl

CONTRIBUTING.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ something. We appreciate any sort of contributions, and don't want a wall of rul
88

99
Clippy welcomes contributions from everyone. There are many ways to contribute to Clippy and the following document
1010
explains how you can contribute and how to get started. If you have any questions about contributing or need help with
11-
anything, feel free to ask questions on issues or visit the `#clippy` on [Discord].
11+
anything, feel free to ask questions on issues or visit the `#clippy` on [Zulip].
1212

1313
All contributors are expected to follow the [Rust Code of Conduct].
1414

@@ -23,7 +23,7 @@ All contributors are expected to follow the [Rust Code of Conduct].
2323
- [Bors and Homu](#bors-and-homu)
2424
- [Contributions](#contributions)
2525

26-
[Discord]: https://discord.gg/rust-lang
26+
[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy
2727
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
2828

2929
## Getting started
@@ -242,7 +242,7 @@ to be run inside the `rust` directory):
242242
```
243243
3. Open a PR to `rust-lang/rust-clippy` and wait for it to get merged (to
244244
accelerate the process ping the `@rust-lang/clippy` team in your PR and/or
245-
~~annoy~~ ask them in the [Discord] channel.)
245+
~~annoy~~ ask them in the [Zulip] stream.)
246246

247247
### Syncing back changes in Clippy to [`rust-lang/rust`]
248248

clippy_dev/src/ra_setup.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub fn run(rustc_path: Option<&str>) {
1414
// we can unwrap here because the arg is required here
1515
let rustc_path = PathBuf::from(rustc_path.unwrap());
1616
assert!(rustc_path.is_dir(), "path is not a directory");
17-
let rustc_source_basedir = rustc_path.join("src");
17+
let rustc_source_basedir = rustc_path.join("compiler");
1818
assert!(
1919
rustc_source_basedir.is_dir(),
2020
"are you sure the path leads to a rustc repo?"
@@ -61,7 +61,7 @@ fn inject_deps_into_manifest(
6161
let new_deps = extern_crates.map(|dep| {
6262
// format the dependencies that are going to be put inside the Cargo.toml
6363
format!(
64-
"{dep} = {{ path = \"{source_path}/lib{dep}\" }}\n",
64+
"{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
6565
dep = dep,
6666
source_path = rustc_source_dir.display()
6767
)

clippy_lints/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ cargo_metadata = "0.11.1"
2121
if_chain = "1.0.0"
2222
itertools = "0.9"
2323
lazy_static = "1.0.2"
24-
pulldown-cmark = { version = "0.7.1", default-features = false }
24+
pulldown-cmark = { version = "0.8", default-features = false }
2525
quine-mc_cluskey = "0.2.2"
2626
regex-syntax = "0.6"
2727
serde = { version = "1.0", features = ["derive"] }

clippy_lints/src/atomic_ordering.rs

+100-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
88

99
declare_clippy_lint! {
1010
/// **What it does:** Checks for usage of invalid atomic
11-
/// ordering in atomic loads/stores and memory fences.
11+
/// ordering in atomic loads/stores/exchanges/updates and
12+
/// memory fences.
1213
///
1314
/// **Why is this bad?** Using an invalid atomic ordering
1415
/// will cause a panic at run-time.
@@ -17,22 +18,35 @@ declare_clippy_lint! {
1718
///
1819
/// **Example:**
1920
/// ```rust,no_run
20-
/// # use std::sync::atomic::{self, AtomicBool, Ordering};
21+
/// # use std::sync::atomic::{self, AtomicU8, Ordering};
2122
///
22-
/// let x = AtomicBool::new(true);
23+
/// let x = AtomicU8::new(0);
2324
///
25+
/// // Bad: `Release` and `AcqRel` cannot be used for `load`.
2426
/// let _ = x.load(Ordering::Release);
2527
/// let _ = x.load(Ordering::AcqRel);
2628
///
27-
/// x.store(false, Ordering::Acquire);
28-
/// x.store(false, Ordering::AcqRel);
29+
/// // Bad: `Acquire` and `AcqRel` cannot be used for `store`.
30+
/// x.store(1, Ordering::Acquire);
31+
/// x.store(2, Ordering::AcqRel);
2932
///
33+
/// // Bad: `Relaxed` cannot be used as a fence's ordering.
3034
/// atomic::fence(Ordering::Relaxed);
3135
/// atomic::compiler_fence(Ordering::Relaxed);
36+
///
37+
/// // Bad: `Release` and `AcqRel` are both always invalid
38+
/// // for the failure ordering (the last arg).
39+
/// let _ = x.compare_exchange(1, 2, Ordering::SeqCst, Ordering::Release);
40+
/// let _ = x.compare_exchange_weak(2, 3, Ordering::AcqRel, Ordering::AcqRel);
41+
///
42+
/// // Bad: The failure ordering is not allowed to be
43+
/// // stronger than the success order, and `SeqCst` is
44+
/// // stronger than `Relaxed`.
45+
/// let _ = x.fetch_update(Ordering::Relaxed, Ordering::SeqCst, |val| Some(val + val));
3246
/// ```
3347
pub INVALID_ATOMIC_ORDERING,
3448
correctness,
35-
"usage of invalid atomic ordering in atomic loads/stores and memory fences"
49+
"usage of invalid atomic ordering in atomic operations and memory fences"
3650
}
3751

3852
declare_lint_pass!(AtomicOrdering => [INVALID_ATOMIC_ORDERING]);
@@ -127,9 +141,89 @@ fn check_memory_fence(cx: &LateContext<'_>, expr: &Expr<'_>) {
127141
}
128142
}
129143

144+
fn opt_ordering_defid(cx: &LateContext<'_>, ord_arg: &Expr<'_>) -> Option<DefId> {
145+
if let ExprKind::Path(ref ord_qpath) = ord_arg.kind {
146+
cx.qpath_res(ord_qpath, ord_arg.hir_id).opt_def_id()
147+
} else {
148+
None
149+
}
150+
}
151+
152+
fn check_atomic_compare_exchange(cx: &LateContext<'_>, expr: &Expr<'_>) {
153+
if_chain! {
154+
if let ExprKind::MethodCall(ref method_path, _, args, _) = &expr.kind;
155+
let method = method_path.ident.name.as_str();
156+
if type_is_atomic(cx, &args[0]);
157+
if method == "compare_exchange" || method == "compare_exchange_weak" || method == "fetch_update";
158+
let (success_order_arg, failure_order_arg) = if method == "fetch_update" {
159+
(&args[1], &args[2])
160+
} else {
161+
(&args[3], &args[4])
162+
};
163+
if let Some(fail_ordering_def_id) = opt_ordering_defid(cx, failure_order_arg);
164+
then {
165+
// Helper type holding on to some checking and error reporting data. Has
166+
// - (success ordering name,
167+
// - list of failure orderings forbidden by the success order,
168+
// - suggestion message)
169+
type OrdLintInfo = (&'static str, &'static [&'static str], &'static str);
170+
let relaxed: OrdLintInfo = ("Relaxed", &["SeqCst", "Acquire"], "ordering mode `Relaxed`");
171+
let acquire: OrdLintInfo = ("Acquire", &["SeqCst"], "ordering modes `Acquire` or `Relaxed`");
172+
let seq_cst: OrdLintInfo = ("SeqCst", &[], "ordering modes `Acquire`, `SeqCst` or `Relaxed`");
173+
let release = ("Release", relaxed.1, relaxed.2);
174+
let acqrel = ("AcqRel", acquire.1, acquire.2);
175+
let search = [relaxed, acquire, seq_cst, release, acqrel];
176+
177+
let success_lint_info = opt_ordering_defid(cx, success_order_arg)
178+
.and_then(|success_ord_def_id| -> Option<OrdLintInfo> {
179+
search
180+
.iter()
181+
.find(|(ordering, ..)| {
182+
match_def_path(cx, success_ord_def_id,
183+
&["core", "sync", "atomic", "Ordering", ordering])
184+
})
185+
.copied()
186+
});
187+
188+
if match_ordering_def_path(cx, fail_ordering_def_id, &["Release", "AcqRel"]) {
189+
// If we don't know the success order is, use what we'd suggest
190+
// if it were maximally permissive.
191+
let suggested = success_lint_info.unwrap_or(seq_cst).2;
192+
span_lint_and_help(
193+
cx,
194+
INVALID_ATOMIC_ORDERING,
195+
failure_order_arg.span,
196+
&format!(
197+
"{}'s failure ordering may not be `Release` or `AcqRel`",
198+
method,
199+
),
200+
None,
201+
&format!("consider using {} instead", suggested),
202+
);
203+
} else if let Some((success_ord_name, bad_ords_given_success, suggested)) = success_lint_info {
204+
if match_ordering_def_path(cx, fail_ordering_def_id, bad_ords_given_success) {
205+
span_lint_and_help(
206+
cx,
207+
INVALID_ATOMIC_ORDERING,
208+
failure_order_arg.span,
209+
&format!(
210+
"{}'s failure ordering may not be stronger than the success ordering of `{}`",
211+
method,
212+
success_ord_name,
213+
),
214+
None,
215+
&format!("consider using {} instead", suggested),
216+
);
217+
}
218+
}
219+
}
220+
}
221+
}
222+
130223
impl<'tcx> LateLintPass<'tcx> for AtomicOrdering {
131224
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
132225
check_atomic_load_store(cx, expr);
133226
check_memory_fence(cx, expr);
227+
check_atomic_compare_exchange(cx, expr);
134228
}
135229
}

clippy_lints/src/await_holding_lock.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare_clippy_lint! {
1010
/// **What it does:** Checks for calls to await while holding a
1111
/// non-async-aware MutexGuard.
1212
///
13-
/// **Why is this bad?** The Mutex types found in syd::sync and parking_lot
13+
/// **Why is this bad?** The Mutex types found in std::sync and parking_lot
1414
/// are not designed to operate in an async context across await points.
1515
///
1616
/// There are two potential solutions. One is to use an asynx-aware Mutex

clippy_lints/src/bit_mask.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ declare_clippy_lint! {
9090
/// if x & 0b1111 == 0 { }
9191
/// ```
9292
pub VERBOSE_BIT_MASK,
93-
style,
93+
pedantic,
9494
"expressions where a bit mask is less readable than the corresponding method call"
9595
}
9696

clippy_lints/src/bytecount.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::utils::{
2-
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability,
3-
span_lint_and_sugg, walk_ptrs_ty,
2+
contains_name, get_pat_name, match_type, paths, single_segment_path, snippet_with_applicability, span_lint_and_sugg,
43
};
54
use if_chain::if_chain;
65
use rustc_ast::ast::UintTy;
@@ -53,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
5352
if let ExprKind::Binary(ref op, ref l, ref r) = body.value.kind;
5453
if op.node == BinOpKind::Eq;
5554
if match_type(cx,
56-
walk_ptrs_ty(cx.typeck_results().expr_ty(&filter_args[0])),
55+
cx.typeck_results().expr_ty(&filter_args[0]).peel_refs(),
5756
&paths::SLICE_ITER);
5857
then {
5958
let needle = match get_path_name(l) {
@@ -63,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for ByteCount {
6362
_ => { return; }
6463
}
6564
};
66-
if ty::Uint(UintTy::U8) != *walk_ptrs_ty(cx.typeck_results().expr_ty(needle)).kind() {
65+
if ty::Uint(UintTy::U8) != *cx.typeck_results().expr_ty(needle).peel_refs().kind() {
6766
return;
6867
}
6968
let haystack = if let ExprKind::MethodCall(ref path, _, ref args, _) =

clippy_lints/src/doc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
534534
return false;
535535
}
536536

537-
let s = if s.ends_with('s') { &s[..s.len() - 1] } else { s };
537+
let s = s.strip_suffix('s').unwrap_or(s);
538538

539539
s.chars().all(char::is_alphanumeric)
540540
&& s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1

clippy_lints/src/duration_subsec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_span::source_map::Spanned;
77

88
use crate::consts::{constant, Constant};
99
use crate::utils::paths;
10-
use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg, walk_ptrs_ty};
10+
use crate::utils::{match_type, snippet_with_applicability, span_lint_and_sugg};
1111

1212
declare_clippy_lint! {
1313
/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds
@@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for DurationSubsec {
4343
if_chain! {
4444
if let ExprKind::Binary(Spanned { node: BinOpKind::Div, .. }, ref left, ref right) = expr.kind;
4545
if let ExprKind::MethodCall(ref method_path, _ , ref args, _) = left.kind;
46-
if match_type(cx, walk_ptrs_ty(cx.typeck_results().expr_ty(&args[0])), &paths::DURATION);
46+
if match_type(cx, cx.typeck_results().expr_ty(&args[0]).peel_refs(), &paths::DURATION);
4747
if let Some((Constant::Int(divisor), _)) = constant(cx, cx.typeck_results(), right);
4848
then {
4949
let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) {

clippy_lints/src/entry.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::utils::SpanlessEq;
22
use crate::utils::{get_item_name, higher, is_type_diagnostic_item, match_type, paths, snippet, snippet_opt};
3-
use crate::utils::{snippet_with_applicability, span_lint_and_then, walk_ptrs_ty};
3+
use crate::utils::{snippet_with_applicability, span_lint_and_then};
44
use if_chain::if_chain;
55
use rustc_errors::Applicability;
66
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
@@ -106,7 +106,7 @@ fn check_cond<'a>(cx: &LateContext<'_>, check: &'a Expr<'a>) -> Option<(&'static
106106
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref key) = params[1].kind;
107107
then {
108108
let map = &params[0];
109-
let obj_ty = walk_ptrs_ty(cx.typeck_results().expr_ty(map));
109+
let obj_ty = cx.typeck_results().expr_ty(map).peel_refs();
110110

111111
return if match_type(cx, obj_ty, &paths::BTREEMAP) {
112112
Some(("BTreeMap", map, key))

clippy_lints/src/fallible_impl_from.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use crate::utils::paths::{BEGIN_PANIC, BEGIN_PANIC_FMT, FROM_TRAIT};
2-
use crate::utils::{
3-
is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then, walk_ptrs_ty,
4-
};
2+
use crate::utils::{is_expn_of, is_type_diagnostic_item, match_def_path, method_chain_args, span_lint_and_then};
53
use if_chain::if_chain;
64
use rustc_hir as hir;
75
use rustc_lint::{LateContext, LateLintPass};
@@ -96,7 +94,7 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h
9694

9795
// check for `unwrap`
9896
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
99-
let reciever_ty = walk_ptrs_ty(self.typeck_results.expr_ty(&arglists[0][0]));
97+
let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
10098
if is_type_diagnostic_item(self.lcx, reciever_ty, sym!(option_type))
10199
|| is_type_diagnostic_item(self.lcx, reciever_ty, sym!(result_type))
102100
{

clippy_lints/src/format.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::utils::paths;
22
use crate::utils::{
33
is_expn_of, is_type_diagnostic_item, last_path_segment, match_def_path, match_function_call, snippet,
4-
span_lint_and_then, walk_ptrs_ty,
4+
span_lint_and_then,
55
};
66
use if_chain::if_chain;
77
use rustc_ast::ast::LitKind;
@@ -90,7 +90,7 @@ fn on_argumentv1_new<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arms: &
9090
if let PatKind::Tuple(ref pats, None) = arms[0].pat.kind;
9191
if pats.len() == 1;
9292
then {
93-
let ty = walk_ptrs_ty(cx.typeck_results().pat_ty(&pats[0]));
93+
let ty = cx.typeck_results().pat_ty(&pats[0]).peel_refs();
9494
if *ty.kind() != rustc_middle::ty::Str && !is_type_diagnostic_item(cx, ty, sym!(string_type)) {
9595
return None;
9696
}

clippy_lints/src/indexing_slicing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ declare_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]
8888
impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
8989
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
9090
if let ExprKind::Index(ref array, ref index) = &expr.kind {
91-
let ty = cx.typeck_results().expr_ty(array);
91+
let ty = cx.typeck_results().expr_ty(array).peel_refs();
9292
if let Some(range) = higher::range(index) {
9393
// Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
9494
if let ty::Array(_, s) = ty.kind() {

clippy_lints/src/inherent_to_string.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
55

66
use crate::utils::{
77
get_trait_def_id, implements_trait, is_type_diagnostic_item, paths, return_ty, span_lint_and_help,
8-
trait_ref_of_method, walk_ptrs_ty,
8+
trait_ref_of_method,
99
};
1010

1111
declare_clippy_lint! {
@@ -125,7 +125,7 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
125125
// Get the real type of 'self'
126126
let fn_def_id = cx.tcx.hir().local_def_id(item.hir_id);
127127
let self_type = cx.tcx.fn_sig(fn_def_id).input(0);
128-
let self_type = walk_ptrs_ty(self_type.skip_binder());
128+
let self_type = self_type.skip_binder().peel_refs();
129129

130130
// Emit either a warning or an error
131131
if implements_trait(cx, self_type, display_trait_id, &[]) {

clippy_lints/src/len_zero.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg, walk_ptrs_ty};
1+
use crate::utils::{get_item_name, snippet_with_applicability, span_lint, span_lint_and_sugg};
22
use rustc_ast::ast::LitKind;
33
use rustc_data_structures::fx::FxHashSet;
44
use rustc_errors::Applicability;
@@ -285,7 +285,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
285285
})
286286
}
287287

288-
let ty = &walk_ptrs_ty(cx.typeck_results().expr_ty(expr));
288+
let ty = &cx.typeck_results().expr_ty(expr).peel_refs();
289289
match ty.kind() {
290290
ty::Dynamic(ref tt, ..) => tt.principal().map_or(false, |principal| {
291291
cx.tcx

0 commit comments

Comments
 (0)