@@ -135,33 +135,59 @@ fn check_replace_option_with_none(cx: &LateContext<'_, '_>, src: &Expr<'_>, dest
135135 }
136136}
137137
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+ ) ;
165191 }
166192 }
167193 }
@@ -209,7 +235,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemReplace {
209235 if let [ dest, src] = & * * func_args;
210236 then {
211237 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) ;
213239 check_replace_with_default( cx, src, dest, expr. span) ;
214240 }
215241 }
0 commit comments