warning: `auto-ref` (bin "auto-ref") generated 1 warning - rust

I get this warnig from the rust compiler, when running the following code:
fn main() {
let test = 3;
let bar = Bar(test);
(&bar).foo();
}
#[derive(Debug, Copy, Clone)]
struct Bar(i32);
impl Bar {
fn foo(self) -> () {
println!("{:?}", self);
}
}
I wanted to try out the auto-ref rule on fn method_name(self).
I run cargo 1.61 on termux.
Can anyone explain to me what the actual warning is or how I can get it to be displayed?
EDIT:
Here's the termux console output
~/auto-ref/src $ cargo run
warning: Hard linking files in the incremental compilation cache failed. Copying files instead. Consider moving the cache directory to a file system which supports hard linking in session dir `/data/data/com.termux/files/home/auto-ref/target/debug/incremental/auto_ref-2c1jpkoha1tv/s-gbbxgywkr4-kv6r95-working`
warning: `auto-ref` (bin "auto-ref") generated 1 warning
Finished dev [unoptimized + debuginfo] target(s) in 1.11s
Running `/data/data/com.termux/files/home/auto-ref/target/debug/auto-ref` Bar(3)
~/auto-ref/src $

Ok, I understand now. What I thought was a warning was just the warnings summary. I got confused because I tried to test a rule that says that a &self method argument can automatically be referenced when using it on type self. The warning mentions auto-ref -- hence my confusion
-- but I think is actually about the linking warning.
What I tried was the following;
use the aut ref rule such that you do
bar.foo()
instead of
(&bar).foo()
.
Also the example code doesn't even do this. Here would be the correct example.
fn main() {
let test = 3;
let bar = Bar(test);
bar.foo();
}
#[derive(Debug, Copy, Clone)]
struct Bar(i32);
impl Bar {
fn foo(&self) -> () {
println!("{:?}", self);
}
}

Related

Cargo: How to include the entire directory or file in feature flags?

I'm working on a Rust project. I'm using Cargo feature flags for conditional compilation of the some code. There are cases where I have to include the entire file in the feature flags so doing so adding #[cfg(feature="my-flag")] over every function & use statement doesn't make much sense.
So to include the entire file in the feature flag I'm thinking to surround all the contents in the file a block & add the feature flag for the block.
#[cfg(feature="my-flag")]
{
use crate::access_control::{func1, func2};
use crate::models;
...
#[derive(Debug)]
pub enum MyEnum{..}
#[derive(Clone)]
pub Struct MyStruct{..}
pub fn my_func() {...}
fn my_func_internal() {...}
...
}
But I'm getting the error Syntax Error: expected an item after attributes
Also, there are also some cases where I want the entire directory to be included the feature flags. How should I go about it? Doing the adding feature flags for every file is one way. Does a better way exist?
As in #MarcusDunn's answer, the proper solution is to apply the attribute to the mod declaration:
// This conditionally includes a module which implements WEBP support.
#[cfg(feature = "webp")]
pub mod webp;
However for the sake of completeness, I would point out that attributes can be applied to the item they're in instead of being applied to the following item. These are called "inner attributes" and are specified by adding a ! after the #:
#![cfg(feature="my-flag")] // Applies to the whole file
use crate::access_control::{func1, func2};
use crate::models;
#[derive(Debug)]
pub enum MyEnum {}
#[derive(Clone)]
pub struct MyStruct {}
pub fn my_func() {}
fn my_func_internal() {}
From https://doc.rust-lang.org/cargo/reference/features.html
// This conditionally includes a module which implements WEBP support.
#[cfg(feature = "webp")]
pub mod webp;
This could be an entire directory - or a single file, depends how you structure your modules.
You can use conditional compilation on modules. Perhaps something like this would work for your use case:
#[cfg(feature = "feat")]
use feat::S;
#[cfg(not(feature = "feat"))]
use no_feat::S;
mod feat {
pub const S: &str = "feat";
}
mod no_feat {
pub const S: &str = "no_feat";
}
fn main() {
println!("{}", S);
}
Running with cargo run:
no_feat
Running with cargo run --features feat:
feat
You can use the cfg-if crate:
cfg_if::cfg_if! {
if #[cfg(feature = "my-flag")] {
// ...
}
}

Why are some clippy lints gone if my modules are public?

