1- use clippy_utils:: diagnostics:: span_lint_and_sugg ;
1+ use clippy_utils:: diagnostics:: span_lint_and_then ;
22use clippy_utils:: higher:: VecArgs ;
33use clippy_utils:: source:: snippet;
44use clippy_utils:: visitors:: for_each_expr_without_closures;
@@ -7,9 +7,7 @@ use rustc_data_structures::packed::Pu128;
77use rustc_errors:: Applicability ;
88use rustc_hir:: { ConstArgKind , ExprKind , Node } ;
99use rustc_lint:: { LateContext , LateLintPass } ;
10- use rustc_middle:: ty:: Ty ;
1110use rustc_session:: declare_lint_pass;
12- use rustc_span:: Span ;
1311
1412declare_clippy_lint ! {
1513 /// ### What it does
@@ -85,77 +83,39 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
8583 let parent_hir_node = cx. tcx . parent_hir_node ( expr. hir_id ) ;
8684 let return_type = cx. typeck_results ( ) . expr_ty ( expr) ;
8785
88- if let Node :: LetStmt ( l) = parent_hir_node {
89- array_span_lint (
90- cx,
86+ let inner_expr = snippet ( cx, inner_expr. span . source_callsite ( ) , ".." ) ;
87+ let vec = if is_vec { "vec!" } else { "" } ;
88+
89+ let ( span, sugg) = match parent_hir_node {
90+ Node :: LetStmt ( l) => (
9191 l. span ,
92- inner_expr. span ,
93- l. pat . span ,
94- Some ( return_type) ,
95- is_vec,
96- false ,
97- ) ;
98- } else if let Node :: Expr ( x) = parent_hir_node
99- && let ExprKind :: Assign ( l, _, _) = x. kind
100- {
101- array_span_lint ( cx, x. span , inner_expr. span , l. span , Some ( return_type) , is_vec, true ) ;
102- } else {
103- span_lint_and_sugg (
104- cx,
105- ZERO_REPEAT_SIDE_EFFECTS ,
106- expr. span . source_callsite ( ) ,
107- "function or method calls as the initial value in zero-sized array initializers may cause side effects" ,
108- "consider using" ,
10992 format ! (
110- "{{ {}; {}[] as {return_type} }}" ,
111- snippet( cx, inner_expr. span. source_callsite( ) , ".." ) ,
112- if is_vec { "vec!" } else { "" } ,
93+ "{inner_expr}; let {var_name}: {return_type} = {vec}[];" ,
94+ var_name = snippet( cx, l. pat. span. source_callsite( ) , ".." )
11395 ) ,
114- Applicability :: Unspecified ,
115- ) ;
116- }
117- }
118- }
119-
120- fn array_span_lint (
121- cx : & LateContext < ' _ > ,
122- expr_span : Span ,
123- func_call_span : Span ,
124- variable_name_span : Span ,
125- expr_ty : Option < Ty < ' _ > > ,
126- is_vec : bool ,
127- is_assign : bool ,
128- ) {
129- let has_ty = expr_ty. is_some ( ) ;
130-
131- span_lint_and_sugg (
132- cx,
133- ZERO_REPEAT_SIDE_EFFECTS ,
134- expr_span. source_callsite ( ) ,
135- "function or method calls as the initial value in zero-sized array initializers may cause side effects" ,
136- "consider using" ,
137- format ! (
138- "{}; {}{}{} = {}[]{}{}" ,
139- snippet( cx, func_call_span. source_callsite( ) , ".." ) ,
140- if has_ty && !is_assign { "let " } else { "" } ,
141- snippet( cx, variable_name_span. source_callsite( ) , ".." ) ,
142- if let Some ( ty) = expr_ty
143- && !is_assign
144- {
145- format!( ": {ty}" )
146- } else {
147- String :: new( )
148- } ,
149- if is_vec { "vec!" } else { "" } ,
150- if let Some ( ty) = expr_ty
151- && is_assign
152- {
153- format!( " as {ty}" )
154- } else {
155- String :: new( )
96+ ) ,
97+ Node :: Expr ( x) if let ExprKind :: Assign ( l, _, _) = x. kind => (
98+ x. span ,
99+ format ! (
100+ "{inner_expr}; {var_name} = {vec}[] as {return_type}" ,
101+ var_name = snippet( cx, l. span. source_callsite( ) , ".." )
102+ ) ,
103+ ) ,
104+ _ => ( expr. span , format ! ( "{{ {inner_expr}; {vec}[] as {return_type} }}" ) ) ,
105+ } ;
106+ span_lint_and_then (
107+ cx,
108+ ZERO_REPEAT_SIDE_EFFECTS ,
109+ span. source_callsite ( ) ,
110+ "function or method calls as the initial value in zero-sized array initializers may cause side effects" ,
111+ |diag| {
112+ diag. span_suggestion_verbose (
113+ span. source_callsite ( ) ,
114+ "consider performing the side effect separately" ,
115+ sugg,
116+ Applicability :: Unspecified ,
117+ ) ;
156118 } ,
157- if is_assign { "" } else { ";" }
158- ) ,
159- Applicability :: Unspecified ,
160- ) ;
119+ ) ;
120+ }
161121}
0 commit comments