These are chat archives for rust-lang/rust

4th
Jul 2018
Ingvar Stepanyan
@RReverser
Jul 04 2018 00:00
@coltfred Generally you can list any conditions in where, although your particular conditions sound strange - I'm not sure there is any type for which Add can output &T
Colt Frederickson
@coltfred
Jul 04 2018 02:14
@RReverser The kind of thing I want is to ask for an implementation of Add where I can add 2 refs together to get another concrete. I guess I don't really need the 2 value version. It seems like this kind of pattern works, but it seems overly complicated:
struct Point<T> {
    x: T,
    y: T
}

impl<T> Add for Point<T> where T: Eq, for<'a> &'a T: Add<Output=T>{
  type Output = Point<T>;
  fn add(self, other: Point<T>) -> Point<T> {
    Point {x: &self.x + &other.x, y: &self.y + &other.y}
  }
}
Obviously in this case I didn't need Eq, but that's just to show a type constraint on T and one on &T
Is this a common pattern when reusing values in a computation (to avoid clones)? Is there a better way to avoid cloning when reusing values? Fairly new to rust here so any pointers or links to common best practices surrounding this would be super helpful.
Colt Frederickson
@coltfred
Jul 04 2018 02:21
Maybe using Macros is actually the more "rust" way to do this kind of general thing? In other languages with typeclasses this is what I would do, but they are all garbage collected so dealing with barrowing, etc isn't an issue.
Judson Lester
@nyarly
Jul 04 2018 05:04
Any advice about resolving type annotations required: cannot resolve '_: std::marker::Send'?
@nyarly you're using a type somewhere that has a type parameter that must be Send, but you're not providing an actual type for that parameter. with some more info (e.g. the relevant code) it would be easier to give advice.
VJ
@00imvj00
Jul 04 2018 11:37
hello, i need some clarification on `static life times.
is anybody online ?
Francis Lalonde
@fralalonde
Jul 04 2018 11:37
(2571 people are online)
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:38
@00imvj00 Of course someone is online. Just ask. Nobody is going to answer in 5 seconds and nobody is going to answer if you don't ask ;-)
VJ
@00imvj00
Jul 04 2018 11:39

So, i have been going through the source code of some of the libs, i have seen that people using `static lifetimes a lot when doing trait bounds.

Now, when you create `static reference how it will work ? what is that mean, ? i mean according to doc, it will never go out of memory.

Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:40
Now, that's not exact.
VJ
@00imvj00
Jul 04 2018 11:40
For EX, when you want to spawn any future in tokio runtime, it will ask for perticular future to implement `static. now what is that mean ?
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:41
Lifetime is a property of a type. So a &'static usize is a somewhat different different type than &'a usize.
VJ
@00imvj00
Jul 04 2018 11:41
what if my future finishes, will it clear memory ?
Zakarum
@omni-viral
Jul 04 2018 11:41
@00imvj00 T: 'static doens't mean that instances of T will live forever. It means that T can live forever
Dmitriy
@dpogretskiy
Jul 04 2018 11:41
everything will clear the memory no matter what, at some point at least
VJ
@00imvj00
Jul 04 2018 11:42
There is no much doc regarding this. there is only some doc regarding static types, not lifetimes.
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:42
And you can ask a type to be 'static. That basically mean „I can hold onto that value as long as I want. It could be forever. Or just a bit.“. But if it is not 'static, there's some limit on how long I can hold to it.
Zakarum
@omni-viral
Jul 04 2018 11:42
&'static T on the other hand means exactly that. Referenced T lives forever
Dmitriy
@dpogretskiy
Jul 04 2018 11:43
you can't leak statics all that easy
other then Box::leak
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:43
@omni-viral Yes. But the type &'static T means I can hold to this reference as long as I want. For that to be true, T itself must live forever, but that's just a byproduct.
Zakarum
@omni-viral
Jul 04 2018 11:44
@vorner Yes. Reference itself can live forever but not obligated :smile:
Francis Lalonde
@fralalonde
Jul 04 2018 11:44
'static means that the struct does not contain &reference anywhere within it. It is totally owned and can thus "live" forever.
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:44
So if some function takes a T: 'static, it basically means it wants „owned“ types, now „views“ or „borrows“, so it can do whatever it likes with that.
Zakarum
@omni-viral
Jul 04 2018 11:45
And with futures it is required since sending !'static types between threads without breaking stuff aren't simple task
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:45
In other words, the function can safely stuff that thing into a global variable and return to it any future time (which is basically what tokio does)
VJ
@00imvj00
Jul 04 2018 11:47
OK. so it is that static variable or static reference CAN live forever but doesn't need to live forever, as soon as it goes out of scope, it will clear out ?
Francis Lalonde
@fralalonde
Jul 04 2018 11:47
exactly
Dmitriy
@dpogretskiy
Jul 04 2018 11:47
wait a second, are you sure?
Zakarum
@omni-viral
Jul 04 2018 11:48
Yes. Except value referenced by &'static must live forever in order to create such reference
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:48
Lifetime of a type is basically an expiration date. 'static means „will not rot on its own“, where „rot“ means some part of the data it uses goes out from under it.
VJ
@00imvj00
Jul 04 2018 11:48
How would system will know that static variable is out of scope ?
Zakarum
@omni-viral
Jul 04 2018 11:49
@00imvj00 { let x = u32; }
At the closing } x is out-of-scope
VJ
@00imvj00
Jul 04 2018 11:49
and how it would clear it ?
Zakarum
@omni-viral
Jul 04 2018 11:49
u32 is 'static
It will insert Drop::drop invocation if type implements Drop
VJ
@00imvj00
Jul 04 2018 11:50

