These are chat archives for rust-lang/rust

3rd
Jul 2018
Sai Zeng
@zengsai
Jul 03 2018 01:40

In futures-channel crate, there is a mpsc queue:

#[derive(Debug)]
struct Node<T> {
    next: AtomicPtr<Node<T>>,
    value: Option<T>,
}

/// The multi-producer single-consumer structure. This is not cloneable, but it
/// may be safely shared so long as it is guaranteed that there is only one
/// popper at a time (many pushers are allowed).
#[derive(Debug)]
pub struct Queue<T> {
    head: AtomicPtr<Node<T>>,
    tail: UnsafeCell<*mut Node<T>>,
}

unsafe impl<T: Send> Send for Queue<T> { }
unsafe impl<T: Send> Sync for Queue<T> { }

Why type of tail in Queue is different from head? Both of them are store the same type of data *mut Node<T>?

I tried to change tail: UnsafeCell<*mut Node<T>> to tail: AtomicPtr<Node<T>>, and other fix, the Queue is working well.

I'd like to known the design philosophy here, can anyone help me out?

file path: futures-channel/src/mpsc/queue.rs
Sai Zeng
@zengsai
Jul 03 2018 01:48
@tsoernes you have a syntax error here, just change pub fn argpmax1<N: Ord, Default>(arr: &Array1<N>) -> (usize, N) { to pub fn argpmax1<N: Ord + Default>(arr: &Array1<N>) -> (usize, N) {
James Sewell
@jamessewell
Jul 03 2018 02:22
error[E0307]: invalid `self` type: &mut StreamFile<[type error]>
  --> src/bin/server.rs:51:22
   |
51 |     fn fill_read_buf(&mut self) -> Result<Async<()>, std::io::Error> {
   |                      ^^^^^^^^^
   |
   = note: type must be `StreamFile<[type error]>` or a type that dereferences to it
   = help: consider changing to `self`, `&self`, `&mut self`, or `self: Box<Self>`
I'm confused about this :O
My Struct is struct StreamFile<A: AsyncRead>
But I don't understand how that translates to using self
Sai Zeng
@zengsai
Jul 03 2018 02:57
can you paste your code ?
@jamessewell
James Sewell
@jamessewell
Jul 03 2018 03:00
I got it working, thanks though!
Eddy S.
@fneddy
Jul 03 2018 08:02
hi, I don't know whom to contact, but the cert of https://docs.rs is expired.
Fredrik Portström
@portstrom
Jul 03 2018 09:34
@turboladen Yes
I wonder how to clone references to elements with wasm-bindgen. There seems to be such a feature.
Ingvar Stepanyan
@RReverser
Jul 03 2018 11:59
@fneddy works for me
Expires on 1 Oct 2018
I guess autorenewal script kicked in by now?
Sylwester Rąpała
@xoac
Jul 03 2018 12:02
I have a struct that is U15 MeasPeriodNum (15bits counter) can I tell rust I want to automatically change it to u16 if necessary?
impl Deref for MeasPeriodNum {
    type Target = u16;
    fn deref(&self) -> &u16 {
        &self.meas_period_num
    }
}
Fredrik Portström
@portstrom
Jul 03 2018 12:04
@xoac You may also want to implement Into. https://doc.rust-lang.org/std/convert/trait.Into.html
Sylwester Rąpała
@xoac
Jul 03 2018 12:04
yes but I need to call into() manually
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:04
And for deref you need to dereference manually
(unless you actually accept a reference to number and not number by value, which is rare)
Fredrik Portström
@portstrom
Jul 03 2018 12:05
If the function you're calling is generic over Into you don't have to call it manually.
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:05
And btw, instead of Into, it's usually better to implement From (it implies Into)
Fredrik Portström
@portstrom
Jul 03 2018 12:06
You can only implement From for your own types, right?
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:06
Nope
Sylwester Rąpała
@xoac
Jul 03 2018 12:06
Both but From autoimplement Into
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:07
@portstrom impl From<MyType> for u16 is also legal
Sylwester Rąpała
@xoac
Jul 03 2018 12:08
@RReverser why is legal?
this exception I guess..
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:08
No, why?
Fredrik Portström
@portstrom
Jul 03 2018 12:09
@RReverser Good to know. Thanks.
Sylwester Rąpała
@xoac
Jul 03 2018 12:11
I thought I can only implement impl From<T> for MyType {} So can I implement impl From<MyType> for SbCrateStruct ?
Dmitriy
@dpogretskiy
Jul 03 2018 12:12
i believe it's any combination of types, if it features your type in it
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:12
Yeah, as long as either generic param or target is your local type, you're fine
Dmitriy
@dpogretskiy
Jul 03 2018 12:13
not sure if it was always like that, hence Into exists for some reason..
Sylwester Rąpała
@xoac
Jul 03 2018 12:13
so can I implement From<MyType> for TcpStream?
Dmitriy
@dpogretskiy
Jul 03 2018 12:14
why not?
Ingvar Stepanyan
@RReverser
Jul 03 2018 12:14
@dpogretskiy Article mentions what is the reason

@xoac You may also want to implement Into. https://doc.rust-lang.org/std/convert/trait.Into.html

There is one exception to implementing Into, and it's kind of esoteric. If the destination type is not part of the current crate, and it uses a generic variable, then you can't implement From directly. For example, take this crate:

so can I implement From<MyType> for TcpStream?

Sure

Dmitriy
@dpogretskiy
Jul 03 2018 12:17
well, yeah at some point nested generics can strike your From's back :)
tsoernes
@tsoernes
Jul 03 2018 13:12
Are there any conventions for mutable reference parameters that are only temporarily modified?
To let the caller know that the mutation is only temporary
Fredrik Portström
@portstrom
Jul 03 2018 13:15
@tsoernes The convention seems to be not to do that.
tsoernes
@tsoernes
Jul 03 2018 13:27
Is it possible to have traits with generic instantiation methods for the structs that implements the traits? I.e. something like:
struct AAVNet {
    alpha: f64,
}

pub trait Agent {
    fn new<A: Agent>(alpha: f64) -> A;
}

impl Agent for AAVNet {
    //  expected struct, variant or union type, found type parameter `AAVNet`
    // (not a struct, variant or union type)
    fn new<AAVNet>(alpha: f64) -> AAVNet {
        AAVNet {
            alpha: alpha,
        }
    }
}
Denis Lisov
@tanriol
Jul 03 2018 13:30
@tsoernes Do you mean something like this?
tsoernes
@tsoernes
Jul 03 2018 13:37
@tanriol Yes very much so, thanks
tsoernes
@tsoernes
Jul 03 2018 15:27
Has anyone created a computational graph with Tensorflow in Rust? I'm quite familiar with the TF bindings for Python; there are some examples for TF-Rust but they all just import a graph defined in Python ..
Hey all, I'm trying to make a rustls connector for rust-postgres. The rustls Stream<'a, S, T> type is constructed with Stream::new(&'a mut S, &'a mut T). Because of the way the rust-postgres tls adaptor works I need to wrap this type in something that owns the Stream, as well as the S and the T that I constructed the Stream with.
I'm having trouble working out how best to implement the constructor of my wrapper type. I can't just construct S and T and pass mutable references to them, because when I return from the constructor, those references are no longer valid
my first attempt was to simply have S and T as fields on my wrapper struct and pass mutable references to Stream::new, but that gives me "borrowed value does not live long enough" saying that it only lives until the end of the constructor
Ingvar Stepanyan
@RReverser
Jul 03 2018 16:36
@jbg So it sounds like you want to pass references to something your struct owns.
This is indeed one of the tricky cases, especially because in Rust Box and Vec can't express that the data they own can outlive the actual container and that refs remain valid even when container is moved, returned etc..
The best solution for your case might be to look at owning_ref crate which allows to workaround exactly that (have valid references to data you own even when your struct is moved around).
Another way would be to do essentially the same but manually, by using raw pointers and casting to references of whatever lifetime you need, but I wouldn't recommend it as it's quite unsafe.
Ingvar Stepanyan
@RReverser
Jul 03 2018 16:43
Also another way could be to separate these structures, so that owner could first construct your wrapper with owned S and T fields, and then call e.g. .create_stream() on the result to actually create the stream
That way you would allow caller to get your structure, store it wherever in any location, and then they can call a method and you will have stable references valid for as long as that target location.
On second thought, this is probably even easier than owning_ref if you're allowed to separate these stages of creating a wrapper and creating an actual stream.
Sylwester Rąpała
@xoac
Jul 03 2018 16:50
Is there a special reason why ? dosen't work on Option<T>
Ingvar Stepanyan
@RReverser
Jul 03 2018 16:51
It does
Sylwester Rąpała
@xoac
Jul 03 2018 16:57
when I go to docs and looking for question mark ? I got https://doc.rust-lang.org/std/macro.try.html
I think there should be mentioned about Option
or a link to ?doc
Ingvar Stepanyan
@RReverser
Jul 03 2018 16:59
try macro is not the same
it's old variant
that was used only explicitly for Result
what you're interested in is ops::Try - https://doc.rust-lang.org/std/ops/trait.Try.html
Sylwester Rąpała
@xoac
Jul 03 2018 17:01
Ow so question mark will be available for everyone
Ingvar Stepanyan
@RReverser
Jul 03 2018 17:01
It is already, yeah
@RReverser I tried to implement it your suggested way (separating the two calls)
it seems to just move the same issue out to the caller
(the caller has to box & return the constructed wrapper to rust-postgres)
David James
@xpe
Jul 03 2018 17:14
Hello, I want to implement iter for a custom struct. I see that one way to do this involves implementing next for the Iterator trait. This makes the struct directly usable as an iterator. Instead, I'm more interested in defining iter that converts it to an iterator. I'm working on getting the return type correct.
@RReverser and using owning_ref doesn't appear to change the problem; I have to take the mutable reference from the owning_ref and pass it to rustls::Stream::new(), and then it doesn't live long enough
David James
@xpe
Jul 03 2018 17:24
This very simple example is compiling for me -- not sure why this approach isn't easier to find online:
pub struct Foo(Vec<f64>);
impl Foo {
    pub fn iter(&self) -> Iter<f64> { self.0.iter() }
}
tsoernes
@tsoernes
Jul 03 2018 17:41
Can anyone give me an example of how to type cast ndarrays? I tried this to no avail:
    fn forward(&mut self, freps: Array<usize, Ix3>) -> Array1<f32> {
        let n_freps = freps.len_of(Axis(0));
        // no method named `from` found for type `ndarray::ArrayBase<ndarray::OwnedRepr<usize>, ndarray::Dim<[usize; 2]>>` in the current scope (rust-cargo)
        let net_inp: Array2<f32> = freps
            .into_shape((n_freps, WDIM))
            .expect("Frep reshape")
            .from();
}
Array2 only defines from() for Vec
this doesn't really seem like a type-cast
into_shape already appears to return an array with the appropriate shape type param
note that Array2<A> is just a type alias for Array<A, Ix2>
so Array2<f32> == Array<f32, Ix2>
which would be what into_shape() would return except that f32 != usize
so you're going to need to map the actual elements here
.map(|u| u as f32) ought to work
Ingvar Stepanyan
@RReverser
Jul 03 2018 19:28

it seems to just move the same issue out to the caller

@jbg Well, kinda, but it's up to caller now whether it's just a local var or it wants to box it etc.

But at least you're giving ability to create streams without boxing, which is not possible otherwise
As now your create_stream method can accept &self and in turn retrieve &S and &T no matter where self lives

@RReverser and using owning_ref doesn't appear to change the problem; I have to take the mutable reference from the owning_ref and pass it to rustls::Stream::new(), and then it doesn't live long enough

With owning_ref the idea is that you can store the reference and the object you're referencing together in OwningRef, and move them around together (although that requires boxing the left side).

tsoernes
@tsoernes
Jul 03 2018 21:48
@jbg I know about the map, that's got to be very slow though, no?
Colt Frederickson
@coltfred
Jul 03 2018 21:56
What's the best way to require that some generic type T has a trait implemented for both T and &T. For example say I wanted to write some trait implementation that needed Add<Output=T> and Add<Output=&T>, how would I say that syntactically
zsugabubus
@zsugabubus
Jul 03 2018 22:12
I guess you will need to Borrow.