These are chat archives for rust-lang/rust

29th
Oct 2017
Paul Masurel
@fulmicoton
Oct 29 2017 00:54
Does somebody know why ? is semantically slightly different from try!
(the latter tends to work better with type inference)
For instance, this compiles with try! but not with ?
https://play.rust-lang.org/?gist=3f20c5ff147a69eb039789dc7989239a&version=stable
Jonas Platte
@jplatte
Oct 29 2017 01:00
@fulmicoton Looks like try! is specific to Result while ? isn't (anymore)
Paul Masurel
@fulmicoton
Oct 29 2017 01:11
Oh... I forgot about the Try trait.
the implementation is very different
Paul Masurel
@fulmicoton
Oct 29 2017 01:16
also if there are compiler people in this chat : I added a minimal reproducible snippet for #44899 . It's fairly interesting.
In a nutshell LLVM hits an assert when trying to compile some code in release mode.
The good news is that it can only happen if the code is bad in the first place.
The sample does not use unsafe code, but it has a branch that can never be taken.
Nikita
@nikita-y
Oct 29 2017 04:33
I have a dumb question: What is an alternative in rust for for (int i=0; i<100; i+=2)expression in c++
Chaitanya Munukutla
@munukutla
Oct 29 2017 04:35
for i in 0...100 {
   // you might have to increment c = c+2 at the end of the loop
}
I have a weird question.
pub fn handle_listener(listener: &TcpListener, map: &mut HashMap<String, String>) {
        loop {
            match listener.accept() {
                Ok((stream, _)) => {
                    thread::spawn(move || {
                        TcpConnection::handle_client(stream, map);
                    });
                },
                Err(error) => {
                    println!("Error: {:?}", error);
                }
            }
        }
    }
It throws the type [stream:std::net::TcpStream, map:&mut std::collections::HashMap<std::string::String, std::string::String>] does not fulfill the required lifetime
@nikita-y , any clue of it?
Nikita
@nikita-y
Oct 29 2017 05:00
@munukutla I did’t get you
Chaitanya Munukutla
@munukutla
Oct 29 2017 05:01
Any clue how to solve the lifetime problem?
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 07:31

Hi folks, I have a lifetime problem with BinaryHeaps:

// job_list is BinaryHeap<Job>
// Job is a simple struct with a few fields including a trigger_at time
// I want to check if the top-most job is ready to be processed, and if it is, then pop it from the heap

while let Some(peeked) = self.job_list.peek() {
            if peeked.trigger_at <= SystemTime::now() {
                let ready_job_opt = self.job_list.pop();
                match ready_job_opt {
                    None => break,
                    Some(j) => println!("Ready to use: {:?}", j),
                }
            }
        }

However, since peek borrows the heap immutably, I can’t mutate the heap using pop while the peeked reference is alive:

