Skip to content

Commit 6b3487a

Browse files
authored
Merge pull request #2448 from rust-lang-nursery/fixes
Fixes
2 parents fc7b395 + 6feb0dd commit 6b3487a

File tree

10 files changed

+61
-78
lines changed

10 files changed

+61
-78
lines changed

clippy_lints/src/copies.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyAndPaste {
134134

135135
/// Implementation of `IF_SAME_THEN_ELSE`.
136136
fn lint_same_then_else(cx: &LateContext, blocks: &[&Block]) {
137-
let hash: &Fn(&&Block) -> u64 = &|block| -> u64 {
138-
let mut h = SpanlessHash::new(cx);
139-
h.hash_block(block);
140-
h.finish()
141-
};
142-
143137
let eq: &Fn(&&Block, &&Block) -> bool = &|&lhs, &rhs| -> bool { SpanlessEq::new(cx).eq_block(lhs, rhs) };
144138

145-
if let Some((i, j)) = search_same(blocks, hash, eq) {
139+
if let Some((i, j)) = search_same_sequenced(blocks, eq) {
146140
span_note_and_lint(
147141
cx,
148142
IF_SAME_THEN_ELSE,
@@ -309,6 +303,19 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
309303
result
310304
}
311305

306+
307+
fn search_same_sequenced<T, Eq>(exprs: &[T], eq: Eq) -> Option<(&T, &T)>
308+
where
309+
Eq: Fn(&T, &T) -> bool,
310+
{
311+
for win in exprs.windows(2) {
312+
if eq(&win[0], &win[1]) {
313+
return Some((&win[0], &win[1]));
314+
}
315+
}
316+
None
317+
}
318+
312319
fn search_same<T, Hash, Eq>(exprs: &[T], hash: Hash, eq: Eq) -> Option<(&T, &T)>
313320
where
314321
Hash: Fn(&T) -> u64,

clippy_lints/src/escape.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ use rustc::lint::*;
55
use rustc::middle::expr_use_visitor::*;
66
use rustc::middle::mem_categorization::{cmt, Categorization};
77
use rustc::ty::{self, Ty};
8+
use rustc::ty::layout::LayoutOf;
89
use rustc::util::nodemap::NodeSet;
910
use syntax::ast::NodeId;
1011
use syntax::codemap::Span;
11-
use utils::{span_lint, type_size};
12+
use utils::span_lint;
1213

1314
pub struct Pass {
1415
pub too_large_for_stack: u64,
@@ -164,7 +165,7 @@ impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
164165
// Large types need to be boxed to avoid stack
165166
// overflows.
166167
if ty.is_box() {
167-
type_size(self.cx, ty.boxed_ty()).unwrap_or(0) > self.too_large_for_stack
168+
self.cx.layout_of(ty.boxed_ty()).ok().map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
168169
} else {
169170
false
170171
}

clippy_lints/src/large_enum_variant.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
33
use rustc::lint::*;
44
use rustc::hir::*;
5-
use utils::{snippet_opt, span_lint_and_then, type_size};
6-
use rustc::ty::TypeFoldable;
5+
use utils::{snippet_opt, span_lint_and_then};
6+
use rustc::ty::layout::LayoutOf;
77

88
/// **What it does:** Checks for large size differences between variants on
99
/// `enum`s.
@@ -61,13 +61,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
6161
let size: u64 = variant
6262
.fields
6363
.iter()
64-
.map(|f| {
64+
.filter_map(|f| {
6565
let ty = cx.tcx.type_of(f.did);
66-
if ty.needs_subst() {
67-
0 // we can't reason about generics, so we treat them as zero sized
68-
} else {
69-
type_size(cx, ty).expect("size should be computable for concrete type")
70-
}
66+
// don't count generics by filtering out everything
67+
// that does not have a layout
68+
cx.layout_of(ty).ok().map(|l| l.size.bytes())
7169
})
7270
.sum();
7371

clippy_lints/src/types.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc::hir::*;
44
use rustc::hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisitorMap, Visitor};
55
use rustc::lint::*;
66
use rustc::ty::{self, Ty, TyCtxt, TypeckTables};
7+
use rustc::ty::layout::LayoutOf;
78
use rustc::ty::subst::Substs;
89
use rustc_typeck::hir_ty_to_ty;
910
use std::cmp::Ordering;
@@ -15,7 +16,7 @@ use syntax::codemap::Span;
1516
use syntax::errors::DiagnosticBuilder;
1617
use utils::{comparisons, higher, in_constant, in_external_macro, in_macro, last_path_segment, match_def_path, match_path,
1718
multispan_sugg, opt_def_id, same_tys, snippet, snippet_opt, span_help_and_lint, span_lint,
18-
span_lint_and_sugg, span_lint_and_then, type_size};
19+
span_lint_and_sugg, span_lint_and_then};
1920
use utils::paths;
2021

2122
/// Handles all the linting of funky types
@@ -1478,7 +1479,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
14781479
let pre_cast_ty = cx.tables.expr_ty(cast_exp);
14791480
let cast_ty = cx.tables.expr_ty(expr);
14801481
// if it's a cast from i32 to u32 wrapping will invalidate all these checks
1481-
if type_size(cx, pre_cast_ty) == type_size(cx, cast_ty) {
1482+
if cx.layout_of(pre_cast_ty).ok().map(|l| l.size) == cx.layout_of(cast_ty).ok().map(|l| l.size) {
14821483
return None;
14831484
}
14841485
match pre_cast_ty.sty {

clippy_lints/src/utils/hir_utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use consts::{constant, constant_context};
1+
use consts::{constant_simple, constant_context};
22
use rustc::lint::*;
33
use rustc::hir::*;
44
use std::hash::{Hash, Hasher};
@@ -64,7 +64,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
6464
return false;
6565
}
6666

67-
if let (Some(l), Some(r)) = (constant(self.cx, left), constant(self.cx, right)) {
67+
if let (Some(l), Some(r)) = (constant_simple(self.cx, left), constant_simple(self.cx, right)) {
6868
if l == r {
6969
return true;
7070
}
@@ -317,7 +317,7 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
317317
}
318318

319319
pub fn hash_expr(&mut self, e: &Expr) {
320-
if let Some(e) = constant(self.cx, e) {
320+
if let Some(e) = constant_simple(self.cx, e) {
321321
return e.hash(&mut self.s);
322322
}
323323

clippy_lints/src/utils/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use rustc::lint::{LateContext, Level, Lint, LintContext};
99
use rustc::session::Session;
1010
use rustc::traits;
1111
use rustc::ty::{self, Ty, TyCtxt};
12-
use rustc::ty::layout::LayoutOf;
1312
use rustc_errors;
1413
use std::borrow::Cow;
1514
use std::env;
@@ -1048,12 +1047,6 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
10481047
None
10491048
}
10501049

1051-
pub fn type_size<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Option<u64> {
1052-
cx.layout_of(ty)
1053-
.ok()
1054-
.map(|layout| layout.size.bytes())
1055-
}
1056-
10571050
/// Returns true if the lint is allowed in the current context
10581051
///
10591052
/// Useful for skipping long running code when it's unnecessary

tests/run-pass/if_same_then_else.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![deny(if_same_then_else)]
2+
3+
fn main() {}
4+
5+
pub fn foo(a: i32, b: i32) -> Option<&'static str> {
6+
if a == b {
7+
None
8+
} else if a > b {
9+
Some("a pfeil b")
10+
} else {
11+
None
12+
}
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![deny(match_same_arms)]
2+
3+
const PRICE_OF_SWEETS: u32 = 5;
4+
const PRICE_OF_KINDNESS: u32 = 0;
5+
const PRICE_OF_DRINKS: u32 = 5;
6+
7+
pub fn price(thing: &str) -> u32 {
8+
match thing {
9+
"rolo" => PRICE_OF_SWEETS,
10+
"advice" => PRICE_OF_KINDNESS,
11+
"juice" => PRICE_OF_DRINKS,
12+
_ => panic!()
13+
}
14+
}
15+
16+
fn main() {}

tests/ui/copies.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ fn if_same_then_else() -> Result<&'static str, ()> {
160160
else if false {
161161
foo();
162162
}
163-
else if foo() { //~ ERROR same body as `if` block
163+
else if foo() {
164164
let _ = match 42 {
165165
42 => 1,
166166
a if a > 0 => 2,
@@ -336,7 +336,7 @@ fn if_same_then_else() -> Result<&'static str, ()> {
336336
let foo = "bar";
337337
return Ok(&foo[0..]);
338338
}
339-
else { //~ ERROR same body as `if` block
339+
else {
340340
let foo = "";
341341
return Ok(&foo[0..]);
342342
}

tests/ui/copies.stderr

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -151,32 +151,6 @@ note: same as this
151151
139 | | }
152152
| |_____^
153153

154-
error: this `if` has identical blocks
155-
--> $DIR/copies.rs:163:19
156-
|
157-
163 | else if foo() { //~ ERROR same body as `if` block
158-
| ___________________^
159-
164 | | let _ = match 42 {
160-
165 | | 42 => 1,
161-
166 | | a if a > 0 => 2,
162-
... |
163-
169 | | };
164-
170 | | }
165-
| |_____^
166-
|
167-
note: same as this
168-
--> $DIR/copies.rs:152:13
169-
|
170-
152 | if true {
171-
| _____________^
172-
153 | | let _ = match 42 {
173-
154 | | 42 => 1,
174-
155 | | a if a > 0 => 2,
175-
... |
176-
158 | | };
177-
159 | | }
178-
| |_____^
179-
180154
error: this `if` has identical blocks
181155
--> $DIR/copies.rs:175:10
182156
|
@@ -370,26 +344,6 @@ note: same as this
370344
326 | | }
371345
| |_____^
372346

373-
error: this `if` has identical blocks
374-
--> $DIR/copies.rs:339:10
375-
|
376-
339 | else { //~ ERROR same body as `if` block
377-
| __________^
378-
340 | | let foo = "";
379-
341 | | return Ok(&foo[0..]);
380-
342 | | }
381-
| |_____^
382-
|
383-
note: same as this
384-
--> $DIR/copies.rs:331:13
385-
|
386-
331 | if true {
387-
| _____________^
388-
332 | | let foo = "";
389-
333 | | return Ok(&foo[0..]);
390-
334 | | }
391-
| |_____^
392-
393347
error: this `if` has the same condition as a previous if
394348
--> $DIR/copies.rs:353:13
395349
|
@@ -427,5 +381,5 @@ note: same as this
427381
361 | if 2*a == 1 {
428382
| ^^^^^^^^
429383

430-
error: aborting due to 22 previous errors
384+
error: aborting due to 20 previous errors
431385

0 commit comments

Comments
 (0)