1//! Function visibility checks.
2//!
3//! - MXL106: Non-pub function has `/// @export` (contradictory).
45use crate::crate_index::{CrateIndex, LintKind};
6use crate::diagnostic::Diagnostic;
7use crate::lint_code::LintCode;
89pub fn check(index: &CrateIndex, diagnostics: &mut Vec<Diagnostic>) {
10for (path, data) in &index.file_data {
11for item in &data.miniextendr_items {
12if item.kind != LintKind::Function {
13continue;
14 }
1516let is_pub = data.fn_visibility.get(&item.name).copied().unwrap_or(false);
17let has_export_tag = data
18 .fn_doc_tags
19 .get(&item.name)
20 .is_some_and(|tags| tags.iter().any(|t| t == "export"));
2122// MXL106: Non-pub function with @export is contradictory
23if !is_pub && has_export_tag {
24 diagnostics.push(
25 Diagnostic::new(
26 LintCode::MXL106,
27 path,
28 item.line,
29::alloc::__export::must_use({
::alloc::fmt::format(format_args!("function `{0}` has `/// @export` but is not `pub`. The explicit @export tag still exports its R wrapper, contrary to the private Rust visibility.",
item.name))
})format!(
30"function `{}` has `/// @export` but is not `pub`. \
31 The explicit @export tag still exports its R wrapper, contrary to the private Rust visibility.",
32 item.name,
33 ),
34 )
35 .with_help("Use `pub fn` for the export, or remove `@export` to keep the R wrapper internal."),
36 );
37 }
38 }
39 }
40}