I have a code that looks approximately like this:
// src/bitboard.rs
#[derive(Copy, Clone, Debug)]
pub struct Bitboard {
value: u64
}
impl Bitboard {
pub const fn new(value: u64) -> Self {
Self { value }
}
pub const fn get_bit(&self, k: u64) -> u64 {
((1u64 << k) & self.value) >> k
}
}
// src/main.rs
pub mod bitboard;
use crate::bitboard::Bitboard;
fn main() {
let bitboard = Bitboard::new(0);
dbg!(bitboard);
}
If I compile it exactly like this, it works without any errors or warnings.
However, if I change my pub mod bitboard to mod bitboard, then clippy starts giving me this warning:
warning: this argument (8 byte) is passed by reference, but would be more efficient if passed by value (limit: 8 byte)
pub const fn get_bit(&self, k: u64) -> u64 {
^^^^^ help: consider passing by value instead: `self`
= note: `-W clippy::trivially-copy-pass-by-ref` implied by `-W clippy::pedantic`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref
I understand what clippy is telling me to do. But I do not understand why it does not suggest this when my module is declared as public. Any ideas?
P.S.: I am using rustc 1.60.0, clippy 0.1.60.
Edit: I should also add that this is not the only extra lint that happens when I remove the pub from my modules. For instance, I also had 1 new clippy::upper_case_acronyms, and 1 new clippy::enum_variant_names.
Edit 2: As requested, I'm including more examples to show the same behaviour happening to clippy::upper-case_acronyms and clippy::enum_variant_names:
// src/fen.rs
pub struct FEN; // upper case acronyms happens here
pub enum FENValidationError { // enum variant names happens here
InvalidFieldsCount,
InvalidPiecePlacement,
InvalidRankSize,
}
// src/main.rs
mod fen; // same thing here. If this becomes `pub mod fen`, the two lint warnings above disappear.
Because changing a public API like that is a breaking change.
Changing the argument to pass by value like clippy recommends is easy if its an internal method, since you have control over all of the code that uses it. But if the argument is on a function or method exposed as part of the public API, changing it would require that all the other projects that use it change too, which is usually unacceptable for something as minor as passing a small Copy value by reference.

Rust Book 12.3 - unresolved import error [E4032]

I am new to Rust and working on the exercise in Chapter 12.3 in the book.
I am pretty confident that my code is the same as that in the book (hard to tell for sure because of the 'snips'). However I get an unresolved import error when I try cargo build or cargo run from the project directory, minigrep/
src/main.rs
use std::env;
use std::process;
use minigrep;
use minigrep::Config;
fn main() {
let args: Vec<String> = env::args().collect();
let config = Config::new(&args).unwrap_or_else(|err| {
println!("Problem parsing args: {}", err);
process::exit(1);
});
println!("Searching for {}", config.query);
println!("In file {}", config.filename);
if let Err(e) = minigrep::run(config) {
println!("Application error: {}", e);
process::exit(1);
}
}
src/lib.rs
use std::fs;
use std::error::Error;
pub struct Config {
pub query: String,
pub filename: String,
}
impl Config {
pub fn new(args: &[String]) -> Result <Config, &'static str> {
if args.len() < 3 {
return Err("not enough args");
}
let query = args[1].clone();
let filename = args[2].clone();
Ok(Config { query, filename })
}
}
pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
let contents = fs::read_to_string(config.filename)?;
println!("With text:\n {}", contents);
Ok(())
}
There is a contradiction between the code samples for the exercise in chapter 12.3 and the earlier section in chapter 7: '7.2 -- Modules and use to control scope -- Separating modules into different files'.
Using 7.2's syntax complies:
mod lib; //.. instead of 'use minigrep'
use lib::Config; //.. instead of 'use minigrep::Config'
Neither of the above answers is correct. Using cargo clean is the correct solution. The incremental build process that produces that red underline in the IDE is a result of cached information about the program and library.
$ cargo clean
This seems to be a VSCode issue. Simply restarting VSCode makes the error go away, as discussed on this GitHub issue: https://github.com/rust-lang/vscode-rust/issues/686
I had this issue because I accidentally chose the wrong file name for the lib.rs. Make sure the file is named lib.rs without a typo. Other file names do not work here because of the use statement.
When you write use minigrep::Config, the compiler will look for a lib.rs file in the current project minigrep to resolve the imports.
I just ran across the same problem when reviewing The Rust Programming Language. The way I got it to compile was to remove the line use minigrep; from src/main.rs and add extern crate minigrep to the top of the file. The other file can stay as it is. Not sure if this a typo in the book (if it is then it is in multiple versions) or if there is a change to the behavior of the Rust compiler to accommodate the new syntax and we are just using a version that is too old. For comparison my version is 1.31.0.

Rust is not honoring a custom cfg feature flag for conditional compilation [duplicate]

