Is it possible to enable overflow checks in `--release` build in Rust? - rust

In --debug mode Rust, integer overflow is detected and it results in panic!(). Then, is it possible to enable this check in --release build without any additional compile option nor methods such as checked_add()? Pseudo code:
#[force(overflow_check)]
fn main() {
//...
}
If possible, totally ignoring --release options is ok. Pseudo code:
#[forbid(optimization)]
fn main() {
//...
}
Why without any additional compile option? Because I'd like to enable overflow check in competitive programming environment in which I have no control over how my code is built.

Related

how do i say that a feature is only available on a given platform

I know how to say that a dependancy is only needed on windows but how do I say (as a crate writer) that a feature is only available on windows.
I tried (based on the depends way)
[target.'cfg(windows)'.features]
windbg = []
but this doesn't work.
cargo build says
warning: unused manifest key: target.cfg(windows).features
and a client app using the crate fails saying that the feature doesn't exist
Currently Cargo is not able to specify feature's target platform, but you can add target_os to your code as an extra attribute to let compiler know that your feature will only be available on the target you set.
Let's say you have defined your feature like below.
#[cfg(feature = "windbg")]
mod windbg {
//...
}
You'll need to replace it with:
#[cfg(all(target_os = "windows", feature = "windbg"))]
mod windbg {
//...
}

How can I add rustdoc comments to proc macro-generated code?

I wrote a proc-macro library to accompany a library I'm writing - they go together, with the former being used to abstract away a lot of redundant code in the latter.
I am successfully generating several structs and impls in my proc macro. I am also using cargo doc with the library, and my documentation is what I expect. However, the documentation comments I'm creating in my proc macro aren't working as expected. Some code from my proc macro looks roughly like this:
#[proc_macro_derive(MyDerive)]
pub fn derive(input: TokenStream) -> TokenStream {
...
let expanded = quote! {
...
impl #my_struct {
/// This comment doesn't show up in documentation
pub fn foo(&self, n: i32) -> bool {
false
}
/// This comment DOES show up in documentation
pub fn bar(n: i32) -> Vec<String> {
...
}
}
}
expanded.into()
}
When I open up the generated documentation:
foo itself shows up in the documentation, but its comment doesn't
bar and its comment are in the documentation
If I change the comment for bar, the comment is not updated.
This third point tells me that I probably used some cargo doc flag at some point that works correctly, but I'm now using a different set of flags that don't work with proc macros. I don't want to document all my external crate dependencies (--no-deps), but I do want to document my private items (--document-private-items). I'm therefore generating docs with cargo doc --no-deps --document-private-items. I've also tried with --release.
I assume documentation is built from the source code and not from the built .so file itself, so I haven't been doing cargo build before doing cargo doc, though I have also tried this to debug this issue. So what is the right way to make sure my proc macro-generated code's documentation gets properly generated and updated?

Does String Literal Slice Usage with String references is Valid?

I have the following code block and it works as intended with no problem:
fn literal_taker(literals_slice: &[&str]){
println!("{:?}",literals_slice);
}
fn string_taker(string_value: String){
literal_taker(&[&string_value]);
}
fn main() {
let string_value = String::from("Hello");
string_taker(string_value);
}
Here, I pass the reference of String as a slice and it is compiling with no error and no clippy issue.
But the problem is, It is shown as warning in Clion Rust plugin:
Is it a bug of an plugin or am I doing something bad practice in Rust?
Playground
CLion Rust Plugin Version: 0.2.0.2106-182
The code does compile as written, as the playground clearly demonstrates. Therefore it is a bug in the IDEA Rust Plugin.
Unlike most other Rust plugins that use the Rust Language Server, which uses code from the compiler, and therefore generally provides diagnostics consistent with what the compiler will, IntelliJ IDEA has its own validator, which might get things wrong.

How to use a crate only for a given platform?

