1use rustc_hir::def_id::DefId;
20use rustc_middle::ty::{Ty, TyKind};
21use rustc_middle::ty::TyCtxt;
22
23fn any_of(callee: Option<DefId>, items: &[Option<DefId>]) -> bool {
25 callee.is_some_and(|c| items.contains(&Some(c)))
26}
27
28fn any_fn(callee: Option<DefId>, fns: &[DefId]) -> bool {
30 callee.is_some_and(|c| fns.contains(&c))
31}
32
33pub fn is_ownership_reconstruction(callee: Option<DefId>) -> bool {
41 any_of(
42 callee,
43 &[
44 crate::def_id::box_from_raw(),
45 crate::def_id::cstring_from_raw(),
46 crate::def_id::arc_from_raw(),
47 crate::def_id::rc_from_raw(),
48 crate::def_id::box_from_raw_in(),
49 crate::def_id::arc_from_raw_in(),
50 crate::def_id::rc_from_raw_in(),
51 crate::def_id::cstring_from_vec_with_nul_unchecked(),
52 ],
53 )
54}
55
56pub fn is_manually_drop_drop(callee: Option<DefId>) -> bool {
60 any_of(callee, &[crate::def_id::manually_drop()])
61}
62
63pub fn is_std_drop(callee: Option<DefId>) -> bool {
66 any_of(callee, &[crate::def_id::drop()])
67}
68
69pub fn is_drop_in_place(callee: Option<DefId>) -> bool {
73 any_of(callee, &[crate::def_id::drop_in_place()])
74}
75
76pub fn is_as_ptr(callee: Option<DefId>) -> bool {
86 any_of(
87 callee,
88 &[
89 crate::def_id::slice_as_ptr(),
90 crate::def_id::slice_as_mut_ptr(),
91 crate::def_id::str_as_ptr(),
92 crate::def_id::str_as_mut_ptr(),
93 crate::def_id::vec_as_ptr(),
94 crate::def_id::vec_as_mut_ptr(),
95 crate::def_id::cstr_as_ptr(),
96 crate::def_id::nonnull_as_ptr(),
97 crate::def_id::const_ptr_slice_as_ptr(),
98 crate::def_id::mut_ptr_slice_as_mut_ptr(),
99 crate::def_id::nonnull_slice_as_mut_ptr(),
100 crate::def_id::box_as_ptr(),
101 crate::def_id::box_as_mut_ptr(),
102 crate::def_id::maybe_uninit_as_ptr(),
103 crate::def_id::maybe_uninit_as_mut_ptr(),
104 crate::def_id::arc_as_ptr(),
105 crate::def_id::rc_as_ptr(),
106 crate::def_id::const_ptr_cast(),
107 crate::def_id::const_ptr_cast_mut(),
108 crate::def_id::const_ptr_cast_array(),
109 crate::def_id::mut_ptr_cast(),
110 crate::def_id::mut_ptr_cast_const(),
111 crate::def_id::mut_ptr_cast_array(),
112 crate::def_id::nonnull_cast(),
113 crate::def_id::box_into_raw(),
114 crate::def_id::cstring_into_raw(),
115 crate::def_id::arc_into_raw(),
116 crate::def_id::rc_into_raw(),
117 ],
118 )
119}
120
121pub(crate) fn is_raw_ptr_cast(callee: Option<DefId>) -> bool {
128 any_of(
129 callee,
130 &[
131 crate::def_id::const_ptr_cast(),
132 crate::def_id::const_ptr_cast_mut(),
133 crate::def_id::const_ptr_cast_array(),
134 crate::def_id::mut_ptr_cast(),
135 crate::def_id::mut_ptr_cast_const(),
136 crate::def_id::mut_ptr_cast_array(),
137 ],
138 )
139}
140
141pub fn is_as_ptr_valid(callee: Option<DefId>) -> bool {
147 is_as_ptr(callee) && !is_raw_ptr_cast(callee)
148}
149
150pub fn is_container_as_ptr(tcx: TyCtxt<'_>, callee: DefId) -> bool {
158 let name = tcx.item_name(callee);
159 if name.as_str() != "as_ptr" && name.as_str() != "as_mut_ptr" {
160 return false;
161 }
162 let Some(self_ty) = crate::helpers::name::get_struct_self_ty(tcx, callee) else {
163 return false;
164 };
165 let TyKind::Adt(adt, _) = self_ty.kind() else {
166 return false;
167 };
168 is_std_vec(adt.did())
169 || is_std_nonnull(adt.did())
170 || is_std_box(adt.did())
171 || is_maybe_uninit_type(adt.did())
172 || is_std_cstring(adt.did())
173}
174
175pub fn is_str_as_bytes(callee: Option<DefId>) -> bool {
178 any_of(callee, &[crate::def_id::str_as_bytes()])
179}
180
181pub(crate) fn is_element_ptr_add(callee: Option<DefId>) -> bool {
191 any_of(
192 callee,
193 &[
194 crate::def_id::const_ptr_add(),
195 crate::def_id::const_ptr_wrapping_add(),
196 crate::def_id::const_ptr_offset(),
197 crate::def_id::const_ptr_wrapping_offset(),
198 crate::def_id::mut_ptr_add(),
199 crate::def_id::mut_ptr_wrapping_add(),
200 crate::def_id::mut_ptr_offset(),
201 crate::def_id::mut_ptr_wrapping_offset(),
202 crate::def_id::nonnull_add(),
203 crate::def_id::nonnull_offset(),
204 ],
205 )
206}
207
208pub(crate) fn is_element_ptr_sub(callee: Option<DefId>) -> bool {
210 any_of(
211 callee,
212 &[
213 crate::def_id::const_ptr_sub(),
214 crate::def_id::const_ptr_wrapping_sub(),
215 crate::def_id::mut_ptr_sub(),
216 crate::def_id::mut_ptr_wrapping_sub(),
217 crate::def_id::nonnull_sub(),
218 ],
219 )
220}
221
222pub(crate) fn is_byte_ptr_add(callee: Option<DefId>) -> bool {
225 any_of(
226 callee,
227 &[
228 crate::def_id::const_ptr_byte_add(),
229 crate::def_id::const_ptr_wrapping_byte_add(),
230 crate::def_id::const_ptr_byte_offset(),
231 crate::def_id::const_ptr_wrapping_byte_offset(),
232 crate::def_id::mut_ptr_byte_add(),
233 crate::def_id::mut_ptr_wrapping_byte_add(),
234 crate::def_id::mut_ptr_byte_offset(),
235 crate::def_id::mut_ptr_wrapping_byte_offset(),
236 crate::def_id::nonnull_byte_add(),
237 crate::def_id::nonnull_byte_offset(),
238 ],
239 )
240}
241
242pub(crate) fn is_byte_ptr_sub(callee: Option<DefId>) -> bool {
244 any_of(
245 callee,
246 &[
247 crate::def_id::const_ptr_byte_sub(),
248 crate::def_id::const_ptr_wrapping_byte_sub(),
249 crate::def_id::mut_ptr_byte_sub(),
250 crate::def_id::mut_ptr_wrapping_byte_sub(),
251 crate::def_id::nonnull_byte_sub(),
252 ],
253 )
254}
255
256pub fn is_pointer_add(callee: Option<DefId>) -> bool {
260 is_element_ptr_add(callee) || is_byte_ptr_add(callee)
261}
262
263pub fn is_pointer_sub(callee: Option<DefId>) -> bool {
265 is_element_ptr_sub(callee) || is_byte_ptr_sub(callee)
266}
267
268pub fn is_byte_ptr_arith(callee: Option<DefId>) -> bool {
270 is_byte_ptr_add(callee) || is_byte_ptr_sub(callee)
271}
272
273pub fn is_layout_constant(callee: Option<DefId>) -> bool {
279 any_of(
280 callee,
281 &[
282 crate::def_id::mem_size_of(),
283 crate::def_id::mem_align_of(),
284 crate::def_id::intrinsics_size_of(),
285 crate::def_id::intrinsics_align_of(),
286 ],
287 )
288}
289
290pub fn is_align_offset(callee: Option<DefId>) -> bool {
293 any_of(
294 callee,
295 &[
296 crate::def_id::ptr_align_offset(),
297 crate::def_id::nonnull_align_offset(),
298 crate::def_id::const_ptr_align_offset(),
299 crate::def_id::mut_ptr_align_offset(),
300 ],
301 )
302}
303
304pub fn is_ptr_write(callee: Option<DefId>) -> bool {
309 any_of(
310 callee,
311 &[
312 crate::def_id::ptr_write(),
313 crate::def_id::ptr_write_unaligned(),
314 crate::def_id::ptr_write_volatile(),
315 crate::def_id::ptr_write_bytes(),
316 ],
317 )
318}
319
320pub fn is_ptr_read(callee: Option<DefId>) -> bool {
324 any_of(
325 callee,
326 &[
327 crate::def_id::ptr_read(),
328 crate::def_id::ptr_read_unaligned(),
329 crate::def_id::ptr_read_volatile(),
330 crate::def_id::copy_to(),
331 crate::def_id::copy_to_nonoverlapping(),
332 crate::def_id::copy_from(),
333 crate::def_id::copy_from_nonoverlapping(),
334 crate::def_id::assume_init_read(),
335 crate::def_id::intrinsics_copy(),
336 crate::def_id::intrinsics_copy_nonoverlapping(),
337 ],
338 )
339}
340
341pub fn is_maybe_uninit_write(callee: Option<DefId>) -> bool {
346 any_of(callee, &[crate::def_id::maybe_uninit_write()])
347}
348
349pub fn is_maybe_uninit_uninit(callee: Option<DefId>) -> bool {
351 any_of(callee, &[crate::def_id::maybe_uninit_uninit()])
352}
353
354pub fn is_maybe_uninit_assume_init(callee: Option<DefId>) -> bool {
357 any_of(
358 callee,
359 &[
360 crate::def_id::maybe_uninit_assume_init(),
361 crate::def_id::assume_init_read(),
362 crate::def_id::maybe_uninit_assume_init_ref(),
363 crate::def_id::maybe_uninit_assume_init_mut(),
364 ],
365 )
366}
367
368pub fn is_mem_copy_or_write(callee: Option<DefId>) -> bool {
373 any_of(
374 callee,
375 &[
376 crate::def_id::intrinsics_copy(),
377 crate::def_id::intrinsics_copy_nonoverlapping(),
378 crate::def_id::copy_from_nonoverlapping(),
379 crate::def_id::copy_to_nonoverlapping(),
380 crate::def_id::ptr_write(),
381 crate::def_id::ptr_write_bytes(),
382 ],
383 )
384}
385
386pub fn is_len(callee: Option<DefId>) -> bool {
393 any_fn(callee, crate::def_id::len_fns())
394}
395
396pub fn is_capacity(callee: Option<DefId>) -> bool {
398 any_fn(callee, crate::def_id::capacity_fns())
399}
400
401pub fn is_unwrap(callee: Option<DefId>) -> bool {
402 any_of(
403 callee,
404 &[
405 crate::def_id::option_unwrap(),
406 crate::def_id::option_expect(),
407 crate::def_id::option_unwrap_unchecked(),
408 crate::def_id::result_unwrap(),
409 crate::def_id::result_unwrap_err(),
410 crate::def_id::result_expect(),
411 crate::def_id::result_expect_err(),
412 crate::def_id::result_unwrap_unchecked(),
413 ],
414 )
415}
416
417pub fn is_from_raw_parts(callee: Option<DefId>) -> bool {
424 any_fn(callee, crate::def_id::from_raw_parts_fns())
425}
426
427pub fn is_from_raw_parts_mut(callee: Option<DefId>) -> bool {
429 any_fn(callee, crate::def_id::from_raw_parts_mut_fns())
430}
431
432pub fn is_cstr_from_ptr(callee: Option<DefId>) -> bool {
433 any_of(callee, &[crate::def_id::cstr_from_ptr()])
434}
435
436pub fn is_cstr_unchecked_constructor(callee: Option<DefId>) -> bool {
440 any_of(
441 callee,
442 &[
443 crate::def_id::cstr_from_bytes_with_nul_unchecked(),
444 crate::def_id::cstring_from_vec_with_nul_unchecked(),
445 ],
446 )
447}
448
449pub fn is_vec_push_or_reserve(callee: Option<DefId>) -> bool {
452 any_of(
453 callee,
454 &[
455 crate::def_id::vec_push(),
456 crate::def_id::vec_reserve(),
457 crate::def_id::vec_reserve_exact(),
458 ],
459 )
460}
461pub fn is_vec_alloc_constructor(callee: Option<DefId>) -> bool {
462 any_of(callee, &[crate::def_id::vec_from_elem()])
463}
464pub fn is_vec_from_box(callee: Option<DefId>) -> bool {
465 any_of(
466 callee,
467 &[
468 crate::def_id::slice_into_vec(),
469 #[cfg(rapx_ge_99)]
470 crate::def_id::box_assume_init_into_vec_unsafe(),
471 ],
472 )
473}
474pub fn is_exchange_malloc(callee: Option<DefId>) -> bool {
476 callee.is_some_and(|c| crate::def_id::exchange_malloc() == Some(c))
477}
478pub fn is_slice_to_vec(callee: Option<DefId>) -> bool {
481 any_of(callee, &[crate::def_id::slice_to_vec()])
482}
483pub fn is_vec_with_capacity(callee: Option<DefId>) -> bool {
486 any_fn(callee, crate::def_id::with_capacity_fns())
487}
488pub fn is_box_alloc_ctor(callee: Option<DefId>) -> bool {
491 any_fn(callee, crate::def_id::box_alloc_ctors())
492}
493pub fn is_into_boxed_slice(callee: Option<DefId>) -> bool {
494 any_of(callee, &[crate::def_id::vec_into_boxed_slice()])
495}
496
497pub fn is_ownership_transfer(callee: Option<DefId>) -> bool {
506 let Some(callee) = callee else { return false };
507 is_ownership_reconstruction(Some(callee))
508 && !crate::def_id::contains(
509 &[crate::def_id::cstring_from_vec_with_nul_unchecked()],
510 callee,
511 )
512}
513
514pub fn is_vec_ownership_transfer(callee: Option<DefId>) -> bool {
515 any_fn(callee, crate::def_id::vec_ownership_transfer_fns())
516}
517
518pub(crate) fn is_nonnull_checked_new(callee: Option<DefId>) -> bool {
520 any_of(callee, &[crate::def_id::nonnull_new()])
521}
522
523pub(crate) fn is_nonnull_new_unchecked(callee: Option<DefId>) -> bool {
529 any_of(callee, &[crate::def_id::nonnull_new_unchecked()])
530}
531
532pub fn is_nonnull_as_ref_as_mut(callee: Option<DefId>) -> bool {
534 any_of(
535 callee,
536 &[
537 crate::def_id::nonnull_as_ref(),
538 crate::def_id::nonnull_as_mut(),
539 ],
540 )
541}
542
543pub fn is_nonnull_as_mut(callee: Option<DefId>) -> bool {
545 any_of(callee, &[crate::def_id::nonnull_as_mut()])
546}
547
548pub(crate) fn is_select_unpredictable(callee: Option<DefId>) -> bool {
551 any_of(
552 callee,
553 &[
554 crate::def_id::select_unpredictable(),
555 crate::def_id::hint_select_unpredictable(),
556 ],
557 )
558}
559
560pub fn is_vec_invalidating_method(callee: Option<DefId>) -> bool {
563 any_of(
564 callee,
565 &[
566 crate::def_id::vec_push(),
567 crate::def_id::vec_reserve(),
568 crate::def_id::vec_reserve_exact(),
569 crate::def_id::vec_shrink_to_fit(),
570 crate::def_id::vec_shrink_to(),
571 crate::def_id::vec_insert(),
572 crate::def_id::vec_remove(),
573 crate::def_id::vec_clear(),
574 crate::def_id::vec_truncate(),
575 crate::def_id::vec_set_len(),
576 ],
577 )
578}
579
580pub fn is_ownership_return(callee: Option<DefId>) -> bool {
583 any_of(
584 callee,
585 &[
586 crate::def_id::box_into_raw(),
587 crate::def_id::cstring_into_raw(),
588 crate::def_id::arc_into_raw(),
589 crate::def_id::rc_into_raw(),
590 ],
591 )
592}
593
594pub fn is_benign_origin_use(callee: Option<DefId>) -> bool {
597 any_of(
598 callee,
599 &[
600 crate::def_id::const_ptr_is_null(),
601 crate::def_id::const_ptr_addr(),
602 crate::def_id::const_ptr_cast(),
603 crate::def_id::const_ptr_cast_mut(),
604 crate::def_id::const_ptr_slice_is_empty(),
605 crate::def_id::const_ptr_slice_len(),
606 crate::def_id::const_ptr_slice_as_ptr(),
607 crate::def_id::mut_ptr_is_null(),
608 crate::def_id::mut_ptr_addr(),
609 crate::def_id::mut_ptr_cast(),
610 crate::def_id::mut_ptr_cast_const(),
611 crate::def_id::mut_ptr_slice_is_empty(),
612 crate::def_id::mut_ptr_slice_len(),
613 crate::def_id::mut_ptr_slice_as_mut_ptr(),
614 crate::def_id::nonnull_addr(),
615 crate::def_id::nonnull_cast(),
616 crate::def_id::nonnull_as_ptr(),
617 crate::def_id::nonnull_slice_is_empty(),
618 crate::def_id::nonnull_slice_len(),
619 crate::def_id::nonnull_slice_as_mut_ptr(),
620 crate::def_id::slice_len(),
621 crate::def_id::slice_is_empty(),
622 crate::def_id::slice_as_ptr(),
623 crate::def_id::slice_as_mut_ptr(),
624 crate::def_id::str_len(),
625 crate::def_id::str_is_empty(),
626 crate::def_id::str_as_ptr(),
627 crate::def_id::str_as_mut_ptr(),
628 crate::def_id::vec_len(),
629 crate::def_id::vec_is_empty(),
630 crate::def_id::vec_as_ptr(),
631 crate::def_id::vec_as_mut_ptr(),
632 crate::def_id::string_len(),
633 crate::def_id::string_is_empty(),
634 crate::def_id::cstr_as_ptr(),
635 crate::def_id::cstr_is_empty(),
636 ],
637 )
638}
639
640pub fn is_std_vec(def_id: DefId) -> bool {
646 crate::def_id::vec_types().contains(&def_id)
647}
648pub fn is_std_box(def_id: DefId) -> bool {
649 crate::def_id::box_types().contains(&def_id)
650}
651pub fn is_std_cstring(def_id: DefId) -> bool {
652 crate::def_id::cstring_types().contains(&def_id)
653}
654pub fn is_std_nonnull(def_id: DefId) -> bool {
655 crate::def_id::nonnull_types().contains(&def_id)
656}
657pub fn is_maybe_uninit_type(def_id: DefId) -> bool {
658 crate::def_id::maybe_uninit_types().contains(&def_id)
659}
660
661pub fn is_maybe_uninit_ty(ty: Ty<'_>) -> bool {
665 use rustc_middle::ty::TyKind;
666 let mut t = ty;
667 loop {
668 match t.kind() {
669 TyKind::Slice(e) | TyKind::Array(e, _) => t = *e,
670 TyKind::RawPtr(e, _) | TyKind::Ref(_, e, _) => t = *e,
671 TyKind::Adt(adt, _) => return is_maybe_uninit_type(adt.did()),
672 _ => return false,
673 }
674 }
675}
676pub fn is_std_iter_or_itermut(def_id: DefId) -> bool {
677 crate::def_id::iter_types().contains(&def_id)
678}
679pub fn is_std_ordering(def_id: DefId) -> bool {
680 crate::def_id::ordering_types().contains(&def_id)
681}
682
683pub fn is_min_like(callee: Option<DefId>) -> bool {
689 any_fn(callee, crate::def_id::min_like_fns())
690}
691pub fn is_max(callee: Option<DefId>) -> bool {
692 any_fn(callee, crate::def_id::max_fns())
693}
694pub fn is_clamp(callee: Option<DefId>) -> bool {
695 any_fn(callee, crate::def_id::clamp_fns())
696}
697pub fn is_abs(callee: Option<DefId>) -> bool {
698 any_fn(callee, crate::def_id::abs_fns())
699}
700pub fn is_neg(callee: Option<DefId>) -> bool {
701 any_fn(callee, crate::def_id::neg_fns())
702}
703pub fn is_sat_unchecked_add(callee: Option<DefId>) -> bool {
704 any_fn(callee, crate::def_id::sat_unchecked_add_fns())
705}
706pub fn is_sat_unchecked_mul(callee: Option<DefId>) -> bool {
707 any_fn(callee, crate::def_id::sat_unchecked_mul_fns())
708}
709pub fn is_checked_add(callee: Option<DefId>) -> bool {
710 any_fn(callee, crate::def_id::checked_add_fns())
711}
712pub fn is_checked_mul(callee: Option<DefId>) -> bool {
713 any_fn(callee, crate::def_id::checked_mul_fns())
714}
715pub fn is_overflowing_abs_neg(callee: Option<DefId>) -> bool {
716 any_fn(callee, crate::def_id::overflowing_nz_fns())
717}
718pub fn is_bit_preserving_nz(callee: Option<DefId>) -> bool {
719 any_fn(callee, crate::def_id::bit_preserving_nz_fns())
720}
721pub fn is_checked_nonzero_iff(callee: Option<DefId>) -> bool {
722 any_fn(callee, crate::def_id::checked_nonzero_iff_fns())
723}
724pub fn is_checked_next_pow2(callee: Option<DefId>) -> bool {
725 any_fn(callee, crate::def_id::checked_next_pow2_fns())
726}
727pub fn is_layout_align(callee: Option<DefId>) -> bool {
728 any_fn(callee, crate::def_id::layout_align_fns())
729}
730pub fn is_split_at(callee: Option<DefId>) -> bool {
731 any_fn(callee, crate::def_id::split_at_fns())
732}
733
734pub fn is_align_to_local(callee: Option<DefId>) -> bool {
742 any_fn(callee, crate::def_id::align_to_local_fns())
743}
744pub fn is_iter_position(callee: Option<DefId>) -> bool {
745 any_fn(callee, crate::def_id::iter_position_fns())
746}
747pub fn is_strlen(callee: Option<DefId>) -> bool {
748 any_fn(callee, crate::def_id::strlen_fns())
749}
750pub fn is_slice_get_unchecked(callee: Option<DefId>) -> bool {
751 any_fn(callee, crate::def_id::slice_get_unchecked_fns())
752}
753
754pub fn is_sliceindex_get_unchecked(callee: Option<DefId>) -> bool {
760 any_fn(callee, crate::def_id::sliceindex_get_unchecked_fns())
761}
762
763pub fn is_slice_range(callee: Option<DefId>) -> bool {
766 any_fn(callee, crate::def_id::slice_range_fns())
767}
768
769pub fn is_mem_replace(callee: Option<DefId>) -> bool {
772 any_of(callee, &[crate::def_id::replace()])
773}