@@ -135,33 +135,59 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest
135
135
}
136
136
}
137
137
138
- fn check_replace_with_uninit ( cx : & LateContext < ' _ , ' _ > , src : & Expr < ' _ > , expr_span : Span ) {
139
- if let ExprKind :: Call ( ref repl_func, ref repl_args) = src. kind {
140
- if_chain ! {
141
- if repl_args. is_empty( ) ;
142
- if let ExprKind :: Path ( ref repl_func_qpath) = repl_func. kind;
143
- if let Some ( repl_def_id) = cx. tables. qpath_res( repl_func_qpath, repl_func. hir_id) . opt_def_id( ) ;
144
- then {
145
- if cx. tcx. is_diagnostic_item( sym:: mem_uninitialized, repl_def_id) {
146
- span_lint_and_help(
147
- cx,
148
- MEM_REPLACE_WITH_UNINIT ,
149
- expr_span,
150
- "replacing with `mem::uninitialized()`" ,
151
- None ,
152
- "consider using the `take_mut` crate instead" ,
153
- ) ;
154
- } else if cx. tcx. is_diagnostic_item( sym:: mem_zeroed, repl_def_id) &&
155
- !cx. tables. expr_ty( src) . is_primitive( ) {
156
- span_lint_and_help(
157
- cx,
158
- MEM_REPLACE_WITH_UNINIT ,
159
- expr_span,
160
- "replacing with `mem::zeroed()`" ,
161
- None ,
162
- "consider using a default value or the `take_mut` crate instead" ,
163
- ) ;
164
- }
138
+ fn check_replace_with_uninit ( cx : & LateContext < ' _ , ' _ > , src : & Expr < ' _ > , dest : & Expr < ' _ > , expr_span : Span ) {
139
+ if_chain ! {
140
+ // check if replacement is mem::MaybeUninit::uninit().assume_init()
141
+ if let Some ( method_def_id) = cx. tables. type_dependent_def_id( src. hir_id) ;
142
+ if cx. tcx. is_diagnostic_item( sym:: assume_init, method_def_id) ;
143
+ then {
144
+ let mut applicability = Applicability :: MachineApplicable ;
145
+ span_lint_and_sugg(
146
+ cx,
147
+ MEM_REPLACE_WITH_UNINIT ,
148
+ expr_span,
149
+ "replacing with `mem::MaybeUninit::uninit().assume_init()`" ,
150
+ "consider using" ,
151
+ format!(
152
+ "std::ptr::read({})" ,
153
+ snippet_with_applicability( cx, dest. span, "" , & mut applicability)
154
+ ) ,
155
+ applicability,
156
+ ) ;
157
+ return ;
158
+ }
159
+ }
160
+
161
+ if_chain ! {
162
+ if let ExprKind :: Call ( ref repl_func, ref repl_args) = src. kind;
163
+ if repl_args. is_empty( ) ;
164
+ if let ExprKind :: Path ( ref repl_func_qpath) = repl_func. kind;
165
+ if let Some ( repl_def_id) = cx. tables. qpath_res( repl_func_qpath, repl_func. hir_id) . opt_def_id( ) ;
166
+ then {
167
+ if cx. tcx. is_diagnostic_item( sym:: mem_uninitialized, repl_def_id) {
168
+ let mut applicability = Applicability :: MachineApplicable ;
169
+ span_lint_and_sugg(
170
+ cx,
171
+ MEM_REPLACE_WITH_UNINIT ,
172
+ expr_span,
173
+ "replacing with `mem::uninitialized()`" ,
174
+ "consider using" ,
175
+ format!(
176
+ "std::ptr::read({})" ,
177
+ snippet_with_applicability( cx, dest. span, "" , & mut applicability)
178
+ ) ,
179
+ applicability,
180
+ ) ;
181
+ } else if cx. tcx. is_diagnostic_item( sym:: mem_zeroed, repl_def_id) &&
182
+ !cx. tables. expr_ty( src) . is_primitive( ) {
183
+ span_lint_and_help(
184
+ cx,
185
+ MEM_REPLACE_WITH_UNINIT ,
186
+ expr_span,
187
+ "replacing with `mem::zeroed()`" ,
188
+ None ,
189
+ "consider using a default value or the `take_mut` crate instead" ,
190
+ ) ;
165
191
}
166
192
}
167
193
}
@@ -209,7 +235,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
209
235
if let [ dest, src] = & * * func_args;
210
236
then {
211
237
check_replace_option_with_none( cx, src, dest, expr. span) ;
212
- check_replace_with_uninit( cx, src, expr. span) ;
238
+ check_replace_with_uninit( cx, src, dest , expr. span) ;
213
239
check_replace_with_default( cx, src, dest, expr. span) ;
214
240
}
215
241
}
0 commit comments