These are chat archives for rust-lang/rust

28th
Jan 2018
Katharina
@spacekookie
Jan 28 2018 02:07
Does anyone know why vscode thinks it should highlight .toml files with the Rust syntax by default? :|
Alexandre Bury
@gyscos
Jan 28 2018 06:30
I think the problem is the rusty-code extension
It registers the toml extension in its package.json
Ritiek Malhotra
@ritiek
Jan 28 2018 08:24
Is there a reason why use is allowed (compiles successfully) in this code?
use {};
fn main {}
Michal 'vorner' Vaner
@vorner
Jan 28 2018 08:27
@ritiek I think this is just a degenerated case. You can do use std::io::{Read, Write};. You probably can also do use {std, log};. So this is just the same thing, but with 0 elements in it.
Ritiek Malhotra
@ritiek
Jan 28 2018 08:31
I see, thanks
Ritiek Malhotra
@ritiek
Jan 28 2018 08:49
But should this really compile successfully? I mean it has 0 elements in it.
Michal 'vorner' Vaner
@vorner
Jan 28 2018 08:50
It's harmless, so why would anyone write a special-case for it? And it probably can happen if you generate some code by a program.
Aleksey Kladov
@matklad
Jan 28 2018 08:53

And there's already a warning for this use-case. Allowing empty imports might be useful if you generate Rust code mechanically.

Also, on nightly one can even use {{{{}}}};=P