ohk.

so,

{
   let x = u32;
   fun(&'static x);
}

fn fun(x: &'static u32);

How in here it will go out of scope ?

Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:51
This won't work
u32 is static
but that &u32 is not
And you can't change it that way. It doesn't work this way.
VJ
@00imvj00
Jul 04 2018 11:51
@vorner code updated. plz check, will that work.
Zakarum
@omni-viral
Jul 04 2018 11:52
Since x doesn't actually live forever &x is not 'static
Even if you try to declare it as such. It wont pass borrow-check
VJ
@00imvj00
Jul 04 2018 11:52
ok.
Do Duy
@juchiast
Jul 04 2018 11:52
Sometime it won't get clean, for example &'static str. String constants live on data segment, it is cleared when the program exit.
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:52
You can't dictate lifetime. Lifetime is, and the lifetime annotations just describe it.
Dmitriy
@dpogretskiy
Jul 04 2018 11:52
i'm confused, so every owned value is 'static?
why is that even a thing?
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:52
@dpogretskiy yes
Zakarum
@omni-viral
Jul 04 2018 11:52
@dpogretskiy In a sence of T: 'static
Dmitriy
@dpogretskiy
Jul 04 2018 11:53
i mean, it's always true
Zakarum
@omni-viral
Jul 04 2018 11:53
Every owned type will satisfy this clause
Dmitriy
@dpogretskiy
Jul 04 2018 11:53
or, not?
Zakarum
@omni-viral
Jul 04 2018 11:53
&'a x wont
fn foo<T: 'static>(T) {}

let x; foo(&x)
Dmitriy
@dpogretskiy
Jul 04 2018 11:53
&'a x is not owned by any means :)
Zakarum
@omni-viral
Jul 04 2018 11:53
This wont compile

why is that even a thing?

To allow checking for 'staticness in where clauses

VJ
@00imvj00
Jul 04 2018 11:54
So, for ex, if i take static reference of some type as arg in some function, so that reference will get destroyed when that funtion returns right ?
Zakarum
@omni-viral
Jul 04 2018 11:55
The reference will be destroyed
Unless you move it
Dmitriy
@dpogretskiy
Jul 04 2018 11:56
oh how interesting

fn with_st<T: 'static>(_t: T) {}

fn without_st<T>(_t: T) {}

fn main() {

    let x = 15u32;
    let y = 15u32;

    with_st(x);
    without_st(x);

    // with_st(&y);
    without_st(&y);

}
so this example compiles
Zakarum
@omni-viral
Jul 04 2018 11:56
Yeap
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:57
I think you are still confused somewhere. &'static u32 is a type for talking about u32s that don't go away. That doesn't say if that reference does or does not go away.
Dmitriy
@dpogretskiy
Jul 04 2018 11:57
now i got it
VJ
@00imvj00
Jul 04 2018 11:57
i am still little bit confused. @vorner can you give another example if that is ok ? may be with struct or enum ?
Dmitriy
@dpogretskiy
Jul 04 2018 11:58
i got confused cause assuming that &'a y is valid type T for without_st doesn't make a lot of sense on it's own
but if there are some Deref's attached it could
Michal 'vorner' Vaner
@vorner
Jul 04 2018 11:59
OK, so struct X { a: String } is 'static. Because no part of that struct talks about something that could go away on by its own.
Zakarum
@omni-viral
Jul 04 2018 11:59
Or any other trait implemented for reference
Dmitriy
@dpogretskiy
Jul 04 2018 12:00
well, totally, i just never tried to do it :) but it makes sense
the more you know :laughing:
VJ
@00imvj00
Jul 04 2018 12:00
ok, so &'static is different from 'static ?
Michal 'vorner' Vaner
@vorner
Jul 04 2018 12:01
struct Y { a: &String } does not have to be 'static ‒ it depends on the string it points to ‒ if that thing could live on some stack (maybe indirectly), it would go away. You can't use that Y past that point, because your program would try to use it when it no longer exist and would blow up.
Dmitriy
@dpogretskiy
Jul 04 2018 12:01
it's different from T: 'static
to be precise
Michal 'vorner' Vaner
@vorner
Jul 04 2018 12:01
X = &'static T is a reference type for T that also satisfies X: 'static.
Dmitriy
@dpogretskiy
Jul 04 2018 12:02
nice catch
VJ
@00imvj00
Jul 04 2018 12:02
ok, so `static means in nutshell fully owned type, mean a parent type will own all the data, no references.
Zakarum
@omni-viral
Jul 04 2018 12:03

no references.

Only 'static references

Dmitriy
@dpogretskiy
Jul 04 2018 12:03
if any
or none
Zakarum
@omni-viral
Jul 04 2018 12:03
Well. If there are no references then for question "Are all references 'static?" you may answer "true"
VJ
@00imvj00
Jul 04 2018 12:03
ok. Got it. so, even if i don't specify, it is static by default , like struct Y { a: String } this is `static
?
Dmitriy
@dpogretskiy
Jul 04 2018 12:04
yeah
VJ
@00imvj00
Jul 04 2018 12:11
awesome, thank you very much guys. it would be really great if this stuff will be documented somewhere.
lol
Francis Lalonde
@fralalonde
Jul 04 2018 12:53
yeah, took me time to figure it out too. but sometimes discussing stuff in the order of questions that come to mind is the best way to learn. no doc can do that.
VJ
@00imvj00
Jul 04 2018 14:51
true. @fralalonde
Judson Lester
@nyarly
Jul 04 2018 17:14
@jbg Okay - I'm working on the other issues in the code. Once this is the last problem (or nearly so) I'll include references. I think part of the challenge here is that the types involve a Future, which I don't know if I'll be able to describe well enough.
tsoernes
@tsoernes
Jul 04 2018 18:43
is this a sensible way to do dependency injection in rust? If so how to call the function?
pub fn simulate<A: Agent>(opt: Opt) {
    let mut agent: A = A::new(opt.alpha, opt.alpha_avg, opt.alpha_grad);
    ...
}
Considering the case where multiple Agent implementations exist, but they're all instantiated the same with the same parameters
Denis Lisov
@tanriol
Jul 04 2018 18:45
It's possible, but I probably won't do that.
Especially taking into account that for testing you may want to have an agent with additional parameters for mocking.
tsoernes
@tsoernes
Jul 04 2018 18:47
so you would a) make simulate a method of the Agent trait b) just as a standalone function taking agent as parameter
Denis Lisov
@tanriol
Jul 04 2018 18:48
As for calling, the explicit syntax would be simulate::<MyAgent>(opt)
Depends on the relationship between the function and the agent.
tsoernes
@tsoernes
Jul 04 2018 18:57
Another question: Say your program has a big, static, unmutable and unchanging configuration; like IP adresses, ports, paths etc. Do you just pass around a config struct, or do you for each function take only the parts of the config that is needed?
Denis Lisov
@tanriol
Jul 04 2018 19:23
I pass around references or cloned Arcs either with the config as a whole, or with a single subconfig if just that one is needed.
Sylwester Rąpała
@xoac
Jul 04 2018 21:52

Is this a doc error?

It is empty unless start < end

So this shouldn't be empty but it;s not: https://play.rust-lang.org/?gist=b8486e84cec089f6415d08c9b3fcb726&version=stable&mode=debug&edition=2015
(this is with error I don't know how to call is_empty) but you can see this just from iteration.

Ingvar Stepanyan
@RReverser
Jul 04 2018 21:53
that playground sample doesn't compile, it asks you to choose correct impl
But either way, that range should be empty, yeah
You're seeing that it's not?
Sylwester Rąpała
@xoac
Jul 04 2018 22:01
yes. I know It's not compile becouse I don't know how to call is_empty()
but this means that in doc is an error
Ingvar Stepanyan
@RReverser
Jul 04 2018 22:10
why?
It is empty unless start < end
that's exactly what it says
"it is empty unless start < end" is the same as "it is non-empty if start < end" or "it is empty if start >= end"
it's all just different ways to say the same thing
Sylwester Rąpała
@xoac
Jul 04 2018 22:37
Ok. Just my English level sorry :(