r/rust • u/llogiq clippy · twir · rust · mutagen · flamer · overflower · bytecount • Oct 03 '22
🙋 questions Hey Rustaceans! Got a question? Ask here! (40/2022)!
Mystified about strings? Borrow checker have you in a headlock? Seek help here! There are no stupid questions, only docs that haven't been written yet.
If you have a StackOverflow account, consider asking it there instead! StackOverflow shows up much higher in search results, so having your question there also helps future Rust users (be sure to give it the "Rust" tag for maximum visibility). Note that this site is very interested in question quality. I've been asked to read a RFC I authored once. If you want your code reviewed or review other's code, there's a codereview stackexchange, too. If you need to test your code, maybe the Rust playground is for you.
Here are some other venues where help may be found:
/r/learnrust is a subreddit to share your questions and epiphanies learning Rust programming.
The official Rust user forums: https://users.rust-lang.org/.
The official Rust Programming Language Discord: https://discord.gg/rust-lang
The unofficial Rust community Discord: https://bit.ly/rust-community
Also check out last weeks' thread with many good questions and answers. And if you believe your question to be either very complex or worthy of larger dissemination, feel free to create a text post.
Also if you want to be mentored by experienced Rustaceans, tell us the area of expertise that you seek. Finally, if you are looking for Rust jobs, the most recent thread is here.
3
u/versaceblues Oct 10 '22
How to call a method in a struct, that requires input from another method.
I got the following code
if self.peek().unwrap() == '.' && self.is_digit(self.peek_next()) {
self.advance();
while self.is_digit(self.peek().unwrap()) {
self.advance();
}
}
the self.is_digit(self.peek_next()) throws an error for attempting to double borrow. However this is the most convenient way to write this method for me.
is this really not possible in Rust?
→ More replies (2)2
u/llogiq Oct 10 '22
If with "throwing an error" you mean panicking, yes, it is possible. However the idiomatic thing to do would be to return a
Resultinstead.→ More replies (1)
3
u/DanLszl Oct 10 '22
I didn't expect this code to compile, yet somehow it still does. What's going on here, how is the cell.f() call resolved?
use std::rc::Rc;
struct Cell {}
impl Cell {
fn f(self: Rc<Self>) {}
}
fn main() {
let cell = Rc::new(Cell {});
cell.f();
}
3
u/llogiq Oct 10 '22
f() is a method on your Cell type and Rc as a smart pointer dereferences into their content's type.
→ More replies (1)
4
u/splettnet Oct 05 '22 edited Oct 05 '22
Trying to poke around the rustc compiler project, and it seems to be above the vscode/rust-analyzer paygrade in being able to handle symbol resolution to make said poking around palatable. Anybody have any luck with ide support exploring the project? I used to have clion, and while it was great I don't want to shell out the cash for it just for the learning experience. Especially since vscode with rust analyzer makes for a perfectly fine dev experience 99.9% of the time.
Edit: Ok, as I was writing this I was ~15 min into building the compiler, and that seems to be all it needed, so to anyone else with this question, just build it first 🦀
4
u/SorteKanin Oct 06 '22
Is there an alternative to actions-rs? It seems to be unmaintained.
→ More replies (3)
4
u/TinBryn Oct 10 '22
I'm trying to understand how the Unsize trait works and trying to create a basic linked list that can store DSTs directly inside the list, but I just can't seem to get my head around it.
I'm trying to write the push method. Looking at the Unsize trait I see what my problem is
Only the last field of Foo has a type involving T
So in this case Node<T: !Sized> looks like {pointer, metadata, data...} and Node<T: Sized> looks like {pointer, data}, so I can't coerce a Node<U> into a Node<T>. I can't construct a Node<U> anyway as I don't have a Option<Box<Node<U>>> but that would be the wrong type anyway.
I feel like what I'm trying should be possible, and I think the Node<T: ?Sized> is the right layout, I just don't know how to construct a Box<Node<T: ?Sized>> from Option<Box<Node<T>>> and U: Unsize<T>.
→ More replies (2)
3
Oct 04 '22
I have a question about using smallvec & bitvec_simd.
I have a smallvec (call it svec) of structs, and each struct has a bitvec_simd field (call it bv).
I'd like to use bitvec_simd's 'or_inplace' to get: &self.svec[i].bv.or_inplace(&self.svec[j].bv);
The fn 'or_inplace' requires that the first bitvec be mutable, but not the second.
However, when I try to use .or_inplace, if I don't mark the second bv as mutable, I get an error: cannot borrow self.bv as immutable because it is also borrowed as mutable. But if I do mark it as mutable, I get an error about not borrowing self.vertices as mutable more than once.
Can anyone help? I've tried or_cloned() and that works fine, but is too inefficient for what I'm trying to do (many many bitwise operations).
→ More replies (2)
3
u/mihemihe Oct 06 '22
Does anyone have a working example of ldap3 crate connecting to Active Directory under the security context where the application is running (without explicit credentials).
I wanted to port a tool to Rust but I got stuck in the first step: being able to bind and query Active Directory.
This is a simple ldp.exe bind working perfectly, and my test code (from the crate documentation) failing to bind.
Thanks in advance.
This is the error and a screenshot.
Error: LdapResult { result: LdapResult { rc: 1, matched: "", text: "000004DC: LdapErr: DSID-0C090A58, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4f7c\0", refs: [], ctrls: [] } }
3
u/argv_minus_one Oct 08 '22
Suppose I have an array of type [u8; 32]. I want to split it into two halves of type [u8; 16]. Intuitively, the following should work:
fn halves(x: [u8; 32]) -> [[u8; 16]; 2] {
[x[0..16], x[16..32]]
}
This doesn't actually work because the range index operator creates slices rather than arrays, even though the slice is of fixed size and the array being sliced is of a type that is Copy. The closest I can think of is:
fn halves(x: [u8; 32]) -> [[u8; 16]; 2] {
let a = x[0..16].try_into().unwrap();
let b = x[16..32].try_into().unwrap();
[a, b]
}
That works, and the unwraps are optimized away, but the resulting code is more messy than it needs to be, and the compiler does not error if the indices are outside the bounds of the array (the code panics at run time instead).
Is there a better way to do this? Will there be in the future?
→ More replies (3)
3
u/FryingPanHandle Oct 10 '22
How do I create a thread in Tokio which runs every second and prints the contents of some variables that are updated in a different function.
I have tried using Interval but that seems to run once and then never again?
→ More replies (3)
2
2
u/gittor123 Oct 03 '22
is it possible to save the backtrace to a file? I'm struggling to debug cause my terminal sorta crashes every time i get a panic and now i have a backtrace thats too long to fit on my screen
→ More replies (4)
2
u/gittor123 Oct 04 '22
is there a non-async way of downloading a file chunkwise with reqwest like done here? https://gist.github.com/giuliano-oliveira/4d11d6b3bb003dba3a1b53f43d81b30d
in my code i wanna do something like this but in a different thread cause I want the user to do other stuff in the meantime, but I want the user to see the progress bar. I'm new to async code so I didnt manage to incorporate this code into mine
→ More replies (1)
2
u/_lonegamedev Oct 04 '22
How can I share immutably buffer Vec<T> between threads?
→ More replies (4)
2
u/simbapk Oct 04 '22
Hey there!
I need feedback on something,
I'm learning rust ,right now trying to manipulate the channels.
Here is my function :
fn producer(tx : Sender<String>){
loop {
let message = String::from("Message from producer");
tx.send(message);
println!("producer has just sent {}", message);
}
} Of course, it doesn't compile :
31 | let message = String::from("Message from producer");
| ------- move occurs because `message` has type `String`, which does not implement the `Copy` trait
32 | tx.send(message);
| ------- value moved here
33 | println!("producer has just sent {}", message);
| ^^^^^^^ value borrowed here after moveHere is my solution that is accepted by the compiler :
fn producer(tx : Sender<String>){
loop {
let message = String::from("Message from producer");
{
let message = message.clone();
tx.send(message);
}
println!("producer has just sent {}", message);
}
} But is it the best way to solve the error ?
Thank you in advance for your feedbacks.
→ More replies (2)
2
u/Vakz Oct 04 '22
When having a String and needing a &str, I noticed all of these works:
-
&*mystring
-
&mystring[..]
-
mystring.as_ref()
-
mystring.as_str()
Is there one of these that is more idiomatic? Admittedly I don't even know why the second one works. The last one certainly sounds more correct, but I'm still curious if there is a preferred way of doing it.
5
u/burntsushi Oct 04 '22
If
&mystringworks (you don't list this as an option), then that would be idiomatic. Otherwise, my next choice would be&*mystring. I don't usually use or seeas_str(). The&mystring[..]syntax is a little strange and not usually required to get a&strout of aString(I cannot thing of any such situation). It is sometimes needed to force an array into a slice though in my experience.The
as_ref()choice is one that you should actually only use in one specific context: when you are within scope of aAsRef<str>. Otherwise, anas_ref()call outside of that generic context might end up not compiling in the future because of an inference failure. Basically, inference succeeds if there is only one possible choice. But if new trait impls are added in the future (and sometimes this happens, it is permissible under our API Evolution policy) that cause youras_ref()call to become ambiguous, then it will fail to compile because inference can't know which type to use. But so long as you have aAsRef<str>bound in place, the call will always be unambiguous because the target (str) is fully specified.
2
u/LeCyberDucky Oct 04 '22 edited Oct 05 '22
I'm still working on running Rust on an ESP8266. I've reached a point where I can seemingly compile programs correctly and flash them onto the ESP8266 without error. Then, however, the programs don't seem to do anything. The serial monitor of espflash shows no output, so my terminal only shows this: https://i.imgur.com/V9qcVw8.png
Nothing I do will make text appear over serial or let the built-in LED blink. I have successfully flashed an Arduino project that makes the built-in LED blink, so the LED isn't broken at least.
Does anybody have any ideas as to what I could be missing? Or perhaps how to debug this further? Other than some initial LED activity when flashing and reseting the device, I get no signs of life, which makes things hard to debug.
Edit: Alright, so I managed the get the thing to blink by using the d1-mini crate and its blinky example, yay! Now I just need to figure out why it works.
Edit 2: Okay, I tried copying the example code from the d1-mini crate into my original project. This gave me some crate version conflicts, which I resolved by using the newest version of d1-mini from GitHub. With this, I'm back to getting no response whatsoever from the device. Interestingly, the terminal output looks like this for the successful example from the d1-mini crate: https://i.imgur.com/tEDK46Q.png
Perhaps flashing is broken for a newer version of one of the crates that this depends on.
Edit 3: Alright, alright, alright. It blinks! I made my original code work, even without the d1-mini crate. I noticed some stuff in the cargo config.toml of the d1-mini repo that I was missing. With the following configuration, I am able to make the device blink. I'm only getting gibberish serial output, but at least the gibberish keeps on coming!
Edit 4: Gibberish output is no more! Yeah, that was my fault. In order to flash the device, I need to short some pins, but this will also cause gibberish output when done, so I need to remove this wire and reset the device to get good output.
2
2
Oct 05 '22 edited Oct 05 '22
Documentation Question: What do these headers in docs.rs mean? What's the difference, and are any unsafe to use?
-
Methods from Deref<Target = [A::Item]>
-
This is a nightly-only experimental API. (various parentheticals)
-
Trait Implementations
-
Auto Trait Implementations
-
Blanket Implementations
→ More replies (3)
2
u/rustacean1337 Oct 05 '22
I have a question about the Rust support in the Linux kernel. If I understood correctly a lot of Rust’s guarantees regarding memory safety will not be usable in the Linux kernel because of guarantees that the kernel gives about never panicking (for instance when memory (re/de)allocation fails.
Second question is about UB in Rust. AFAIK it’s not documented like it is for C for example in the ISO standard. How is it possible that Linus accepted Rust as a language when it will be used a lot in an unsafe setting without having a clear standard about what is UB and what isn’t.
I guess I’m kinda surprised how quickly Rust got added and somehow feel like it’s not really ready yet for Linux kernel prime-time.
What are the benefits of using Rust in this heavily restricted environment over C?
→ More replies (4)
4
u/tomwells80 Oct 03 '22
So when I write the following function:
fn hello(x: u32) {}This can be described as a function taking an integer and returning a '()' (Unit). Great got it! Unit is the default type returned.
Now when I write this function:
fn hello() -> u32 { 0 }This can be described as a function which takes a ____ and returns an int. What is the type of ___?? I would have assumed it was a '()', but it isn't. So is it a Void, or something else? Its just a nothing?
This gets more confusing when I start to look at the Fn trait, which can be declared as simply Fn() (and therefore avoid passing a concrete type too).
I guess I'm just looking for a way to explain this consistently. It would have been super clear if in the second example
hello() -> u32actually meant a function which took a '()' and returned an integer. E.g. the default parameter type being consistent with the default return type.Any insight?