Andrey Lesnikov
@ozkriff
Jan 28 2018 08:54
Rust has a lot of degenerated cases in the grammar, but as long as they cause warnings (at least with clippy) - it seems ok to me
Kelly Thomas Kline
@kellytk
Jan 28 2018 10:07
Sergey Noskov
@Albibek
Jan 28 2018 10:20
@kellytk compiler can't determine, what is the value of input when error happens, because your match in main returns 2 different types. Here's how you can fix it https://play.integer32.com/?gist=57d909d9fc9438124247484eb6b88514
Kelly Thomas Kline
@kellytk
Jan 28 2018 11:08
@Albibek Why must Ok() and Err() in main's match branches be called with the value/error?
Sergey Noskov
@Albibek
Jan 28 2018 11:30
@kellytk because they are the same type only in this case. It could be written in another way maybe, but withh the same meaning. I think you need this chapter in the book to understand better: https://doc.rust-lang.org/book/first-edition/error-handling.html#the-result-type
Kelly Thomas Kline
@kellytk
Jan 28 2018 12:04
Thanks @Albibek
Daniel Bischof
@dbischof90
Jan 28 2018 12:38
Good morning people
Can someone think of a nice solution to this snippet here that does not use a clone()?
https://play.rust-lang.org/?gist=5e3f26873f712c8ce29869c59fa0ca74&version=stable
As you can see, it's primarily about dealing with taking and receiving ownership in a borrowed surrounding
Aleksey Kladov
@matklad
Jan 28 2018 12:41
::std::mem::swap(&mut self.a, Vec::new()) might help you
Daniel Bischof
@dbischof90
Jan 28 2018 12:41
I can solve this via clone() but since that would mean some performance overhead I'd like not to introduce it would be nice to know whether there's an way.
Sorry, what? :D
Daniel Bischof
@dbischof90
Jan 28 2018 12:45
Would you mind taking a minute to explain what you did there?
Aleksey Kladov
@matklad
Jan 28 2018 12:45
Sure!
Daniel Bischof
@dbischof90
Jan 28 2018 12:45
I'm ~1-2 months into Rust, haven't encountered that yet.
Aleksey Kladov
@matklad
Jan 28 2018 12:46
The mem::swap and mem::replace are a couple of very useful functions
I suggest familiarizing yourself with https://doc.rust-lang.org/std/mem/
Basically, they allow you to acquire ownership of T if what you have is &T
&mut T
basically, you swap &mut T with some default state, modify the swapped out object as you wish, and than swap it back
Daniel Bischof
@dbischof90
Jan 28 2018 12:47
That is exactly the problem I have, yes. I wasn't aware Rust lets you do that!
Aleksey Kladov
@matklad
Jan 28 2018 12:48
Here's a nice illustration of the trick: http://media2.giphy.com/media/MS0fQBmGGMaRy/giphy.gif :)
Daniel Bischof
@dbischof90
Jan 28 2018 12:48
I've been fighting this situation since roughly two weeks :D In various constellations
HAHA
That is awesome
Aleksey Kladov
@matklad
Jan 28 2018 12:48
Ok, gotta go right now, bye! o/
Daniel Bischof
@dbischof90
Jan 28 2018 12:48
Bye!
Edoardo Luppi
@lppedd
Jan 28 2018 14:01
Hi guys! I posted a question on Stackoverflow about manual memory management using unsafe Rust (https://stackoverflow.com/questions/48485454/rust-manual-memory-management/)
Unfortunately, we ended up writing about C++ standards... :worried:
I know that this in not recommended etc. but is there a documented way of handling (allocating, re-allocating and freeing) raw memory?
Aleksey Kladov
@matklad
Jan 28 2018 14:04

@lppedd yeah, "just allocate a chunk of memory" is not on stable yet.

If you want to learn how real memory allocation works, I suggest reading sources of stdlib. Here's a raw_vec, for example: https://github.com/rust-lang/rust/blob/master/src/liballoc/raw_vec.rs

And it indeed bottoms out at the heap module: https://github.com/rust-lang/rust/blob/master/src/liballoc/heap.rs
Edoardo Luppi
@lppedd
Jan 28 2018 14:08
Thanks, I will give them a look. I had found the https://doc.rust-lang.org/std/heap/struct.Heap.html structure and https://doc.rust-lang.org/std/ptr/ module, but wasn't sure about them
Aleksey Kladov
@matklad
Jan 28 2018 14:09
Yep, heap::Heap is basically malloc/free. The relevant RFC is https://github.com/rust-lang/rfcs/blob/master/text/1974-global-allocators.md
Edoardo Luppi
@lppedd
Jan 28 2018 14:10
Interesting! So the developers of Redox OS (the OS being developed in Rust) basically used unstable features?
Aleksey Kladov
@matklad
Jan 28 2018 14:10
I am not too familiar with Redox, but I bet they indeed have to use nightly.
There's other important stuff missing, like inline assembly
Edoardo Luppi
@lppedd
Jan 28 2018 14:12
I hope I'll never have to use inline assembly hahaha
Anyway thank you very much! At least you did not begin by telling me about Box, Rc ect. or how in C++ you don't use new and delete anymore.
Aleksey Kladov
@matklad
Jan 28 2018 14:16

It's interesting though, that Box is currently implemented using compiler magic: https://github.com/rust-lang/rust/blob/0119b44270243db7479ea946bb0cdd5522c351b6/src/liballoc/boxed.rs#L242

And Rc and friends bottom out at Box themselves.

Edoardo Luppi
@lppedd
Jan 28 2018 14:18
Yeah I read a little bit of their implementation and when I found the box keyword I had to Google it.
I don't even remember it mentioned on the Rust book
Aleksey Kladov
@matklad
Jan 28 2018 14:18
It's unstable and is not supper neccessary at the moment (because there's no placement new)
I guess that box syntax ultimately desugars into call to this function and memcpy: https://github.com/rust-lang/rust/blob/0119b44270243db7479ea946bb0cdd5522c351b6/src/liballoc/boxed.rs#L157
Daniel Bischof
@dbischof90
Jan 28 2018 14:33
In a match, we can match specific patterns and add a default case for everything else.
Is the contrary possible too? Define a match response for all variants BUT one?
On the other side, I could implement the special cases and implement a default.
Daniel Bischof
@dbischof90
Jan 28 2018 14:53
Hm. No wait, an actual question.
Suppose I wanted to implement cmp() and partial_cmp() for a struct which carries an enum. The order will be determined through the enum too.
Does Rust know implicitly that if I compare a and b that I can compare b and a too?
So far I have 4 different variants with potentially different behaviour - meaning that I have to implement up to 16 different match statements
Although if the symmetry was understood I could reach the same information with 10.
That would, if there would be more variants coming for me, decrease the number of redundant code as well.
Aleksey Kladov
@matklad
Jan 28 2018 14:55
@dbischof90 could you gist a code example?
Daniel Bischof
@dbischof90
Jan 28 2018 14:56
I'll give one in a couple of minutes, hang on. afk.
Eh, okay, a little hasty. :D
But it might already show the question that I have
one of the statements of line 16 or 17 could somehow be seen not necessary
I understand that the match does not care about that
Aleksey Kladov
@matklad
Jan 28 2018 15:23
I think that for Eq and Ord it's best to rely on derving. If, for some reason, you can't just derive them for you type, than it's best to implement implement it by delegating to some type which uses deriving.
Daniel Bischof
@dbischof90
Jan 28 2018 15:24
But could there be a nice way to use symmetry here? I know that if a <= b, then automatically b >= a.
Aleksey Kladov
@matklad
Jan 28 2018 15:24
Otherwise, it's very easy to accidentally make a non-transitive implementation and break all sorts of invriants.
Daniel Bischof
@dbischof90
Jan 28 2018 15:24
Yes.
That's what I was trying - comparing my variants would come down to compare specific tuples of their arguments
But just a subset. Some of the arguments can/could be compared, but should not be.
One of them would be an ID of some sort and I don't want my elements to be sorted by their naming, only by a specific subset of their properties
I can imagine a situation where this ordering would not need to be symmetric.
Aleksey Kladov
@matklad
Jan 28 2018 15:28
So, you probably could define a key functions, such that self.cmp(other) is defined as self.key().cmp(other.key())
Also, I think that the implementation in the playground is not transitive :)
Daniel Bischof
@dbischof90
Jan 28 2018 15:29
Good observation :D
Just a quick example thrown together
Would a possibility be to implement the n * (n + 1)/2 different variants of (a, b) that are needed and call something like cmp(b,a).reverse() in the other cases?
Or well, would that be wise at all.
Aleksey Kladov
@matklad
Jan 28 2018 15:33
Hm, I am pretty sure that you actually need only n variants with judicial use of derive :-) Would it be too much trouble to paste a real life example? :)
Daniel Bischof
@dbischof90
Jan 28 2018 15:35
I'm on that still :D
But let me write the clumsy version and I'll come back once that's finished.
Oh wait
I meant to implement PartialOrd, not PartialEq!!
The Eq can be solved in one case for me, it was more about the ordering
Adel Prokurov
@aprokurov
Jan 28 2018 17:10
How i can write with std::fs::File some word to second string?
Denis Lisov
@tanriol
Jan 28 2018 17:34
@aprokurov Do I understand correctly that you want to insert a word in the middle of a file?
Adel Prokurov
@aprokurov
Jan 28 2018 18:43
@tanriol
Yes
Alkis Evlogimenos
@alkis
Jan 28 2018 20:51
how do I make a &'static [T] from a Vec<T>?
Patrick Elsen
@xfbs
Jan 28 2018 20:51
Why do you need to do that?
Alexandre Bury
@gyscos
Jan 28 2018 20:52
Vec::as_ptr to get a *const T, then mem::forget the vec, then unsafe cast to 'static [T]
Alkis Evlogimenos
@alkis
Jan 28 2018 20:52
i want to allocate a vector, put N things in it and let them live forever
Patrick Elsen
@xfbs
Jan 28 2018 20:53
@gyscos's solution sounds a little unsafe but it'd work
Alexandre Bury
@gyscos
Jan 28 2018 20:55
Hmm actually I'm not sure how to go from *const T + size to the &'static [T]
Alkis Evlogimenos
@alkis
Jan 28 2018 20:55
maybe: std::slice::from_raw_parts
Alexandre Bury
@gyscos
Jan 28 2018 20:55
Ah yes
I was reading the doc for the slice primitive, not the module
Alkis Evlogimenos
@alkis
Jan 28 2018 20:56
ok that worked but I was hoping for some easier solution :-p
I tried Vec::as_slice() but that didn't work
Alexandre Bury
@gyscos
Jan 28 2018 20:58
The entire block should be safe (you can't get memory unsafety by using it)
But I don't think the std lib offers suck methods
Alkis Evlogimenos
@alkis
Jan 28 2018 20:58
I am not really scared of unsafe blocks
Alexandre Bury
@gyscos
Jan 28 2018 20:58
As long as you don't consume/forget the vec, you can't get a static lifetime (since it may be dropped at any time)
We could add Vec::leak(self) -> &'static [T] to the std lib
Alkis Evlogimenos
@alkis
Jan 28 2018 20:59
that would be nice
Alexandre Bury
@gyscos
Jan 28 2018 20:59
But I think this may be too tempting for newcomers
It's only useful in some niches (in which it's very useful), but may look like an easy way to silence the borrow checker
Which it shouldn't be
Alkis Evlogimenos
@alkis
Jan 28 2018 21:00
when the name is leak it doesn't look like an easy way
compared to all the other newcomer non-friendly features this would be at the bottom of the list
Alexandre Bury
@gyscos
Jan 28 2018 21:01
Well we can try an RFC :)
Assuming there's not one already
Denis Lisov
@tanriol
Jan 28 2018 21:01
It's already there :-)
Well, almost there - rust-lang/rust#45881
Alkis Evlogimenos
@alkis
Jan 28 2018 21:03
its merged
so I guess a PR for Vec::leak is not out of the question
why is the lifetime specified as 'a instead of just static?
Alexandre Bury
@gyscos
Jan 28 2018 21:04
So it can be anything
Denis Lisov
@tanriol
Jan 28 2018 21:04
my_vec.into_boxed_slice().leak()
Alexandre Bury
@gyscos
Jan 28 2018 21:04
It can be tied to another "fake" lifetime (maybe from a PhantomData) if needed
Alkis Evlogimenos
@alkis
Jan 28 2018 21:05
there is no boxed slice for Vec
I guess you are suggesting that API instead of just leak()?
But I don't find Box::leak in the doc
Alkis Evlogimenos
@alkis
Jan 28 2018 21:08
Box::leak was submitted recently
Denis Lisov
@tanriol
Jan 28 2018 21:08
It's in beta, not in stable yet.
Alkis Evlogimenos
@alkis
Jan 28 2018 21:08
unsafe { &* Box::into_raw(s.into_boxed_slice()) } better than what I had before :-)