This question already has an answer here:
Example of how to use Conditional Compilation Macros in Rust
(1 answer)
Closed 4 years ago.
I'm trying to use rust's conditional compilation feature and it is not working at all. I'm attempting to use this to toggle between a default library and a different one, using the cfg to re-export one of two different submodules depending on if the feature flag is set or not. The code:
lib.rs:
pub mod ffi;
#[cfg(ffiv1)]
mod ffiv1;
#[cfg(not(ffiv1))]
mod ffiv2;
#[test]
fn test_ffi_struct() {
let _fs = ffi::FFIStruct{ x: 42};
}
#[cfg(ffiv1)]
#[test]
fn test_v1() {
println!("v1 enabled");
}
ffi.rs:
//re-export as ffi::FFIStruct
#[cfg(ffiv1)]
pub use ffiv1::FFIStruct;
#[cfg(not(ffiv1))]
pub use ffiv2::FFIStruct;
ffiv1.rs:
pub struct FFIStruct {
pub x: i32,
y: IShouldFail
}
ffiv2.rs:
pub struct FFIStruct {
pub x: i64
}
Cargo.toml:
[features]
ffiv1 = []
With the default cargo build/test, this builds and works as expected, everything is ok.
With cargo build --features ffiv1, it behaves as no feature flags were passed at all. Running cargo with --verbose shows --cfg 'feature="ffiv1"' going to rustc.
I would expect the compilation to fail on the undefined symbol IShouldFail in ffiv1.rs. (and the extra test to run if it compiled).
What is wrong here?
The syntax for conditional compilation based on Cargo features is like this:
#[cfg(feature = "...")]
/* ... */
#[cfg(not(feature = "..."))]
/* ... */
In your case that would be #[cfg(feature = "ffiv1")]. The #[cfg(ffiv1)] also means something but is controlled by a different rustc flag than what Cargo uses for optional features.

Cannot implement quickchecks Arbitrary for my own type - "source trait is private"

I am using quickcheck to validate some properties of my code. At one point, I need an ASCII byte, so I tried to write an implementation of Arbitrary like this:
extern crate quickcheck;
use quickcheck::{quickcheck,Arbitrary,Gen};
#[derive(Debug,Copy,Clone)]
struct AsciiChar(u8);
impl Arbitrary for AsciiChar {
fn arbitrary<G>(g: &mut G) -> AsciiChar
where G: Gen
{
let a: u8 = g.gen_range(0, 128);
AsciiChar(a)
}
}
#[test]
fn it_works() {}
This fails with the error:
src/lib.rs:12:21: 12:40 error: source trait is private
src/lib.rs:12 let a: u8 = g.gen_range(0, 128);
^~~~~~~~~~~~~~~~~~~
Some searching led me to various bug reports (1, 2, 3, 4) that all seem to suggest I need to use the supertrait of Gen, which is rand::Rng. I updated my crates and use statements to
extern crate quickcheck;
extern crate rand;
use rand::Rng;
use quickcheck::{quickcheck,Arbitrary,Gen};
But I continue to get the same error.
I've tried with
rustc version 1.1.0-dev (b402c43f0 2015-05-07) (built 2015-05-07)
rustc 1.1.0-dev (3ca008dcf 2015-05-12) (built 2015-05-12)
I'm also using quickcheck v0.2.18
Ah, this was a tricky one. To progress in my testing, I added this hack:
impl Arbitrary for AsciiChar {
fn arbitrary<G>(g: &mut G) -> AsciiChar
where G: Gen
{
let a: u8 = Arbitrary::arbitrary(g);
AsciiChar(a % 128)
}
}
After that compiled, I got this error:
src/lib.rs:419:5: 419:23 error: use of unstable library feature 'rand': use `rand` from crates.io
src/lib.rs:419 extern crate rand;
^~~~~~~~~~~~~~~~~~
src/lib.rs:419:5: 419:23 help: add #![feature(rand)] to the crate attributes to enable
My problem was that I forgot to add rand to my Cargo.toml. I was thinking that I would just magically get the same version pulled in by quickcheck.
The ultimate problem was that I hadn't actually used the correct version of Rng, the one that Gen was a subtrait of. Very confusing!
After adding rand to my Cargo.toml, I am back in business.
That's strange. I can reproduce your initial error, but your suggested fix works for me:
extern crate quickcheck;
extern crate rand;
use quickcheck::{Arbitrary,Gen};
use rand::Rng;
#[derive(Debug,Copy,Clone)]
struct AsciiChar(u8);
impl Arbitrary for AsciiChar {
fn arbitrary<G>(g: &mut G) -> AsciiChar
where G: Gen
{
let a: u8 = g.gen_range(0, 128);
AsciiChar(a)
}
}
#[test]
fn it_works() {}
Running cargo test on both beta5 and the 2015-05-12 nightly works.

Resources