Skip to main content

miniextendr_lint/rules/
ffi_unchecked.rs

1//! `_unchecked` FFI call outside guard context.
2//!
3//! - MXL301: Warns on `ffi::*_unchecked()` calls in user code.
4//!   These bypass main-thread routing and must only be called inside
5//!   `with_r_unwind_protect`, `with_r_thread`, or similar guard closures.
6
7use crate::crate_index::CrateIndex;
8use crate::diagnostic::Diagnostic;
9use crate::lint_code::LintCode;
10
11pub fn check(index: &CrateIndex, diagnostics: &mut Vec<Diagnostic>) {
12    for (path, data) in &index.file_data {
13        for (fn_name, line) in &data.ffi_unchecked_calls {
14            diagnostics.push(
15                Diagnostic::new(
16                    LintCode::MXL301,
17                    path,
18                    *line,
19                    format!(
20                        "`ffi::{}()` is a raw FFI call — only safe on R's main thread.",
21                        fn_name
22                    ),
23                )
24                .with_help(
25                    "Use the checked wrapper (without `_unchecked` suffix), or ensure this \
26                     call is inside `with_r_unwind_protect` / an `extern \"C-unwind\"` callback.",
27                ),
28            );
29        }
30    }
31}