I would like to use the nix crate in a project.
However, this project also has an acceptable alternative implementation for OSX and Windows, where I would like to use a different crate.
What is the current way of expressing that I only want nix in Linux platforms?
There's two steps you need to make a dependency completely target-specific.
First, you need to specify this in your Cargo.toml, like so:
[target.'cfg(target_os = "linux")'.dependencies]
nix = "0.5"
This will make Cargo only include the dependency when that configuration is active. However, this means that on non-Linux OS, you'll get a compile error for every spot you use nix in your code. To remedy this, annotate those usages with a cfg attribute, like so:
#[cfg(target_os = "linux")]
use nix::foo;
Of course that has rippling effects as now other code using those items fails to compile as the import, function, module or whatever doesn't exist on non-Linux. One common way to deal with that is to put all usages of nix into one function and use a no-op function on all other OSes. For example:
#[cfg(target_os = "linux")]
fn do_stuff() {
nix::do_something();
}
#[cfg(not(target_os = "linux"))]
fn do_stuff() {}
fn main() {
do_stuff();
}
With this, on all platforms, the function do_stuff exists and can be called. Of course, you have to decide for yourself what the function should do on non Linux.

How to disable unused code warnings in Rust?

struct SemanticDirection;
fn main() {}
warning: struct is never used: `SemanticDirection`
--> src/main.rs:1:1
|
1 | struct SemanticDirection;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(dead_code)] on by default
I will turn these warnings back on for anything serious, but I am just tinkering with the language and this is driving me bats.
I tried adding #[allow(dead_code)] to my code, but that did not work.
You can either:
Add an allow attribute on a struct, module, function, etc.:
#[allow(dead_code)]
struct SemanticDirection;
Add a crate-level allow attribute; notice the !:
#![allow(dead_code)]
Pass it to rustc:
rustc -A dead_code main.rs
Pass it using cargo via the RUSTFLAGS environment variable:
RUSTFLAGS="$RUSTFLAGS -A dead_code" cargo build
Another way to disable this warning is to prefix the identifier by _:
struct _UnusedStruct {
_unused_field: i32,
}
fn main() {
let _unused_variable = 10;
}
This can be useful, for instance, with an SDL window:
let _window = video_subsystem.window("Rust SDL2 demo", 800, 600);
Prefixing with an underscore is different from using a lone underscore as the name. Doing the following will immediately destroy the window, which is unlikely to be the intended behavior.
let _ = video_subsystem.window("Rust SDL2 demo", 800, 600);
Put these two lines on the top of the file.
#![allow(dead_code)]
#![allow(unused_variables)]
Making the code public also stops the warnings; you'll need to make the enclosing mod's public too.
This makes sense when you're writing a library: your code is "unused" internally because it's intended to be used by client code.
also as an addition: rust provides four levels of lints (allow, warn, deny, forbid).
https://doc.rust-lang.org/rustc/lints/levels.html#lint-levels
For unused functions, you should make the function public, but watch out. If the struct isn't public, then you'll still get the error as in here:
//this should be public also
struct A{
A{}
}
impl A {
pub fn new() -> A {
}
}
Or if you don't want it to be public, you should put #[allow(unused)]
Directly way to just put the following in the head of the file
#![allow(dead_code, unused_variables)]
The dead_code lint detects unused, unexported items.
The unused_variables lint detects variables which are not used in any way.
More simple way is to put the following in the head of the file
#![allow(unused)]
Ref: rust lint list
You can always disable unused variables/functions by adding an (_) to the variable name, like so:
let _variable = vec![0; 10];
You can add the #[allow(dead_code)] attribute to the struct definition like so:
#[allow(dead_code)]
struct SemanticDirection;
Or you can disable the warning for the entire file by adding the attribute at the top of the file, like so:
#![allow(dead_code)]
struct SemanticDirection;
But these attributes only work if you have the dead_code lint enabled. By default, the dead_code lint is enabled in Rust, but you can disable it by adding the following to the top of your code:
#![deny(dead_code)]
This will disable the dead_code lint for the entire file.
It's generally a good idea to keep the dead_code lint enabled, as it can help you catch mistakes in your code and ensure that you are not introducing unnecessary code into your project. However, it can be annoying when you are just experimenting and trying out different things, so it's understandable if you want to disable it in those cases.
At the top of *.rs file:
#![allow(unused)] // FIXME
using features
#[cfg(feature = "dead_code")]
note: "dead_code" can be replaced by any word.

Resources