Skip to content

Commit 0cc53f4

Browse files
committed
Auto merge of rust-lang#11957 - J-ZhengLi:issue11535, r=Jarcho
don't lint [`default_numeric_fallback`] on return and local assigned macro calls with type stated fixes: rust-lang#11535 changelog: don't lint [`default_numeric_fallback`] on return and local assigned macro calls with type stated
2 parents c6aeb28 + a9baf34 commit 0cc53f4

7 files changed

+139
-48
lines changed

clippy_lints/src/default_numeric_fallback.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use clippy_utils::{get_parent_node, numeric_literal};
44
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
55
use rustc_errors::Applicability;
66
use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor};
7-
use rustc_hir::{Body, Expr, ExprKind, HirId, ItemKind, Lit, Node, Stmt, StmtKind};
7+
use rustc_hir::{Block, Body, Expr, ExprKind, FnRetTy, HirId, ItemKind, Lit, Node, Stmt, StmtKind};
88
use rustc_lint::{LateContext, LateLintPass, LintContext};
99
use rustc_middle::lint::in_external_macro;
1010
use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
@@ -122,13 +122,42 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
122122
impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
123123
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
124124
match &expr.kind {
125+
ExprKind::Block(
126+
Block {
127+
stmts, expr: Some(_), ..
128+
},
129+
_,
130+
) => {
131+
if let Some(parent) = self.cx.tcx.hir().find_parent(expr.hir_id)
132+
&& let Some(fn_sig) = parent.fn_sig()
133+
&& let FnRetTy::Return(_ty) = fn_sig.decl.output
134+
{
135+
// We cannot check the exact type since it's a `hir::Ty`` which does not implement `is_numeric`
136+
self.ty_bounds.push(ExplicitTyBound(true));
137+
for stmt in *stmts {
138+
self.visit_stmt(stmt);
139+
}
140+
self.ty_bounds.pop();
141+
// Ignore return expr since we know its type was inferred from return ty
142+
return;
143+
}
144+
},
145+
146+
// Ignore return expr since we know its type was inferred from return ty
147+
ExprKind::Ret(_) => return,
148+
125149
ExprKind::Call(func, args) => {
126150
if let Some(fn_sig) = fn_sig_opt(self.cx, func.hir_id) {
127151
for (expr, bound) in iter::zip(*args, fn_sig.skip_binder().inputs()) {
128-
// Push found arg type, then visit arg.
129-
self.ty_bounds.push((*bound).into());
130-
self.visit_expr(expr);
131-
self.ty_bounds.pop();
152+
// If is from macro, try to use last bound type (typically pushed when visiting stmt),
153+
// otherwise push found arg type, then visit arg,
154+
if expr.span.from_expansion() {
155+
self.visit_expr(expr);
156+
} else {
157+
self.ty_bounds.push((*bound).into());
158+
self.visit_expr(expr);
159+
self.ty_bounds.pop();
160+
}
132161
}
133162
return;
134163
}
@@ -137,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
137166
ExprKind::MethodCall(_, receiver, args, _) => {
138167
if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {
139168
let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
140-
for (expr, bound) in iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {
169+
for (expr, bound) in iter::zip(iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {
141170
self.ty_bounds.push((*bound).into());
142171
self.visit_expr(expr);
143172
self.ty_bounds.pop();

tests/ui/default_numeric_fallback_f64.fixed

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,7 @@ mod nested_local {
7373

7474
mod function_def {
7575
fn ret_f64() -> f64 {
76-
// Even though the output type is specified,
77-
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
78-
1.0_f64
76+
1.
7977
}
8078

8179
fn test() {

tests/ui/default_numeric_fallback_f64.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ mod nested_local {
7373

7474
mod function_def {
7575
fn ret_f64() -> f64 {
76-
// Even though the output type is specified,
77-
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
7876
1.
7977
}
8078

tests/ui/default_numeric_fallback_f64.stderr

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,66 +86,60 @@ LL | let y = 1.;
8686
| ^^ help: consider adding suffix: `1.0_f64`
8787

8888
error: default numeric fallback might occur
89-
--> $DIR/default_numeric_fallback_f64.rs:78:9
90-
|
91-
LL | 1.
92-
| ^^ help: consider adding suffix: `1.0_f64`
93-
94-
error: default numeric fallback might occur
95-
--> $DIR/default_numeric_fallback_f64.rs:84:27
89+
--> $DIR/default_numeric_fallback_f64.rs:82:27
9690
|
9791
LL | let f = || -> _ { 1. };
9892
| ^^ help: consider adding suffix: `1.0_f64`
9993

10094
error: default numeric fallback might occur
101-
--> $DIR/default_numeric_fallback_f64.rs:88:29
95+
--> $DIR/default_numeric_fallback_f64.rs:86:29
10296
|
10397
LL | let f = || -> f64 { 1. };
10498
| ^^ help: consider adding suffix: `1.0_f64`
10599

106100
error: default numeric fallback might occur
107-
--> $DIR/default_numeric_fallback_f64.rs:102:21
101+
--> $DIR/default_numeric_fallback_f64.rs:100:21
108102
|
109103
LL | generic_arg(1.);
110104
| ^^ help: consider adding suffix: `1.0_f64`
111105

112106
error: default numeric fallback might occur
113-
--> $DIR/default_numeric_fallback_f64.rs:105:32
107+
--> $DIR/default_numeric_fallback_f64.rs:103:32
114108
|
115109
LL | let x: _ = generic_arg(1.);
116110
| ^^ help: consider adding suffix: `1.0_f64`
117111

118112
error: default numeric fallback might occur
119-
--> $DIR/default_numeric_fallback_f64.rs:123:28
113+
--> $DIR/default_numeric_fallback_f64.rs:121:28
120114
|
121115
LL | GenericStruct { x: 1. };
122116
| ^^ help: consider adding suffix: `1.0_f64`
123117

124118
error: default numeric fallback might occur
125-
--> $DIR/default_numeric_fallback_f64.rs:126:36
119+
--> $DIR/default_numeric_fallback_f64.rs:124:36
126120
|
127121
LL | let _ = GenericStruct { x: 1. };
128122
| ^^ help: consider adding suffix: `1.0_f64`
129123

130124
error: default numeric fallback might occur
131-
--> $DIR/default_numeric_fallback_f64.rs:144:24
125+
--> $DIR/default_numeric_fallback_f64.rs:142:24
132126
|
133127
LL | GenericEnum::X(1.);
134128
| ^^ help: consider adding suffix: `1.0_f64`
135129

136130
error: default numeric fallback might occur
137-
--> $DIR/default_numeric_fallback_f64.rs:164:23
131+
--> $DIR/default_numeric_fallback_f64.rs:162:23
138132
|
139133
LL | s.generic_arg(1.);
140134
| ^^ help: consider adding suffix: `1.0_f64`
141135

142136
error: default numeric fallback might occur
143-
--> $DIR/default_numeric_fallback_f64.rs:174:25
137+
--> $DIR/default_numeric_fallback_f64.rs:172:25
144138
|
145139
LL | inline!(let x = 22.;);
146140
| ^^^ help: consider adding suffix: `22.0_f64`
147141
|
148142
= note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
149143

150-
error: aborting due to 24 previous errors
144+
error: aborting due to 23 previous errors
151145

tests/ui/default_numeric_fallback_i32.fixed

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ mod nested_local {
7474

7575
mod function_def {
7676
fn ret_i32() -> i32 {
77-
// Even though the output type is specified,
78-
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
79-
1_i32
77+
1
8078
}
8179

8280
fn test() {
@@ -186,4 +184,36 @@ fn check_expect_suppression() {
186184
let x = 21;
187185
}
188186

187+
mod type_already_infered {
188+
// Should NOT lint if bound to return type
189+
fn ret_i32() -> i32 {
190+
1
191+
}
192+
193+
// Should NOT lint if bound to return type
194+
fn ret_if_i32(b: bool) -> i32 {
195+
if b { 100 } else { 0 }
196+
}
197+
198+
// Should NOT lint if bound to return type
199+
fn ret_i32_tuple() -> (i32, i32) {
200+
(0, 1)
201+
}
202+
203+
// Should NOT lint if bound to return type
204+
fn ret_stmt(b: bool) -> (i32, i32) {
205+
if b {
206+
return (0, 1);
207+
}
208+
(0, 0)
209+
}
210+
211+
#[allow(clippy::useless_vec)]
212+
fn vec_macro() {
213+
// Should NOT lint in `vec!` call if the type was already stated
214+
let data_i32: Vec<i32> = vec![1, 2, 3];
215+
let data_i32 = vec![1_i32, 2_i32, 3_i32];
216+
}
217+
}
218+
189219
fn main() {}

tests/ui/default_numeric_fallback_i32.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ mod nested_local {
7474

7575
mod function_def {
7676
fn ret_i32() -> i32 {
77-
// Even though the output type is specified,
78-
// this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
7977
1
8078
}
8179

@@ -186,4 +184,36 @@ fn check_expect_suppression() {
186184
let x = 21;
187185
}
188186

187+
mod type_already_infered {
188+
// Should NOT lint if bound to return type
189+
fn ret_i32() -> i32 {
190+
1
191+
}
192+
193+
// Should NOT lint if bound to return type
194+
fn ret_if_i32(b: bool) -> i32 {
195+
if b { 100 } else { 0 }
196+
}
197+
198+
// Should NOT lint if bound to return type
199+
fn ret_i32_tuple() -> (i32, i32) {
200+
(0, 1)
201+
}
202+
203+
// Should NOT lint if bound to return type
204+
fn ret_stmt(b: bool) -> (i32, i32) {
205+
if b {
206+
return (0, 1);
207+
}
208+
(0, 0)
209+
}
210+
211+
#[allow(clippy::useless_vec)]
212+
fn vec_macro() {
213+
// Should NOT lint in `vec!` call if the type was already stated
214+
let data_i32: Vec<i32> = vec![1, 2, 3];
215+
let data_i32 = vec![1, 2, 3];
216+
}
217+
}
218+
189219
fn main() {}

tests/ui/default_numeric_fallback_i32.stderr

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,66 +98,78 @@ LL | let y = 1;
9898
| ^ help: consider adding suffix: `1_i32`
9999

100100
error: default numeric fallback might occur
101-
--> $DIR/default_numeric_fallback_i32.rs:79:9
102-
|
103-
LL | 1
104-
| ^ help: consider adding suffix: `1_i32`
105-
106-
error: default numeric fallback might occur
107-
--> $DIR/default_numeric_fallback_i32.rs:85:27
101+
--> $DIR/default_numeric_fallback_i32.rs:83:27
108102
|
109103
LL | let f = || -> _ { 1 };
110104
| ^ help: consider adding suffix: `1_i32`
111105

112106
error: default numeric fallback might occur
113-
--> $DIR/default_numeric_fallback_i32.rs:89:29
107+
--> $DIR/default_numeric_fallback_i32.rs:87:29
114108
|
115109
LL | let f = || -> i32 { 1 };
116110
| ^ help: consider adding suffix: `1_i32`
117111

118112
error: default numeric fallback might occur
119-
--> $DIR/default_numeric_fallback_i32.rs:103:21
113+
--> $DIR/default_numeric_fallback_i32.rs:101:21
120114
|
121115
LL | generic_arg(1);
122116
| ^ help: consider adding suffix: `1_i32`
123117

124118
error: default numeric fallback might occur
125-
--> $DIR/default_numeric_fallback_i32.rs:106:32
119+
--> $DIR/default_numeric_fallback_i32.rs:104:32
126120
|
127121
LL | let x: _ = generic_arg(1);
128122
| ^ help: consider adding suffix: `1_i32`
129123

130124
error: default numeric fallback might occur
131-
--> $DIR/default_numeric_fallback_i32.rs:124:28
125+
--> $DIR/default_numeric_fallback_i32.rs:122:28
132126
|
133127
LL | GenericStruct { x: 1 };
134128
| ^ help: consider adding suffix: `1_i32`
135129

136130
error: default numeric fallback might occur
137-
--> $DIR/default_numeric_fallback_i32.rs:127:36
131+
--> $DIR/default_numeric_fallback_i32.rs:125:36
138132
|
139133
LL | let _ = GenericStruct { x: 1 };
140134
| ^ help: consider adding suffix: `1_i32`
141135

142136
error: default numeric fallback might occur
143-
--> $DIR/default_numeric_fallback_i32.rs:145:24
137+
--> $DIR/default_numeric_fallback_i32.rs:143:24
144138
|
145139
LL | GenericEnum::X(1);
146140
| ^ help: consider adding suffix: `1_i32`
147141

148142
error: default numeric fallback might occur
149-
--> $DIR/default_numeric_fallback_i32.rs:165:23
143+
--> $DIR/default_numeric_fallback_i32.rs:163:23
150144
|
151145
LL | s.generic_arg(1);
152146
| ^ help: consider adding suffix: `1_i32`
153147

154148
error: default numeric fallback might occur
155-
--> $DIR/default_numeric_fallback_i32.rs:175:25
149+
--> $DIR/default_numeric_fallback_i32.rs:173:25
156150
|
157151
LL | inline!(let x = 22;);
158152
| ^^ help: consider adding suffix: `22_i32`
159153
|
160154
= note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
161155

162-
error: aborting due to 26 previous errors
156+
error: default numeric fallback might occur
157+
--> $DIR/default_numeric_fallback_i32.rs:215:29
158+
|
159+
LL | let data_i32 = vec![1, 2, 3];
160+
| ^ help: consider adding suffix: `1_i32`
161+
162+
error: default numeric fallback might occur
163+
--> $DIR/default_numeric_fallback_i32.rs:215:32
164+
|
165+
LL | let data_i32 = vec![1, 2, 3];
166+
| ^ help: consider adding suffix: `2_i32`
167+
168+
error: default numeric fallback might occur
169+
--> $DIR/default_numeric_fallback_i32.rs:215:35
170+
|
171+
LL | let data_i32 = vec![1, 2, 3];
172+
| ^ help: consider adding suffix: `3_i32`
173+
174+
error: aborting due to 28 previous errors
163175

0 commit comments

Comments
 (0)