Rust syntax: assignment to underscore without let - rust

For a few Rust versions now, one can do _ = foo() instead of let _ = foo() in assignments. However, I can not recall the name of this syntax and can't find official documentation for it. I also don't find the PR in the rustlang repo. Can anyone provide some context, please?

It is part of the destructuring assignment RFC, that allows pattern to be used for assignments and not just variable declaration. Stabilized in Rust 1.59.0.

Related

cfg attribute with arbitrary constant expression

I have the following const:
const IS_WSL: bool = is_wsl!();
and I'd like to be able to use this with the cfg attibute to perform conditional compilation. Something like:
#[cfg(const = "IS_WSL")] // what goes here?
const DOWNLOLADS: &'static str = "/mnt/c/Users/foo/Downloads";
#[cfg(not(const = "IS_WSL"))]
const DOWNLOADS: &'static str = "/home/foo/Downloads";
Obviously this syntax doesn't work, but is there any way to achieve what I'm describing?
I'm aware of custom rustc flags, but would like to avoid doing that, since there's a fair amount of logic that I'd rather not try to write in bash
The answer is not. You have to use something like build script to achieve that.
It cannot work because cfg-expansion occurs at an earlier pass in the compiler than constant evaluation.
cfg expansion works at the same time as macro expansion. Both can affect name resolution (macros can create new names, which other macros, or even the same macro, can later refer to) which forces us to use a fixed-point algorithm (resolve names, expand macros, resolve names, expand macros... until no more names can be resolved, i.e. a fixed point was reached). const evaluation takes a place after type checking, sometimes (with generic_const_exprs) even during codegen. If it could affect macro expansion, we would have a giant fixed-point loop resolve names - expand macros - resolve names - expand macros... until a fixed point is reached, then lower to HIR - type-check - evaluate constants (or even lower to MIR - monomorphize and evaluate constants) - and back to name resolution. Besides slowing the compiler down a lot, it'll also make it significantly more complex, not really something the rustc team wants.
In your specific case, since both cfg variants declare a static with the same name and type you can just match on IS_WSL:
const IS_WSL: bool = is_wsl!();
const DOWNLOADS: &'static str = match IS_WSL {
true => "/mnt/c/Users/foo/Downloads",
false => "/home/foo/Downloads",
};
Playground
This doesn't have the same power as cfg does, but it is still useful if you just need to select two values of the same type.

Where is checksumValid() defined?

I am working from a compliance perspective. I am struggling with the simplest thing, how to find the source for various functions that are called by rustup.
For example, the rustup source code references checksumValid, but I can't find it defined anywhere. I searched stackoverflow, I searched Google, etc.
I'd appreciate help finding checksumValid, but more importantly, what is wrong with my approach?
pub enum Notification<'a> {
...
NoUpdateHash(&'a Path),
ChecksumValid(&'a str),
SignatureValid(&'a str, &'a PgpPublicKey),
...
ChecksumValid(&'a str) here is not actually a function but rather one of many possible values of an enum Notification defined in this line. While the () is usually associated with functions in rust it can denote other things as well. In this case it denotes one possible value of the enum that contains some data that is of type &str with a lifetime of 'a. This is the definition of this value, in this line right here.
You might want to read this to understand the syntax.

In Rust, what kind of syntax is ::<Template>? [duplicate]

I read the below syntax from byteorder:
rdr.read_u16::<BigEndian>()
I can't find any documentation which explains the syntax instance.method::<SomeThing>()
This construct is called turbofish. If you search for this statement, you will discover its definition and its usage.
Although the first edition of The Rust Programming Language is outdated, I feel that this particular section is better than in the second book.
Quoting the second edition:
path::<...>, method::<...>
Specifies parameters to generic type, function, or method in an expression; often referred to as turbofish (e.g., "42".parse::<i32>())
You can use it in any kind of situation where the compiler is not able to deduce the type parameter, e.g.
fn main () {
let a = (0..255).sum();
let b = (0..255).sum::<u32>();
let c: u32 = (0..255).sum();
}
a does not work because it cannot deduce the variable type.
b does work because we specify the type parameter directly with the turbofish syntax.
c does work because we specify the type of c directly.

Converting an array, slice or vector to base58 encoding WITH check

I'm writing a code that converts an array/slice/vector to a B58-encoded string with the check. Here is the relevant code excerpt:
use bs58;
i = b"Hello"; // or
i = [0,1,2,3]; // or
i = vec![0,1,2,3];
let e = bs58::encode(i).with_check().into_string();
No matter what type I supply to bs58::encode(), it errors out saying that method with_check() not found. Coming from Python, it's really frustrating because I have to spend hours debugging simple stuff that should just work.
If you look in the API documentation for bs58::encode, you see that it returns a EncodeBuilder.
Looking at the documentation for that, you see that there is a with_check method but it has a note attached to it:
This is supported on crate feature check only.
Rust supports crates defining optional features - these features typically have extra dependancies that are not needed in all cases, so they are off by default.
You can enable the extra features in your Cargo.toml file, like this:
[dependancies]
bs58 = { version="0.4.0", features=["check"] }
See also the Features section of the Cargo book.

Is it safe to use Proc with the same name as Iterator in Nim?

I would like to define proc with the same name as iterator to be able to write short code table.keys.sorted.
And it seems Nim support that and resolve naming conflict correctly.
Is this an official feature of Nim that's going to be supported in future versions? Is it safe to use such approach?
Example
import tables, algorithm
var table = init_table[string, int]()
table["b"] = 2
table["a"] = 1
# Proc with same name as Iterator
proc keys*[K, V](table: Table[K, V]): seq[K] =
for k in table.keys: result.add k
# Nim properly resolves `keys` as `proc` and not as `iterator`
echo table.keys.sorted
The fact that you can define an iterator and a proc with same signature is currently regarded as design mistake (see issue #8901) but it will probably stick for a while.
Other options for your request of having short code are:
echo toSeq(table.keys).sorted
this uses toSeq from sequtils and unfortunately you cannot use UFCS with that (see github issue).
Another option (actually on top of that) would be to define a template sortedKeys that does the above .
Or you could argue that this is not a design mistake and we could think of it as a feature that allows you to use keys of a table as a sequence. :)

Resources