redpen icon indicating copy to clipboard operation
redpen copied to clipboard

ReachabilityCheck with traits?

Open Erk- opened this issue 2 years ago • 0 comments

I was looking into adding a check to ensure no allocations happens and at least the naive approch with using ReachabilityCheck does not seem to work. It does not seem to catch any of trait methods such as Allocator or GlobalAllocator. And the only way I have gotten it to work is to name all the functions that does allocations. Which I am not sure is feasibly.

The source for my naive lint as far:

use crate::attribute::RedpenAttribute;
use crate::reachability_check::{Config, ReachabilityCheck};
use rustc_lint::Lint;
use rustc_session::{declare_tool_lint, impl_lint_pass};

pub struct DontAllocate;

impl Config for DontAllocate {
    fn new() -> DontAllocate {
        DontAllocate
    }

    fn lint(&self) -> &'static Lint {
        ALLOCS
    }

    fn is_relevant_leaf(&self, path: &str) -> bool {
        [
            "alloc::alloc::alloc",
            "alloc::alloc::alloc_zeroed",
            "alloc::alloc::dealloc",
            "alloc::alloc::realloc",

            // Traits
            // These does not seem to work?
            "alloc::alloc::GlobalAlloc::alloc",
            "alloc::alloc::GlobalAlloc::dealloc",
            "alloc::alloc::GlobalAlloc::alloc_zeroed",
            "alloc::alloc::GlobalAlloc::realloc",
            "alloc::alloc::Allocator::allocate",
            "alloc::alloc::Allocator::deallocate",
            "alloc::alloc::Allocator::allocate_zeroed",
            "alloc::alloc::Allocator::grow",
            "alloc::alloc::Allocator::grow_zeroed",
            "alloc::alloc::Allocator::shrink",

            "std::alloc::alloc",
            "std::alloc::alloc_zeroed",
            "std::alloc::dealloc",
            "std::alloc::realloc",

            // Traits
            // These does not seem to work?
            "std::alloc::GlobalAlloc::alloc",
            "std::alloc::GlobalAlloc::dealloc",
            "std::alloc::GlobalAlloc::alloc_zeroed",
            "std::alloc::GlobalAlloc::realloc",
            "std::alloc::Allocator::allocate",
            "std::alloc::Allocator::deallocate",
            "std::alloc::Allocator::allocate_zeroed",
            "std::alloc::Allocator::grow",
            "std::alloc::Allocator::grow_zeroed",
            "std::alloc::Allocator::shrink",

            "alloc::alloc::__rust_alloc",
            "alloc::alloc::__rust_alloc_zeroed",
            "alloc::alloc::__rust_realloc",
            "alloc::alloc::__rust_dealloc",

            "std::alloc::__rust_alloc",
            "std::alloc::__rust_alloc_zeroed",
            "std::alloc::__rust_realloc",
            "std::alloc::__rust_dealloc",
            
            "alloc::string::String::try_reserve",
            "alloc::string::String::try_reserve_exact",

            "std::string::String::try_reserve",
            "std::string::String::try_reserve_exact",

            "alloc::vec::Vec::try_reserve",
            "alloc::vec::Vec::try_reserve_exact",

            "std::vec::Vec::try_reserve",
            "std::vec::Vec::try_reserve_exact",

            "alloc::raw_vec::RawVec::try_reserve",
            "alloc::raw_vec::RawVec::try_reserve_exact",
        ]
        .contains(&path)
    }

    fn is_disabled_scope(&self, attr: &RedpenAttribute) -> bool {
        matches!(attr, RedpenAttribute::WontAllocate)
    }
    fn affected_description(&self) -> &'static str {
        "can allocate"
    }
}

declare_tool_lint! {
    pub redpen::ALLOCS,
    Allow,
    "The marked function cannot transitively allocate"
}

impl_lint_pass!(ReachabilityCheck<'_, DontAllocate> => [ALLOCS]);

pub type AllocFreedom<'a> = ReachabilityCheck<'a, DontAllocate>;

Erk- avatar Nov 21 '23 09:11 Erk-