Skip to content

Add an API to get the basename of an intrinsic #65

Closed
@adpaco-aws

Description

@adpaco-aws

Context: In Kani we used to get the basename of intrinsic instances with mangled_name() until rust-lang/rust#121309 landed in the Rust compiler. Then some intrinsics became inlineable so their names became qualified, and this made our match on the intrinsic name to fail in those cases, leaving them as unsupported constructs as in this example:

warning: Found the following unsupported constructs:
             - _RNvNtCscyGW2MM2t5j_4core10intrinsics8unlikelyCs1eohKeNmpdS_5arith (3)
             - caller_location (1)
             - foreign function (1)
         
         Verification will fail if one or more of these constructs is reachable.
         See https://model-checking.github.io/kani/rust-feature-support.html for more details.

[...]

Failed Checks: _RNvNtCscyGW2MM2t5j_4core10intrinsics8unlikelyCs1eohKeNmpdS_5arith is not currently supported by Kani. Please post your example at https://github.com/model-checking/kani/issues/new/choose
 File: "/home/ubuntu/.rustup/toolchains/nightly-2024-02-18-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs", line 25, in core::num::<impl i8>::checked_add

In model-checking/kani#3048 we switched to using trimmed_name() to work around this, but that API may include type arguments if the intrinsic is defined on generics. So in those cases, we tweak the name to remove the type parameters as follows:

        /// Gets the basename of an intrinsic given its trimmed name.
        ///
        /// For example, given `arith_offset::<u8>` this returns `arith_offset`.
        fn intrinsic_basename(name: &str) -> &str {
            let scope_sep_count = name.matches("::").count();
            // We expect at most one `::` separator from trimmed intrinsic names
            debug_assert!(
                scope_sep_count < 2,
                "expected at most one `::` in intrinsic name, but found {scope_sep_count} in `{name}`"
            );
            let name_split = name.split_once("::");
            if let Some((base_name, _type_args)) = name_split { base_name } else { name }
        }
        // The trimmed name includes type arguments if the intrinsic was defined
        // on generic types, but we only need the basename for the match below.
        let intrinsic = intrinsic_basename(intrinsic);

However, this looks a little fragile and we probably shouldn't be doing it ourselves in the first place. Therefore, would it be possible to add an API to get the basename of an intrinsic? Or, if it's more appropriate, an API that removes the type arguments from the trimmed name as we're doing now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions