These are chat archives for rust-lang/rust

7th
Feb 2017
John Gallagher
@jgallagher
Feb 07 2017 00:25
does anyone know of an example of building a C binary or library for use only by a unit test?
Sebastian Blei
@iamsebastian
Feb 07 2017 09:55
Is it possible to do dynamically typed structs, like the following?
http://play.integer32.com/?gist=640bfd1b6a136417c5e8bcf57807a894&version=stable
Based on content of firsts CSV row, i would like to determine, of which struct the container should hold a Vector of rows.
Or maybe I should call it a dynamic type alias.
Felix S Klock II
@pnkfelix
Feb 07 2017 10:11
@iamsebastian no, you cannot write code like that in Rust, not directly.
@iamsebastian I have thoughts on ways one might try to encode this sort of thing (one option, if the set of types is small and fixed: continuation-passing style. Another option, if the set of types is expected to grow: trait objects)
Sebastian Blei
@iamsebastian
Feb 07 2017 10:13
Thanks @pnkfelix. I will then try another way.
Tomer Margalit
@matomer
Feb 07 2017 12:21
Hi, I'm trying to figure out why something doesn't work:
trait t1{}
trait t2{}
trait tg<T> {}

impl <T: t1> tg<T> for i32 { }
impl <T: t2> tg<T> for i32 { }
the compiler says it's a conflicting implementation
so does this effectively mean that there can be at most one implementation where the trait is tg<T> for a generic T?
Aleksey Kladov
@matklad
Feb 07 2017 12:24
I think the problem is there might be a type T which is both T: t1 and T: t2. Then, you'll get to implementations of tg<T> for i32.
Peter Atashian
@retep998
Feb 07 2017 12:26
There's no way to say t1 and t2 are mutually exclusive at the moment
Tomer Margalit
@matomer
Feb 07 2017 12:28
but unless there's a type that implements both there's no need
additionally this effectively means that you can't have two different impls of this form
with one exception:
Felix S Klock II
@pnkfelix
Feb 07 2017 12:29
matomer: the point is that there could be a type that implements both. In a downstream crate, for example.
Tomer Margalit
@matomer
Feb 07 2017 12:29
impl <T: t1> tg<T> for i32 { }
impl <T> tg<S<T>> for i32 { }
Felix S Klock II
@pnkfelix
Feb 07 2017 12:29
matomer: There is talk of extending impl specialization to allow one to write something along these lines
Tomer Margalit
@matomer
Feb 07 2017 12:30
I'm asking because I'm trying to implement reference resolution
and I get problematic cases like
Felix S Klock II
@pnkfelix
Feb 07 2017 12:30
@matomer (where you would be forced to specify all cases: t1 alone, t2 alone, and t1+t2 together)
Tomer Margalit
@matomer
Feb 07 2017 12:30
I see
I get things like this:

impl <T:t1, TT:tg2<T>> tg1<T> for TT { }
impl <T, TT: t2> tg2<TT> for T { }
where I have to figure out if a type implements tg2<T>
to do that I need to figure out whether I can use the second impl
and to do that I need to figure out whether any type of t1 can implement t2
so I'm going over all corner cases and when trying it I got this
Felix S Klock II
@pnkfelix
Feb 07 2017 12:34
@matomer i don't know whether it will help, but you might want to read over the impl-specialization RFC (keeping in mind that specialization is an unstable feature only available in Rust nightly): https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md
Tomer Margalit
@matomer
Feb 07 2017 12:35
no, if there's a plan to implement it then I should probably handle that case anyway
@pnkfelix can something like the example I gave be used in a program?
I don't see any reason why not and if yes then effectively I need to check whether a trait "has an implementation" for another trait
Felix S Klock II
@pnkfelix
Feb 07 2017 12:36
@matomer to be honest I don't understand the examples you're giving. In part because I don't understand whether you're writing something that is analyzing Rust code itself, or if you're trying to explicitly write case analyses as a series of trait impls... ?
Tomer Margalit
@matomer
Feb 07 2017 12:36
analyzing rust code
Felix S Klock II
@pnkfelix
Feb 07 2017 12:36
@matomer okay, that's helpfu
Tomer Margalit
@matomer
Feb 07 2017 12:36
in an ide when you do go to definition
I need to figure out the relevant impls
so I'm trying to figure out for a type T what impls are "for" it
an impl for a trait t1 that T doesn't implement won't be for it
but an impl for a trait t1 that T does implement will be for it and therefore the go to should jump there (e.g. function name)
Felix S Klock II
@pnkfelix
Feb 07 2017 12:37
@matomer hmm. Is this something that might be better implemented as a query on the Rust Language Service?
Tomer Margalit
@matomer
Feb 07 2017 12:38
I'm currently writing it, it's for intellij-rust
and I already have the parsed tokens
so I don't know that I need anything else
just need to figure out how to avoid cycles when traversing the type/impl dependency graph
Felix S Klock II
@pnkfelix
Feb 07 2017 12:39
@matomer but it sounds like you're trying to duplicate the work of determining whether a type implements a trait? Am I wrong in that understanding?
Tomer Margalit
@matomer
Feb 07 2017 12:39
no, you're right
Felix S Klock II
@pnkfelix
Feb 07 2017 12:39
(Maybe I'm wrong about whether such a query will even be exposed via the RLS... )
Tomer Margalit
@matomer
Feb 07 2017 12:39
but it says "This project is in the early stages of development, it is not yet ready for real use. It will probably eat your laundry."
Felix S Klock II
@pnkfelix
Feb 07 2017 12:40
true
Tomer Margalit
@matomer
Feb 07 2017 12:40
and I want it now :)
Felix S Klock II
@pnkfelix
Feb 07 2017 12:40
I just meant in terms of long term planning
Tomer Margalit
@matomer
Feb 07 2017 12:40
and I already have a lot
Felix S Klock II
@pnkfelix
Feb 07 2017 12:40
since you said you are trying to anticipate future language changes
Tomer Margalit
@matomer
Feb 07 2017 12:40
yes you're right
if it were ready I would've used it
but I don't want to wait so I'm trying to do it on my own
also I didn't know about it when I started :)
Aleksey Kladov
@matklad
Feb 07 2017 12:41
Yeah, in general we are definitely not ready to switch to the RLS right now. It would be wonderful to switch to the RLS in the future, but we need to be sure that it is indeed the best path forward.
Tomer Margalit
@matomer
Feb 07 2017 12:41
oh wait
it relies on racer
Felix S Klock II
@pnkfelix
Feb 07 2017 12:42
@matklad yeah I agree; looking over the current RLS spec it seems like for the short term it wouldn't even attempt to handle this sort of query
Tomer Margalit
@matomer
Feb 07 2017 12:43
@pnkfelix I'm more interested in theoretically would Rust allow something like the example I wrote
because if yes then I need to consider that cases
otherwise I don't
in the end I'm probably going to build some sort of dependency graph and go over it to make sure there are no cycles
rustc solves the problem by waiting for an overflow
Felix S Klock II
@pnkfelix
Feb 07 2017 12:44
@matomer my initial instinct is that its possible that the impls you listed might be supported in the future, though one might have to supply additional impls in addition to those
@matomer (to ensure that there always exists a most specific implementation)
Tomer Margalit
@matomer
Feb 07 2017 12:45
@pnkfelix the first one yes
but I'm more interested in:
impl <T:t1, TT:tg2<T>> tg1<T> for TT { }
impl <T, TT: t2> tg2<TT> for T { }
Aleksey Kladov
@matklad
Feb 07 2017 12:46

There are couple of big limitations of RLS at the moment:

1) It assumes that only one "leaf" crate is being developed. It can't handle the case where the project is a cargo workspace, and several packages are modified
2) It compiles (incrementally and without codegen) the whole crate at once. I am not sure that literally running the compiler, even if it is fast, will work good in the long term. I think this maybe will work, but at least the concrete syntax trees should be cached on the RLS side (https://github.com/rust-lang-nursery/rls/issues/118).

Tomer Margalit
@matomer
Feb 07 2017 12:50
which effectively means 'if P implements t2 then any type implementing tg2<P> implement tg1<T>'
Felix S Klock II
@pnkfelix
Feb 07 2017 12:50
@matomer I think there must be something I'm missing; one can devise cases where your impls are supported today
(you can add a impl tg2<A> for B {}; I left that out but it still compiles with it)
Felix S Klock II
@pnkfelix
Feb 07 2017 12:55
more fleshed out: https://is.gd/JeNiD9 (though I still think I'm missing something regarding the example)
Tomer Margalit
@matomer
Feb 07 2017 12:55
ok, you're right
I got stuck trying to add another one
because currently you can't add another tg2<T> impl
so it's an easy problem to solve
e.g. this: impl <T, TT: t3> tg2<TT> for T { } will give problems
or maybe not
Felix S Klock II
@pnkfelix
Feb 07 2017 12:57
@matomer right, now we're back to "how do you deal with a type that implements both t2 and t3"
(and thus my earlier comment about hypothetical future for specialization)
Tomer Margalit
@matomer
Feb 07 2017 12:58
no, say even that I'm going to guarantee they're distinct
but I assume it will come
then checking if t1 is implemented for t2
becomes a harder problem
since you effectively get trait inheritance
as t1 can implement t3 implement t4 which implements t2
Tomer Margalit
@matomer
Feb 07 2017 13:15
@pnkfelix is something like this acceptable in rust? i.e. would it be supported in the future?
Felix S Klock II
@pnkfelix
Feb 07 2017 13:16
@matomer I'm afraid I don't understand the scenario and I cannot take the time right now to try to do so
Tomer Margalit
@matomer
Feb 07 2017 13:17
ok
Tomer Margalit
@matomer
Feb 07 2017 13:25
ok, nvm checked and it works now