55 |         while let Some(peeked) = self.job_list.peek() {
   |                                  ------------- immutable borrow occurs here
56 |             if peeked.trigger_at <= SystemTime::now() {
57 |                 let ready_job_opt = self.job_list.pop();
   |                                     ^^^^^^^^^^^^^ mutable borrow occurs here
...
63 |         }
   |         - immutable borrow ends here

what’s a good way around this?

Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 07:46
hmm, looking
TatriX
@TatriX
Oct 29 2017 07:46
Oh, I see
I'm taking a peeked as a reference
That's why my example works
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 07:46
yeah
actually, I think it works with non struct values
TatriX
@TatriX
Oct 29 2017 07:50
I'm getting your error if I take peeked by reference and then using &5 in the condition. You could try taking a reference of your job struct.
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 07:53
still getting the same thing:
55 |         while let Some(ref peeked) = self.job_list.peek() {
   |                                      ------------- immutable borrow occurs here
...
58 |                 let ready_job_opt = self.job_list.pop();
   |                                     ^^^^^^^^^^^^^ mutable borrow occurs here
...
64 |         }
   |         - immutable borrow ends here
TatriX
@TatriX
Oct 29 2017 07:57
try Some(&peeked)
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 07:58
55 |         while let Some(&peeked) = self.job_list.peek() {
   |                        ^------
   |                        ||
   |                        |hint: to prevent move, use `ref peeked` or `ref mut peeked`
   |                        cannot move out of borrowed content
Michal 'vorner' Vaner
@vorner
Oct 29 2017 08:02
while let Some(time) = self.job_list.peek().map(|j| j.trigger_at) {
  if time <= …
}
that uses the fact the SystemTime is copy, so it won't keep it borrowed.
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:03
ah yes, that makes sense
I didn’t want to copy the entire job
awesome, I finally got it to compile
Thanks a lot @TatriX & @vorner ! :)
learnt a new trick
Paul Masurel
@fulmicoton
Oct 29 2017 08:05
@nikita-y there is a step-by API in nightly too.
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:08
got it - eventually my job object is supposed to contain some large binary data so I didn’t want to clone the whole thing
seems like there is no other way around it
Paul Masurel
@fulmicoton
Oct 29 2017 08:09
@urjitbhatia you can use the peek_mut API and pop the PeekMut object
That's a tiny bit confusing because pop is not a method but a function that takes your peekmut as first arg
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:12
hmm
interesting
Paul Masurel
@fulmicoton
Oct 29 2017 08:13
This is especially powerful if you want to "replace" the head.
like if you want to take the top k element of an iterator
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:14
I see
Paul Masurel
@fulmicoton
Oct 29 2017 08:15
@urjitbhatia your code also becomes simpler
because you don't have to check the is_some twice
TatriX
@TatriX
Oct 29 2017 08:16
Cool trick
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:17
nice, yeah that works really well. I didn’t read a lot of the PeekMut API
this is certainly very helpful
Paul Masurel
@fulmicoton
Oct 29 2017 08:18
here, it just looks cleaner, but for .replace() it is really important, because it is typically more than twice as fast as popping and pushing.
that's usually a detail textbook forget :)
Urjit Singh Bhatia
@urjitbhatia
Oct 29 2017 08:19
right!
I have to say, Rust community is amazing! :)
Jonas Platte
@jplatte
Oct 29 2017 10:52
@nikita-y Regarding your question about loops: There are three options I know:
Solution 1 (requires nightly): https://play.rust-lang.org/?gist=f0b8a9f6088f52db5bd3b4761c112c4d&version=nightly
Solution 2 (depends on itertools): https://play.rust-lang.org/?gist=090735ae601e36258227d8c97d5df03c&version=stable
Solution 3 (no special deps, but possibly not what you want): https://play.rust-lang.org/?gist=703c86f180fbe548c5ab4cb8dc953af7&version=stable
Jonas Platte
@jplatte
Oct 29 2017 11:00
@munukutla Does TcpConnection::handle_client take a mutable or non-mutable reference to your map? Also could you please post a playground link that reproduces the error instead of just a snippet; or at least the full error message?
Dumindu Madunuwan
@dumindu
Oct 29 2017 13:14
Hi,
I am new to Rust, I could understand some main usages of use but still couldn't understand why we need pub use. can anybody suggest me any resource to identify why we need pub use exactly?
Jonas Platte
@jplatte
Oct 29 2017 13:17
@dumindu pub use is a re-export. If you have a library foo with a module bar.rs that defines a type Baz, but you don't want to expose that module directly, and instead just provide Baz as an export from the root of your library, you put a pub use bar::Baz; in your lib.rs.
Dumindu Madunuwan
@dumindu
Oct 29 2017 13:22
but same thing can be done via use foo::bar::Baz , right? why we need to use pub use on this?
Jonas Platte
@jplatte
Oct 29 2017 13:23
use just makes the symbol available in the current module, pub use also exports it.
Dumindu Madunuwan
@dumindu
Oct 29 2017 13:26
can you tell me what is the difference of them?
Jonas Platte
@jplatte
Oct 29 2017 13:30
I just did. It's the same as the difference between mod and pub mod...
Dumindu Madunuwan
@dumindu
Oct 29 2017 13:41
okay, It's bit clear about the usage of pub mod, I'll try to test pub use via some codes. Thanks for spending your time in here at weekends :)
Jonas Platte
@jplatte
Oct 29 2017 13:47
You're welcome :)
Dumindu Madunuwan
@dumindu
Oct 29 2017 16:17
└── src
   ├── greetings.rs
   └── main.rs
// -- greetings.rs --
pub fn hello() {
    println!("Hello, world!");
}

// -- main.rs --
mod greetings;

fn main() {
    greetings::hello();
}
on main.rs, can we use pub use self::greetings; like statement instead of mod greetings; ?
I tried but I couldn't. Can we use pub use self:: instead mod?
Jonas Platte
@jplatte
Oct 29 2017 16:18
@dumindu No. mod and use are different. use brings things into scope that the compiler already knows about and mod declares that there is a module, so the compiler then looks for it.
Dumindu Madunuwan
@dumindu
Oct 29 2017 16:20
found some code on https://aturon.github.io/blog/2017/07/26/revisiting-rusts-modules/ but I didn't read its content properly, might be a proposal :)
Jonas Platte
@jplatte
Oct 29 2017 16:20
pub is never useful in a main.rs, only in submodules or library roots (lib.rs)
Yes, that is a proposal, not the current behaviour
Dumindu Madunuwan
@dumindu
Oct 29 2017 16:21
:+1:
Jonas Platte
@jplatte
Oct 29 2017 16:33
@dumindu Here is an example:
└── src
   ├── foo
   │   ├── bar.rs
   │   └── mod.rs  
   └── main.rs
// foo/bar.rs
pub fn baz() { unimplemented!() }

// foo/mod.rs
mod bar;

pub use bar::baz;

// main.rs
mod foo;

fn main() {
    // Doesn't work, because foo::bar is private
    foo::bar::baz();

    // This works, because baz is reexported in foo/mod.rs
    foo::baz();
}
Dumindu Madunuwan
@dumindu
Oct 29 2017 17:09
@jplatte
I use simple hello world for baz but
 foo::baz();
  |       ^^^ not found in `foo`

but why we need to use

// foo/mod.rs
mod bar;
pub use bar::baz;

we can use

// foo/mod.rs
pub mod bar;

// main.rs
mod foo;

fn main () {
    foo::bar::buz()
}

right?

Jonas Platte
@jplatte
Oct 29 2017 17:17
About the error: Needs to be pub use self::bar::baz;, I forgot
And yes, you can do it like that
But when creating libraries, you don't always want to expose your interal module structure to the user
Dumindu Madunuwan
@dumindu
Oct 29 2017 17:22
got it. Thanks :)