-
theemathas
@j`ey I don't think this is going to work :/
-
j`ey
theemathas: I have no idea about codeblocks
-
j`ey
tbh I thought most of the IDEs were just a UI over gdb
-
theemathas
Ehhh…
-
theemathas
I guess.
-
theemathas
BTW, is gdb supposed to break on panic?
-
theemathas
(I'm not sure if the warnings meant that gdb isn't going to work)
-
j`ey
breakpoint on rust_begin_unwind
-
theemathas
j`ey: Doesn't work
-
theemathas
I can set a breakpoint at main though
-
_habnabit
rbreak panic
-
theemathas
Although it says that main doesn't have line number information
-
insaneinside
theemathas: `main` is not the `main` you write in Rust IIRC
-
theemathas
_habnabit: I'm trying that and it's very weird
-
theemathas
insaneinside: Whoops
-
_habnabit
theemathas, weird?
-
theemathas
_habnabit: "Thread 2 hit Breakpoint 8, __rde_realloc () at liballoc_jemalloc/lib.rs:162"
-
theemathas
_habnabit: bt yields: #0 __rde_realloc () at liballoc_jemalloc/lib.rs:162 #1 0x00007ffeefbff728 in ?? () #2 0x0000000000000005 in ?? () #3 0x00007ffeefbff700 in ?? () #4 0x00000001000a4fe6 in __rde_usable_size () at liballoc_jemalloc/lib.rs:152 Backtrace stopped: previous frame inner to this frame (corrupt stack?)
-
_habnabit
neat
-
theemathas
(But with newlines)
-
zucchini
_habnabit: I actually fixed it by wrapping all (also UnsafeCell) with a Mutex. I need UnsafeCell to trick the compiler with the lifetime thing. Now everything works. :)
-
zucchini
-
theemathas
I tried breaking at cargo_clippy::main
-
theemathas
"Single stepping until exit from function _ZN12cargo_clippy4main17h71690b95c701d32aE, which has no line number information."
-
theemathas
D:
-
theemathas
Something's definitely wrong here.
-
_habnabit
zucchini, you don't need the UnsafeCell; the Mutex is already providing you interior mutability
-
zucchini
yeah I know but without unsafe cell it didnt work
-
zucchini
due to the lifetime problem
-
albel727
you might as well have casted to mut pointer and back
-
_habnabit
zucchini, sure, and i said you can already unsafely erase that lifetime without UnsafeCell
-
zucchini
with UnsafeCell I have the get() method that returns a raw-pointer that can trick the lifetime checker
-
_habnabit
zucchini, &str coerces to *const str
-
zucchini
oh
-
zucchini
i will give it a shot :)
-
albel727
you don't need UnsafeCell to get a raw pointer. I'm not sure one ever needs UnsafeCell.
-
zucchini
XD
-
_habnabit
albel727, you do if you're implementing Mutex
-
zucchini
well I initially copied the code from "cargo-tally"
-
albel727
and Cell
-
theemathas
_habnabit zucchini insaneinside: help meeeeee TT_TT
-
albel727
but that's not what most people need to do.
-
insaneinside
theemathas: well the problem is that cargo_clippy isn't being compiled in debug mode I think?
-
theemathas
insaneinside: the command I used to run rust-gdb was "rust-gdb ../target/debug/cargo-clippy"
-
theemathas
I think that's debug mode
-
_habnabit
zucchini, but, doing work like this (a whole mutex lock!) in a Deref impl strikes me as strange
-
insaneinside
theemathas: yeah it ought to be.. but that's a binary, yes? I assume the binary's source has `extern crate cargo_clippy;` in it somewhere?
-
insaneinside
I wonder if the actual lib is *not* being compiled with debuginfo
-
» albel727 doubts that somehow
-
theemathas
insaneinside: The source has "extern crate clippy_lints" somewhere, I think.
-
albel727
since gdb complains about corrupt stack, I wonder if it's actually a real bug with stack overflow, and reverse debugging can undamage the stack.
-
insaneinside
"reverse debugging"? Insert Soviet Russia joke here.
-
albel727
hey, it's a thing in gdb.
-
theemathas
albel727: I inserted "panic!()" and attempted to break on that.
-
theemathas
It's not a stack overflow bug.
-
theemathas
Oh.
-
theemathas
The "rbreak panic" thing caused a SIGSEGV
-
theemathas
D:
-
theemathas
I'm getting a segfault in rust D:
-
kpcyrd
theemathas: unsafe code?
-
theemathas
I'm gonna assume that gdb messed around jemalloc somehow
-
albel727
never happened to me
-
albel727
though I never did break on panic
-
albel727
well, one can try to switch the allocator to system anyway.
-
theemathas
It segfaulted from std::sys_common::backtrace::demangle
-
theemathas
I'm gonna assume that's not my fault.
-
theemathas
The main problem is that I can't break on a function in an extern crate.
-
theemathas
And I can't run the code line-by-line when I break on cargo_clippy::main
-
theemathas
TT_TT
-
theemathas
Maybe I should just do println!() debugging
-
Tene
I've got my first real rust app together (trivial CRUD with rocket and diesel), and the debug build runs fine, but the release build exits immediately. Anyone have any advice on diagnosing this?
-
Tene
My main() is just a call to setup and launch rocket.
-
Tene
It doesn't appear to be crashing; it's exiting successfully.
-
Sergio
Tene: Are you seeing any log messages?
-
Tene
No output at all.
-
Sergio
Which version of Rocket?
-
j`ey
println time!
-
» albel727 lold
-
Sergio
Rocket doesn't do anything differently on debug/production.
-
Sergio
debug/release*
-
j`ey
not even run quicker? :P
-
Sergio
Heh
-
Sergio
Functionally*
-
Sergio
:)
-
Tene
rocket 0.3.6
-
theemathas
j`ey: Yeah. println! time.
-
_habnabit
Tene, my guess is you're running the wrong binary
-
centril
theemathas: Don't you mean dbg!(expr) time?
-
theemathas
centril: What?
-
Sergio
Tene: Is your code up somewhere?
-
Sergio
That's really weird.
-
Sergio
Are you running it with `cargo run --release`?
-
j`ey
centril: lol
-
centril
!rfc 2173 @ theemathas
-
rustbot
[PR 2173] <open> RFC: Quick dbg!(expr) macro <
rust-lang/rfcs #2173>
-
albel727
!crate dbg
-
rustbot
dbg (1.0.3) - dbg!(expr, ..) macro from RFC 2173 in stable Rust ->
crates.io/crates/dbg <
docs.rs/dbg>
-
Tene
I just added a println!() before and after the rocket call, and those aren't running either. It's got to be something weird in my environment.
-
Sergio
Yeah.
-
theemathas
centril: Thanks
-
_habnabit
Tene, what's the mtime on the binary you're running
-
centril
theemathas: =)
-
j`ey
Tene: comment out evrything but println
-
Aaronepower
Tene: `cargo clean` and rebuild
-
Aaronepower
Tene: And `rustup update`
-
albel727
might as well do just that
-
j`ey
and turn pc off and on
-
Sergio
Lol
-
albel727
(because the new compiler is going to be rebuilding everything anyway)
-
albel727
and turn your lights off and on. put your head on your pillow in between. stay that way for 8 hours or more.
-
theemathas
centril: I don't think dbg! is going to be of much use right now though.
-
theemathas
albel727: lol
-
centril
theemathas: granted =)
-
Tene
I'm building in the rustlang/rust:nightly docker container, on a windows host. I've done clean builds here.
-
centril
theemathas: you can introduce the crate for the rfc as a temporary dependency and use it instead of println! if that helps you
-
Tene
Or, at least I thought I was. Time to clean everything.
-
theemathas
centril: I'm just gonna do printlns
-
centril
:D
-
albel727
but do you actually use cargo run --release
-
albel727
or how do you run your binary?
-
Tene
I was running it with cargo run --release, although I've just edited it in the running container and rebuilt, and it's working fine now apparently.
-
_habnabit
gremlins
-
Tene
This is my first time trying any real development on Windows. I'm not sure how much of my pain here has been just due to unfamiliarity.
-
centril
Tene: welcome to the club; membership brings a lot of pain.
-
mefistofeles
Tene: it's a PITA
-
emerentius
even worse outside of rust
-
centril
emerentius: Haskell development is not so bad on Win tho =)
-
emerentius
relative to haskell itself windows seems easy
-
» emerentius runs
-
emerentius
kidding, I don't actually know haskell
-
badmann
hey guys im doing "cargo build --target i686-unknown-linux-gnu --release" on a project with reqwest support, but it's complaining about not finding any openssl libs. also if I execute my previous native binary on another machine i get missing lib error. any way to statically link it?
-
Aaronepower
badmann: I would suggest trying to build it as musl.
-
Aaronepower
badmann: musl will have it statically linked.
-
badmann
Aaronepower: doesn't that deal only with C std libraries?
-
j`ey
maybe sfackler knows?
-
badmann
i think the issue is one of the dependencies is dynamically compiling openssl
-
Aaronepower
badmann: I don't think so?
-
badmann
pastebin.com/0LcDbLy8 here are all the dynamic libs in my exe
-
cahoots
hi, if i mark an enum, MyEnum, with "#[repr(u32)]" and then i expose a fn via FFI with a signature "my_fn(my_enum: MyEnum)", and the C header for it is "my_fn(uint32_t my_enum)", will that work?
-
badmann
compiling with musl fails, since it says "Could not find directory of OpenSSL installation..."
-
Aaronepower
badmann: Do you not have the openssl env variables set?
-
» albel727 watches unemotionally as Rust tries to reinvent ebuilds :>
-
badmann
no
-
badmann
sfackler/rust-openssl #183 using these flags i get "error: could not find native static library `ssl`, perhaps an -L flag is missing?"
-
badmann
github.com/sfackler/rust-openssl this seems to suggest only setting a variable is sufficient, but unfortunately it does not work for OPENSSL_STATIC=yes
-
theemathas
-
phaazon
hey
-
phaazon
I need to put a value in some kind of a box so that I can “take it out”, move it to a function (that returns the same type), and get that result and put it in the box again
-
Icefoz
theemathas: Good question!
-
phaazon
is there such a thing despites raw pointers?
-
sfackler
phaazon: Option
-
phaazon
Box doesn’t have a “map”-like function
-
theemathas
Icefoz: I ran into this while troubleshooting a problem on #rust-beginners
-
phaazon
sfackler: what do you mean?
-
sfackler
Option<T> is a type that will let you do that
-
phaazon
well, I’m “sure” I have someting
-
phaazon
something
-
phaazon
I don’t want to pattern match on Some(_)
-
phaazon
something*
-
Icefoz
theemathas: It works when you remove the type annotation from x and let it figure it out on its own...
-
sfackler
what happens if your function panics?
-
phaazon
my current version is to do something with ptr::null_mut() + deref_mut + ptr::read + deref_mut back again
-
_habnabit
phaazon, why does it have to be the same box?
-
phaazon
sfackler: well, having to pattern match against None => unreachable!() is meh
-
phaazon
_habnabit: it’s in a FnMut closure
-
muvlon
phaazon, how about &mut T?
-
theemathas
Icefoz: Odd
-
phaazon
muvlon: you cannot move out of that
-
muvlon
it sounds like you just want to borrow your thing to the function
-
sfackler
-
sfackler
but not the caveats around panics
-
phaazon
muvlon: no, the closure has ownership over it
-
_habnabit
phaazon, then why do you have to move it?
-
Icefoz
theemathas: That's a very odd case. I think it's having problems figuring out that the returned type's lifetime is connected to the input type's.
-
phaazon
because I must pass it to a function that needs to move it
-
sfackler
*note
-
muvlon
phaazon, ah, it needs ownership
-
_habnabit
phaazon, wait, so, does it just want to have an FnMut closure moved into it?
-
Icefoz
theemathas: It works if I define a type for foo as well.
-
theemathas
Icefoz: I actually ran into that before.
-
phaazon
_habnabit: I’ll recap
-
theemathas
Icefoz: You cannot have a closure with generic lifetimes.
-
_habnabit
phaazon, maybe some example code
-
theemathas
-
phaazon
I have an FnMut closure that needs to take ownership of a value (because that FnMut closure will call a Fn(A, _, _, _) -> A function
-
phaazon
I just need to find a way to retrieve the value
-
phaazon
give it to the Fn function
-
phaazon
and have it back in the FnMut
-
phaazon
so that next time I call the FnMut object, the value is changed
-
phaazon
is it clear enough now? :)
-
_habnabit
phaazon, would still like example code
-
phaazon
I’ll show you some code yeah
-
theemathas
-
Icefoz
theemathas: Okay, I'm stumped.
-
theemathas
Haha
-
stephaneyfx
theemathas: It does not compile to prevent you from having 2 mutable references to foo
-
theemathas
stephaneyfx: How?
-
stephaneyfx
theemathas: If it did compile, you could call f twice to get 2 such mutable refs
-
theemathas
stephaneyfx: FnOnce are a thing though
-
emerentius
theemathas, trying to get implement reborrowing yourself?
-
theemathas
emerentius: Ran into this while troubleshooting someone else's code on #rust-beginners
-
emerentius
ah, not even re
-
theemathas
not even what?
-
phaazon
yeah, I’ll use an Option
-
phaazon
the pointer stuff is too boring.
-
theemathas
stephaneyfx: Also, commenting out the "f()" line gets rid of the error.
-
emerentius
not even reborrowing because foo isn't a borrow yet
-
stephaneyfx
theemathas: Good points
-
emerentius
I believe the issue is that you're creating a temporary &mut
-
theemathas
-
albel727
tldr: closures in rust are useless, unless passed as function arguments
-
» albel727 runs
-
theemathas
lol
-
talchas
albel727: that's not exactly untrue :P
-
scottmcm
talchas: I was about to say the same :P
-
talchas
closure inference with lifetimes is Hard, because it's basically rank-2 inference
-
theemathas
-
theemathas
albel727 talchas scottmcm ^
-
talchas
so iirc rust never tries to infer a for<'a> without a signature, and there's some hacks to try to make things useful in some cases without
-
stephaneyfx
-
talchas
theemathas: and not only what I just said, it only looks for the signature within like the statement or something
-
theemathas
stephaneyfx: WHYYYYYYYYY
-
theemathas
Why is that "let bar = bar" required???
-
scottmcm
theemathas: so the `move` picks up the right thing
-
phaazon
ok, it should work
-
phaazon
I used Option::take
-
phaazon
thanks peeps
-
stephaneyfx
scottmcm: It actually works without `move`
-
theemathas
-
SpaceManiac
theemathas: the former forcibly moves `bar`, the latter reborrows it
-
theemathas
SpaceManiac: Why?
-
talchas
SpaceManiac: oddly move || go({foo}) also seems to reborrow
-
SpaceManiac
oh hm
-
theemathas
I'm tempted to file a bug now
-
emerentius
talchas, can you post link? I was trying to get that to do it
-
SpaceManiac
go({bar}) doesn't work so it's not strictly a move issue
-
talchas
emerentius: I'm saying that it doesn't work
-
talchas
which is odd, because in most cases that's a move just like let bar = bar;
-
emerentius
err yeah, I meant move
-
talchas
(fn id<T>(x: T) -> T { x } and foo(id(x)) also fails here when it usually works)
-
talchas
in short: define the signature you want for your closure, every time
-
talchas
(it's too bad let x: impl Trait; was deferred)
-
theemathas
talchas: What?
-
theemathas
Should I file a bug?
-
albel727
it's known
-
talchas
theemathas: fn fix_closure<F:FnOnce()-> &mut Foo>(x: F) -> F { x } ... let f = fix_closure(go(bar));
-
theemathas
Huh?
-
talchas
should work
-
talchas
and yeah, it's known that closure inference just falls over in weird ways all the time
-
emerentius
talchas, it was failing because it tried to make FnMut out of it?
-
theemathas
Oh
-
theemathas
The "you cannot make a closure generic over lifetimes" thing
-
theemathas
Wait, no
-
talchas
emerentius: that might be part of it sometimes, mostly it's "you can't make a closure generic over lifetimes without a signature"
-
theemathas
I'm confused now
-
theemathas
I ran into it before
-
talchas
theemathas: the F signature I wrote there is the same as in your call() with the explicit 'a
-
talchas
actually, wait no
-
talchas
it's totally not
-
talchas
and maybe mine won't work and you need yours for this
-
theemathas
-
theemathas
I'm confused
-
talchas
yeah, I forgot that here you'd need the explicit 'a
-
theemathas
talchas: So why did we need "let bar = bar"?
-
talchas
theemathas: I'm really not sure why there
-
talchas
:closure inference:
-
theemathas
I'm really tempted to file a bug
-
talchas
feel free, I just doubt it'll go anywhere
-
talchas
the let bar = bar thing seemed particularly odd
-
sssilver
hey guys, does Rust have the concept of a property? or it's just functions all the way?
-
theemathas
sssilver: No such thing as a property.
-
theemathas
Just methods.
-
badmann
sfackler/rust-openssl #604 i finally figured it out. it looks like the environment variables are treated in an inconsistent fashion across operating systems, and in order for static to work a few others must be set (only on linux)...
-
theemathas
talchas: Possibly relevant issue I filed a long time ago
rust-lang/rust #22557
-
theemathas
That one is actually probably not relevant
-
sssilver
properties are nice though, they add important semantics and readability
-
sssilver
I'm sure someone has suggested this before
-
scottmcm
Sometimes they're nice; often they're a waste of time; occasionally (especially when writable) they're extra confusing
-
theemathas
sssilver: A quick google search yields 3 instances of people suggesting that.
-
scottmcm
Rust generally tries not to have things unless they're particularly helpful.
-
sssilver
programming language communities are fascinating. For every feature there's always a million people who will vehemently oppose implementing it
-
sssilver
I was reading a thread on golang mailing list the other day where someone suggested the idea that enums are good and useful
-
scottmcm
opposition is the correct default response, sssilver
-
sssilver
and a million people attacking the poor soul about how enums are useless
-
scottmcm
a language with all possible features would be terrible
-
sssilver
and how "I have been programming for X years and never once needed an enum in my life"
-
sssilver
I was bewildered that there are so many real programmers who never felt like they needed an enum
-
jonhoo
I think part of the reason is that the full usefulness of enums doesn't become apparent until you have algebraic datatypes and compiler support for checking that you've covered every case
-
jonhoo
which then sort of requires pattern matching
-
sssilver
scottmcm: "a language with all possible features" aka c++ haha
-
jonhoo
many of these features seem unimpressive in isolation
-
scottmcm
sssilver: There are a ton of features that C++ doesn't have.
-
scottmcm
sssilver: For example, green threads and garbage collection
-
scottmcm
sssilver: neither of which is fundamentally bad, but would both be poor choices for C++
-
sssilver
ehh you can define a garbage collector, and allocate all the memory through it
-
» sssilver shrugs
-
scottmcm
sssilver: and if you look at how go has apparently decided to do error handling, I'm not surprised it doesn't want sum types, since doing them properly would lead to changing everything that does error handling
-
sssilver
you're saying like it's a bad thing -- error handling in go is super clumsy imo
-
scottmcm
Oh, I don't like Go at all. But not having sum types is consistent with their past choices.
-
sssilver
I'm all for returning a result type, but most go error handling in the wild makes me cringe
-
scottmcm
And I applaud Go for sticking carefully to its goals.
-
talchas
in particular here, simplicity and only one way to do anything
-
talchas
even if it's an objectively bad way :P
-
scottmcm
<3 talchas
-
sssilver
also I don't understand how they can state they're statically typed and then go on to say
-
sssilver
> func ResolveIPAddr(net, addr string) (*IPAddr, os.Error) where net is one of "ip", "ip4" or "ip6".
-
sssilver
(this is a stdlib function)
-
sssilver
but anyway, this is pretty offtopic at this point
-
sssilver
yeah, properties would be nice :)
-
scottmcm
sssilver: more concretely, In C# I usually see properties overused, with everything always being a property, even when doing so provides no advantage
-
sssilver
scottmcm: properties are a semantic thing. IMO Swift gets it right, at least as far as the standard library and common popular libs
-
scottmcm
And things like `whatever.Length = 4;` is usually more confusing than helpful, in my experience
-
scottmcm
"semantic"? They seem fully syntactic, to me -- just omitting `()`s
-
sssilver
I disagree; to me it's more reasonable then whatever.setLength(4)
-
sssilver
scottmcm: yeah the semantics is what defines the choice of a property vs a function, that's what I mean
-
sssilver
perhaps I'm not using the right word
-
sssilver
Eng is not my native language
-
scottmcm
sssilver: see, I think if there's any useful invariant involved, then different methods like `.truncate(n)` or `.resize(n, x)` or `unsafe .set_len(n)` (see Vec) are better
-
scottmcm
sssilver: and if there isn't an invariant, then it should just be a field :P
-
sssilver
:) I see your viewpoint
-
sssilver
getters though -- those are less ambiguous
-
theemathas
talchas: Filed the issue
rust-lang/rust #47478
-
sssilver
anyway, great chatting -- gotta walk to the hotel. Have a good one!
-
scottmcm
sssilver: sure, but then it's just whether you can omit the `()`s, which is convenient, but clearly not necessary
-
scottmcm
sssilver|away: and in Rust might have implications on what is held borrowed, for example.
-
centril
Manishearth: I don't want to derail your RFC more; so I'll reply here instead =)
-
centril
Manishearth: I'm not sure which you are referring to with "the proposals"
-
Manishearth
centril: theres an ongoing internals thread about this
-
centril
Manishearth: sure; I've participated in that one =)
-
Manishearth
plus, historically this has always been about a generic framework
-
Manishearth
it doesnt focus on testing . nor does it constrain the output
-
centril
Manishearth: What I am saying is that it shouldn't be a generic framework, as testing and benchmarks provide so fundamentally different forms of outputs
-
centril
and trying to fit them into one will just make both worse, I think
-
centril
could be wrong of course =)
-
Manishearth
centril: the framework doesnt constrain outputs at all
-
Manishearth
centril: the focus is on making it possiblr to have cargo orchestrate the build
-
centril
Manishearth: Are we talking about the formatters of the output or the test runners producing the outputs?
-
Manishearth
testing, bench, cargo fuzz, examples -- they all need a way to take tagged code from foo/ or src/ amd do stuff with it getting all the right args from cargo
-
Manishearth
centril: what
-
Manishearth
the frameworl literally lets you generate arbitrary harness code. output whatever you want
-
centril
-
Manishearth
thats an impl detail of the builtin runner
-
Manishearth
it doesnt impose anything on other harnesses
-
jonhoo
yeah, that wouldn't be mandated by libtest 2.0, whatever it ends up being
-
Manishearth
again, the proposals just give you a way to do codegen
-
jonhoo
yup, basically
-
Manishearth
jonhoo: btw might flesh my proposal out into an erfc, are there any missing/unaddressed concerns?
-
Manishearth
its a bit different from yours but not in any major ay i think
-
Manishearth
aside from the fact that mine focuses on the cargo side
-
Manishearth
which i think is really the core of this feature
-
Manishearth
centril: if libtedt 2.0 provides anything it would be proc macro tools for collecting attributes etc
-
PappyFlapps
sorry for a dumb question, but rust makes me feel dumb sometimes. Can I (reasonable w/o extern crate) modify orig vec from a slice?
gist.github.com/4fa2749a780f1b9c66440191bfc29739
-
Manishearth
not TestDesc
-
jonhoo
I think the biggest restriction of your proposed design is that I don't think having an "iterate over things with this annotation" is sufficient for test frameworks that are sufficiently different from xUnit-style specifications
-
jonhoo
but I might be wrong and not have thought enough about your design
-
Manishearth
thiygh it may eventually also provide tools for various formatters but you can use your own
-
centril
jonhoo, Manishearth: that's fine - but if we want custom test runners to output their final results and events into a machine readable format that supports multiple different output formats, test runners need some type definitions or traits to provide values which can then be serialized to human readable strings, json, xml, <insert your format>
-
Manishearth
jonhoo wait, thags not a constraint of my system?
-
centril
values for*
-
Manishearth
jonhoo: mine lets you run arbitrary proc macro code, and may have helpers for collecting attrs/etc
-
Manishearth
wait maybe i wrote the original one that way
-
Manishearth
in which case my bad
-
jonhoo
centril: a test runner is free to use println!() *instead* of outputting through a standardized interface if its properties are such that they don't fit well with standardized formats
-
cobrand
-
Manishearth
"collect all attrs" and "remove main()" are supposed to
-
jonhoo
centril: I don't think we want to design that interface to take basically whatever, because then the formatters will not be able to do anything useful
-
centril
jonhoo: it may be free to use println!(), but it shouldnt...?
-
Manishearth
be helper apis that you can use if tou want
-
cobrand
-
jonhoo
centril: for example, consider the case of the output formatter being TAP
-
Manishearth
jonhoo imo the interface shouldnt be stabilized
-
Manishearth
jonhoo however exposing libtests formstter is good
-
jonhoo
Manishearth: I think it's useful to have at least some very common events that are shared by most consumers of test output
-
centril
-
Manishearth
sorry, i mean that there shouldnt be pressure to use the interface
-
Manishearth
my bad
-
jonhoo
ah, yes, agreed
-
Manishearth
as in, it would eb a convention basically
-
jonhoo
Manishearth: I guess my observation is that it's not sufficient to just be able to iterate over functions
-
PappyFlapps
cobrand : ah i see, create a scope ... thanks
-
jonhoo
Manishearth: there are good arguments for some test runner wanting to annotate, say, a module, or a var
-
Manishearth
yeah
-
jonhoo
but apart from that I think what you propose could work just fine
-
Manishearth
jonhoo in ehich case they have to build their own proc macro stuff for that
-
jonhoo
yes, but they won't be able to do that without compiler support
-
Manishearth
the "find test functions" would be a helper api
-
jonhoo
because there needs to be a way to *find* the annotated things
-
jonhoo
which is basically what my proposal is
-
Manishearth
jonhoo sure they would. its a prpc macro
-
jonhoo
so I think some combination of the two is the way to go
-
jonhoo
prpc?
-
Manishearth
mine gives you a proc macro running on the entire crate
-
Manishearth
*proc
-
jonhoo
ah
-
Manishearth
im on ssh and a phone
-
jonhoo
hehe, np
-
centril
jonhoo: The runner being able to classify itself and provide extra data in the form of some object-notation string isn't whatever
-
jonhoo
centril: I don't see why there's any advantage to that though?
-
Manishearth
mine is just a proc macro that takes in the lib and outputs the binary
-
jonhoo
what would a TAP formatter do with that information?
-
Manishearth
within this framewoek it can have helpers that do some of the work
-
jonhoo
Manishearth: yes, but we don't want to have test runners need to parse the entire crate? that's seems super inconvenient, even if it is flexible
-
jonhoo
also, relatedly, this is basically what matklad proposed in the last meeting I think
-
jonhoo
a whole-crate macro
-
centril
jonhoo: The TAP formatter can ignore it... this is the first I've heard of TAP tho..
-
centril
The alternative is that the runner can't provide it at all other than with println or logging to a file
-
jonhoo
centril: I think the very narrow interface that we'd encourage would just have "success"/"failure" type things, and nothing else, because it's most likely that most formatter will be able to do something useful with that
-
jonhoo
anything else there isn't really any advantage to forcing through the same interface
-
centril
jonhoo: The most common formatter will probably be JSON and human readable output
-
jonhoo
it's not about the "wrapping"
-
jonhoo
like whether it's JSON or human readable
-
jonhoo
but about *standardized* output
-
centril
the human readable format can just dump the extra JSON if you do something like --verbose
-
centril
or --extra
-
jonhoo
TAP for example is a protocol that is supported by lots of IDEs + other tools for consuming test output
-
jonhoo
and there are others
-
jonhoo
and having "extra" information isn't something that is a part of that
-
jonhoo
there's nothing useful for the formatter to do
-
jonhoo
and if you're *not* conforming to a standard, then println! is fine, right?
-
jonhoo
the interface is solely about making it easy to conform to a wide range of testing format standards
-
centril
jonhoo: println! has bunch of concurrency and readability issues...
-
jonhoo
so that most runners will work with most standardized formats
-
jonhoo
centril: ah, but that the runner could manage internally
-
jonhoo
by using a logger or a lock or whatever
-
jonhoo
Manishearth: I think a separate concern I have with your proposal, but that may not be warranted, is that it's so broad that it'll be hard to then standardize anything about testing. such as a test output formatter interface. but maybe that's a silly objection
-
centril
jonhoo: Is the set of #[my_runner::test]s handled by the runner, or does cargo handle executing each #[my_runner::test] by spawning the runner, etc.?
-
centril
jonhoo: well your concern here is my concern also...
-
jonhoo
Manishearth: I also worry that because it's such a "large" feature at that point, it'll be hard to get buy in for implementing it in a reasonable timeframe
-
jonhoo
Manishearth: I'd almost prefer something more scoped at first, and then see if for example your proposal could later be used to *implement* that first scoped step down the line
-
jonhoo
centril: in my proposal (and in Manishearth's), cargo basically doesn't handle anything
-
jonhoo
all it really does is pick which main() to run
-
jonhoo
and each main() is generated by the test runner, and it can do whatever it wants to
-
centril
jonhoo: but is that main() for each #[my_runner::test] fn my_important_test() {..} or one main() {..} for __all__ the #[my_runner::test] in the crate?
-
jonhoo
there's a single main() that's managed by the runner
-
jonhoo
it decides what tests it wants to run from that main
-
jonhoo
the test runner decides the entire contents of main
-
jonhoo
which may include spawning threads, may include importing all the tests and running them sequentially, may include forking off into different processes
-
jonhoo
it's entirely up to the test runner
-
jonhoo
the annotations are essentially just for the runner to help find tests and other functions/bits
-
centril
sec, reading your proposal again
-
cobrand
hum, I have a crate which is a lib, whenever I try to "cargo test" it says "error[E0601]: main function not found"
-
cobrand
is this normal?
-
jonhoo
do you have a file called src/main.rs by any chance?
-
cobrand
nope
-
cobrand
just a src/lib.rs, I have a few main in examples/ but that's it
-
cobrand
It worked like 10 minutes before that, and now i get this
-
cobrand
oh that's because one of my files in examples/ is empty, so it doesn't have a main
-
centril
jonhoo: "Note that this would select the indicated test runner for the entire crate." <-- I find this bit problematic... What if I want to use unit tests some places and proptest some other places and something else for integration testing..?
-
centril
jonhoo: also; why not a TestEvent::Ignored(String) variant?
-
jonhoo
centril: see the parenthetical -- cargo already compiles integration tests as separate crates
-
jonhoo
so while you could only use on test runner inside src/
-
jonhoo
you could use different test runners in different test files under tests/ for example
-
centril
jonhoo: I read the parenthetical, and I don't think it is sufficient... I want to use different runners inside src/ for each module
-
jonhoo
it's true that it's a limitation of that design, but it's not quite as big as it may seem
-
centril
unit tests for one module, property based for another
-
jonhoo
centril: that will be very tricky with *any* design
-
jonhoo
because there is only one main
-
jonhoo
though I think *maybe* you could do it with Manishearth's
-
jonhoo
but you would need to compile src/ multiple times
-
jonhoo
there's also subcrating, though that may be a bit extreme
-
jonhoo
as for the TestEvent enum, I haven't fleshed it out at all -- that was just a very brief example to show what I was thinking
-
centril
jonhoo: you could have multiple mains, but call different runners one after the other and use different attributes such as #[proptest::test], #[test], #[othertest::test]
-
jonhoo
that post is not anywhere close to an RFC -- it was more a proposal for how we might go about this
-
centril
jonhoo: I understand that fully ;)
-
jonhoo
centril: no, there can be only one main() in a program. in theory the compiler could generate a main that calls out to lots of other test runner functions (like my proposed main() already does to TestRunner::run)
-
jonhoo
the only issue is how the crate author specifies the test runner
-
jonhoo
that's the hard part in a sense
-
jonhoo
finding a nice API for that that's still feasible to implement
-
centril
jonhoo: what I meant by multiple mains is that you have one real main that just call other "mains"
-
centril
obviously an executable program can only have one entry point
-
jonhoo
yes, that's what my design already does. except it's limited to calling just one
-
jonhoo
because it's not clear how you even declare that there are many
-
jonhoo
in theory it should be doable -- you'd just have to find a nice interface for it
-
centril
jonhoo: I think #[proptest] having registering to one place and #[test] registering to another is nice
-
centril
jonhoo: you'd have to complicate things a bit to have a list of runners, and for each runner registered_test_components!(runner)
-
jonhoo
well, registered_test_components! is one thing -- in theory that should just work as already proposed
-
jonhoo
though you do run into issues like what if two test runners declare the same keywords/attributes?
-
jonhoo
but the bigger issue is how you add a test runner in the first place. you can't just extern crate it with an annotation. it needs to be "selected" somewhere
-
centril
jonhoo: a hard error =) and the runners ecosystem will have to be nice and not be greedy about attributes
-
jonhoo
centril: it's hard to make it a hard error given that they are just procedural macros. the whole intention of this design is to introduce as little extra stuff/knowledge into the compiler as possible
-
jonhoo
so the user would end up with some really weird errors in that case
-
jonhoo
not being greedy is weird
-
jonhoo
who gets to have #[test] ?
-
centril
jonhoo: #[use_test_runner(MyTestRunner)] extern crate test_runner_proptest; #[use_test_runner(DefaultTestRunner)] extern crate test_runner_default; The #[use..] invocation registers an attribute, if two invocation registers the same you get a hard error - simple and not weird at all; The runners are executed in order of #[use..] and are only given the tests annotated with attributes they
-
centril
registered - #[test] is reserved for the built in default runner which you don't have to do #[use..] for
-
jonhoo
what do you mean "registers the same"?
-
jonhoo
the registration isn't per runner
-
jonhoo
that would be super complicated
-
jonhoo
"registration" is just the ability to have a set of symbols available to query at runtime
-
jonhoo
that way the compiler basically doesn't need to know about any of this
-
jonhoo
it's just a minor hook to register symbols that can later be iterated over
-
centril
jonhoo: an attribute #[foobar] has a name "foobar" - if a runner reserves #[foobar] through some API the compiler provides, and some other runner also reserves "foobar", then you get an error
-
jonhoo
that's not the proposed API in my post at all
-
centril
jonhoo: it is not, i know
-
jonhoo
#[foobar] would be a procedural macro that generates whatever code it wants to
-
Manishearth
jonhoo yes, this is exactly my point, they should be a hole crate proc macro
-
Manishearth
*whole
-
jonhoo
Manishearth: so, I don't think going to whole-crate is necessary
-
jonhoo
I think that makes it more complicated than it needs to be
-
Manishearth
jonhoo: IMO cargo is the hardest part
-
Manishearth
jonhoo : why though?
-
jonhoo
I think being able to register symbols (basically functions, variables, types, modules, or whatever) is the only thing that's needed
-
jonhoo
the rest is fully covered by procedural macros
-
Manishearth
no
-
jonhoo
why it's more complicated?
-
Manishearth
you need te ability to generate and replace main
-
Manishearth
and also inject imports
-
centril
jonhoo: #[proc_macro_test(proptest)] fn my_runner(..) {..}
-
Manishearth
i find the whole crate macro thing to be *simpler*
-
Manishearth
it doesnt need anything on top of what exists
-
Manishearth
and we can expose common ops as APIs
-
centril
Manishearth: it is simpler, but it is too simple and blocks use cases that are necessary imo
-
jonhoo
Manishearth: it's more complicated in that you have to walk the source tree of the crate
-
Manishearth
like "remove main" and "find attr functions"
-
jonhoo
centril: I don't think it blocks anything?
-
Manishearth
centril what dies it block?
-
jonhoo
Manishearth's proposal is by far the most general one
-
Manishearth
jonhoo proc macrocalready knows how to do that
-
jonhoo
Manishearth: yes, I know, I'm saying I think the interface is too painful to use :)
-
Manishearth
jonhoo: fwiw this is what tge current test runner does anyway
-
Manishearth
jonhoo: not if we expose helper apis
-
Manishearth
jonhoo basically
-
jonhoo
Manishearth: true, though then we need lots of helpers, which seems unfortunate
-
centril
assuming that the "whole-crate" idea is jonhoo's "we can have one #[use_test_runner]" approach it blocks combining different runners inside src/
-
Manishearth
its either expose a restricted api, or expose a general thing *and* that api
-
Manishearth
jonhoo: i see two apis we need
-
jonhoo
I'd prefer to start with something that is geared specifically towards testing, and then potentially replace it down the line with something that can still maintain the same neat interface
-
Manishearth
like, its not more work in eitger way, but the general api gets it to us for free
-
Manishearth
jonhoo: i think that kinda sucks for bench and fuzz and other use cases
-
jonhoo
I think you could still do bench and fuzz in my proposal
-
Manishearth
yeah
-
Manishearth
but nit test frameworks that work differently
-
Manishearth
*not
-
centril
jonhoo: regarding TAP; you can just linearlize the JSON into the TAP format and dump it there, no?
-
jonhoo
Manishearth: there would be some restrictions of course, but I think that's okay for a first iteration if it opens up for most of what we want with a very targeted interface
-
Manishearth
jonhoo: anyway, ill write up an erfc and include this concern
-
jonhoo
:+1:
-
Manishearth
because its an erfc we can implement the general thing and make a decision on not exposing that lwter
-
Manishearth
*later
-
jonhoo
Manishearth: I'm not really opposed to your way of doing things. I only worry that it's biting off a lot of work, and aiming to be so general as to be hard to deal with and manage.
-
Manishearth
jonhoo: got an email address?
-
Manishearth
jonhoo: the way i see it its exactly the same amount of work
-
jonhoo
Manishearth: jon + thesquareplanet com
-
Manishearth
its going to be a proc macro anyway, either we expose a restricted API or we expose the underpinning and that api
-
jonhoo
yup
-
Manishearth
*underpinnings
-
jonhoo
well, sort of. I think the restricted API may be less work
-
jonhoo
but I could easily be wrong
-
Manishearth
everything is already there, its a question of exposing
-
Manishearth
heh sure
-
Manishearth
anyway ill sketch it out and email it to you pls devtools
-
jonhoo
it also means that we are opening up a huge API surface, which then needs to be supported
-
Manishearth
*plus
-
jonhoo
rather than something smaller which we can see how pans out
-
jonhoo
sounds good
-
Manishearth
jonhoo: nah. its the same surface as proc macro
-
centril
On the extra data thingy... I guess any extra data can be injected into the String - but it would be nice for the runner to know if verbose or non-verbose data is requested
-
Manishearth
my proposal is literally to make it a whole crate proc macro and let it do whatever it wants
-
Manishearth
that does block us on proc macros but i think thats ok
-
jonhoo
oh, yeah, blocking on proc should be fine
-
jonhoo
just more incentive to have that completed
-
centril
Manishearth: elaborate on "whole crate proc macro"? is the whole-crate bit for the proc macro that defines the runner, or for the whole crate that is using the runner ?
-
jonhoo
and yeah, I realize that's the proposal, but that's giving away a lot of power vs. something that doesn't let you do whole-crate macros :p
-
jonhoo
centril: I don't understand why you want to use standardized output formatters for a non-standard output? why is println!() not sufficient for specialized testers?
-
Manishearth
centril: the harness is generated by running a special proc mscro on the whole crate
-
Manishearth
jonhoo: centril: ill also include a vague thing about outputs
-
jonhoo
centril: as for things like verbose, the runner can parse that from command-line flags?
-
Manishearth
centril: email?
-
centril
Manishearth: twingoow⊙gc
-
Manishearth
thanks
-
jonhoo
Manishearth: haha, "a vauge thing about outputs" :p
-
centril
=)
-
jonhoo
vague*
-
centril
jonhoo: println doesn't go to IDEs - it only goes to the terminal
-
Manishearth
yeah no spell check on ssh on phone
-
jonhoo
no no, wasn't complaining about spelling
-
Manishearth
and im terrible at phone keyboards
-
jonhoo
just found the phrasing entertaining
-
Manishearth
heh
-
jonhoo
I think output formatting is very much a secondary concern
-
Manishearth
its an erfc
-
jonhoo
it's a nice-to-have for integration with standardized testing protocols
-
jonhoo
but can probably be handled independently
-
Manishearth
so i can say "we want to have some output formatters that folks can use if they wish, and we should figure one out"
-
jonhoo
sort of like an opt-in for test runners
-
Manishearth
yeah
-
jonhoo
essentially, "if you can provide these events, that buys your runner some integration for free"
-
centril
jonhoo: so the runner can parse command-line flags passed to cargo, like cargo test --extra ?
-
jonhoo
the runner fully dictates main()
-
Manishearth
yep
-
jonhoo
it can do whatever it wants
-
jonhoo
including parsing arguments
-
Manishearth
we dont constrain it all
-
centril
right; but cargo passed on --extra to the main() of the harness
-
Manishearth
the test support is literally "gimme a file and ill give you a new file" followed by "caego knows how to build this"
-
centril
passes* on - my spelling is shite too
-
Manishearth
yep
-
Manishearth
dont run cargo test --runner foo -- randomflags unless those flags actually work
-
jonhoo
yeah, I think we'll want to stipulate that all arguments to cargo test are passed on to the test runner
-
jonhoo
it's pretty annoying to have to do the split with --
-
Manishearth
jonhoo: oh. btw. forgot to mention, we need a concept of generated code deps
-
Manishearth
jonhoo: if you depend on manishtest, manishtests deps will be build deps, BUT your generated test may have its own dependencies
-
Manishearth
i.e. deps on clap or libfuzzer or ...
-
jonhoo
hmm
-
centril
OK; Cool. You've addressed all my concerns (save for being able to use different runners in 'src/')... #[proptest] can just do one of: 1. save extra data to file, 2. dump to terminal via println! 3. just inject all extra data as a json string inside the TestEvent::Success/Failure String
-
Manishearth
either have a way for the crate to output dep info or include it in the cargo.toml of manishtest
-
jonhoo
hmm, I have half a mind to just say that test runners should be declared as regular dependencies, but that probably isn't feasible
-
Manishearth
[harness-dependencies]
-
jonhoo
it *could* be that we want [harness-dependencies]
-
Manishearth
jonhoo: they are, kinda
-
jonhoo
haha, yeah
-
Manishearth
well, it dependa actuslly
-
centril
[harness-dependencies] sounds lovely
-
jonhoo
the alternative would be to say that [dev-dependencies] are considered regular dependencies of binaries generated by harnesses
-
Manishearth
if we have #[proc_macro_test(testname)] and a harness=testname key then no need to specially declare it in Cargo.toml
-
centril
The "using multiple custom runners inside 'src/'" is a big concern of mine tho
-
Manishearth
however for keeping things easy to grok id prefer thdy be explicitly declared
-
Manishearth
centril yeah ...
-
Manishearth
centril: also not all runners make sense inside src
-
centril
Manishearth: granted =)
-
Manishearth
eg fuzzing needs separate targets
-
centril
but test, proptest, quickcheck, .. those kind of testing frameworks do
-
Manishearth
yep!
-
Manishearth
the ability to say "dont run on src" suffices
-
centril
Manishearth: I don't think having multiple runners per crate is insurmountable tho; you could easily just have them register their own attribute and then run the runners in the order defined in Cargo.toml [harnesses]
-
jonhoo
yeah, though I think it'd also be perfectly fine to have cargo generate multiple binaries
-
jonhoo
and then run those in sequence
-
centril
[harnesses] proptest = "1.0.0" \n quickcheck = "1.5.0" \n ...
-
centril
jonhoo: totally; but you have to still deconflict attributes so that multiple proc macros cant reserve the same attribute
-
centril
so you know which one belongs to which runner
-
jonhoo
yup
-
jonhoo
and I think that's something we'd have to deal with in Manishearth's design too
-
jonhoo
somehow
-
jonhoo
if two harnesses want to use the same keyword
-
jonhoo
but (obviously) in different ways
-
jonhoo
#[test] and #[bench] are strong candidates here
-
centril
Tho I think #[test] should be reserved for the default runner we have today for simplicity
-
remexre
What do people normally use, syntax-wise, for macros that generate impls? I've tried (<T>, Foo<T>), (<T> Foo<T>), and (Foo<T> where <T>), and all have ambiguities...
-
centril
no-one but the compiler gets it, so there are no squabbles over it
-
jonhoo
there isn't a good reason for that if a crate doesn't use the default runner though
-
jonhoo
and the problem still doesn't go away
-
centril
jonhoo: crates.io harmony is the good reason ;)
-
jonhoo
this is different though. this is like saying no two crates can have a type with the same name
-
jonhoo
sort of
-
centril
we wouldn't want community fights about which one of jonhootest and centriltest got to be '#[test]'
-
remexre
Also, I haven't been following along, but #[test(name_of_test_crate)] ?
-
centril
jonhoo: hmm... not really; crate types are namespaced by the crate, and you can always rename them with 'use..'
-
jonhoo
no, but who gets, say #[test::setup] ? what about #[benchmark] ? or #[skip] ?
-
centril
remexre: I think that nests badly if you have #[test(proptest(runs = 100))]
-
jonhoo
centril: yes, I'm not saying that's the case today
-
jonhoo
I'm comparing the proposed "just say no-one can use #[test]" doesn't solve the problem -- it'd be the same as saying there can be no duplicates
-
remexre
#[test(proptest)] #[proptest(runs = "100")] fn asdf() {} ?
-
centril
#[proptest(runs = 100)] is simpler
-
centril
remexre: #[proptest(runs = 100)] fn foobar() {}
-
muvlon
it's more like "no two crates can have a macro with the same name"
-
centril
short and sweet
-
remexre
But then the compiler's prevented from adding new attributes, no?
-
centril
remexre: how so?
-
jonhoo
I think both of those proposals are a little too simple. There are testing frameworks that have significantly different ways of specifying tests. Requiring that format for attributes would be way too limiting
-
remexre
let's say the compiler adds a proptest attribute; now what happens?
-
jonhoo
yeah, that also true remexre
-
centril
remexre: that is already true of attributes and custom derive
-
jonhoo
though we sort of already have this problem with procedural macros
-
jonhoo
but this would likely make it worse
-
remexre
I thought derives "got to" the attrs before the parser proper?
-
centril
remexre: yes, but the trait... ;)
-
remexre
Oh, right
-
jonhoo
not sure about that. but regardless, proc macros can do arbitrary attributes
-
centril
#[derive(Arbitrary)] <-- who gets Arbitrary?
-
remexre
yeah, sure, that makes sense. Why aren't those paths again? :P
-
centril
remexre: +1 ;)
-
centril
remexre: and why can you custom derive non-traits ?
-
remexre
or at least #[derive(crate_name::Type)], even if it's fakey
-
remexre
idk, I like the vulkano shader derive
-
remexre
(over writing shader loading logic myself :P)
-
jonhoo
yup
-
jonhoo
and again, proc macros can make arbitrary attributes
-
jonhoo
like #[foobar]
-
centril
remexre: you could just scope it like 'use proptest::arbitrary::Arbitrary; #[derive(Arbitrary)] struct FooBar;'
-
jonhoo
so we already have a namespacing problem there
-
jonhoo
the particular issue with test harnesses is that they are *likely* to pick overlapping names
-
centril
jonhoo: its a good thing they are unstable so we can break the lot of it
-
remexre
centril: A use could be present below the derive expansion, no?
-
centril
remexre: below = ?
-
remexre
#[derive(Arbitrary)] pub struct Asdf; use proptest::arbitrary::Arbitrary;
-
remexre
Or even expanded to by another custom derive
-
remexre
#[derive(Arbitrary)] struct qwertz; #[derive(ExpandToQuickcheckOrProptestArbitraryUseBasedOnThePhaseOfTheMoon)] struct bar;
-
centril
remexre: the compiler could simply add a rule that says that derive can only see uses before - and uses inside derive do not expand into the module directly
-
centril
or one of those
-
muvlon
this sounds very hacky
-
centril
muvlon: less hacky than not namespacing custom derive :P
-
muvlon
it is a workaround for not namespacing custom derive (or macros in general)
-
remexre
idk, gtg tho; bye all
-
muvlon
and it might put off the *actual* work to namespace macros
-
centril
muvlon: I'm certainly open to more general ideas
-
jonhoo
Yeah, I'm with muvlon here
-
jonhoo
this problem is not becoming better with time, and will come back to bite us
-
centril
it was an OTOH thought ;)
-
muvlon
i like the "use proptest::arbitrary::Arbitrary; #[derive(Arbitrary)] struct FooBar" idea best
-
muvlon
but then i'd also want `use error_chain::bail; bail!("foo")`
-
muvlon
instead of the odd #[macro_use]
-
centril
jonhoo: on #[test] and who gets to use it.. you can do #[mytest] mod foobar { #[test::setup] fn setup() {..} fn mytest(..) {..} .. }
-
jonhoo
#[macro_use] is so weird
-
centril
or just #[mytest::setup]
-
muvlon
the entire macros-not-being-namespaced issue is weird
-
jonhoo
yeah
-
centril
On a separate note... There needs to be more focus on property based testing in Rust in general
-
muvlon
so i'm against any sort of bandaids for now
-
jonhoo
and with proc macros, it's just become worse
-
centril
muvlon: I thought failure was all the rage now what with error_chain being sorta deprecated :P
-
jonhoo
because now we can have collisions on arbitrary attributes too
-
muvlon
i used failure for a crate recently
-
muvlon
but then went back to error_chain because i didn't find a way to match against failure::Error
-
centril
jonhoo: this is a real problem for quickcheck and proptest if you want to combine them cause they both will have traits Arbitrary
-
centril
and deriving for that
-
muvlon
i know i'm supposed to write custom error types and impl Fail for them but really I just want a single error type like error_chain! generates for me
-
» centril casts shame on muvlon :D
-
jonhoo
muvlon: the single error type should be failure::Error
-
jonhoo
and then you use .downcast_ref()
-
jonhoo
if you need to introspect it
-
jonhoo
is at least the impression I've gotten
-
centril
downcasting :(
-
albel727
rewrite it in java
-
» albel727 runs
-
jonhoo
haha
-
jonhoo
nice
-
centril
albel727: you run a lot :P
-
muvlon
jonhoo, yes, that is a solution
-
muvlon
but matching is far more ergonomic
-
jonhoo
I agree
-
centril
muvlon: +1 million
-
jonhoo
I guess one observation is that callers often don't care exactly what the error was
-
albel727
I'm told that often. not as often as I run though. :>
-
jonhoo
like with io::Error
-
FenrirWolf
you can still make a one-error-to-rule-them-all when using Failure. it just doesn't implement one for you by default
-
FenrirWolf
think you'd hjave to do it yourself, which if that's the pattern you want i guess it makes sense to use the tool that just does it for you
-
centril
The thought of dynamic dispatch makes me uncomfortable in general; I need to be more OK with it
-
muvlon
failure::Error is only supposed to be for "high-level errors", i.e. when it's probably too late to handle anything anyway and you just want to alert the user/log it
-
muvlon
so you maybe won't need to match against it as much if you write another error that impls Fail
-
centril
muvlon: my largest problem with Fail(ure) is that it has 'static + Send + Sync directly and no tower of traits
-
muvlon
but i want that crispy error_chain macro that eliminates that sort of boilerplate
-
centril
so it is unusable for error types with lifetimes
-
muvlon
that too
-
sfackler
centril: how many of those have you seen?
-
centril
sfackler: they are clearly in the minority; but for lexers (which are common), it is useful to have an MyError::Unknown enum MyError<'a> { Unknown(&'a str), .. }
-
centril
saving the span is also a viable option
-
sfackler
why is it bad for that to not implement Fail?
-
centril
sfackler: it can't implement Fail
-
centril
afaik
-
sfackler
I know. Why is that a bad thing?
-
centril
sfackler: cause the failure crate brings with a common and useful API for custom deriving stuff
-
centril
which you don't get by not being able to impl Fail
-
sfackler
but when are people going to be using the MyError<'a> as a normal Fail error that's propagated around? you can't really since it holds a borrow
-
centril
What is very appealing to me about failure is the custom deriving stuff
-
centril
sfackler: its not the propagating-around that I am after, it is the conversions (From impls, etc.) and what is offered by quick-error that I am after
-
centril
I guess I could fork failure and have an identical interface save for the trait name to support lifetimes and piggyback on the work done there
-
centril
but that bifurcates a bit, which I would be happy to avoid
-
muvlon
i see no reason *not* to stick with error_chain for the time being
-
muvlon
i think the rust ecosystem has a tendency to move super fast instead of letting things mature
-
muvlon
error_chain isn't even 1.0 yet and it's already considered "old and busted"
-
centril
muvlon: quick-error for me =)
-
muvlon
haven't used that one yet, i'll give it a look
-
centril
^,-
-
centril
muvlon: I could be wrong; but I think the great appetizer of failure was custom derive
-
muvlon
custom derive is cool and all but with the downcasting it feels a bit like going back to good ol Box<Error>
-
cobrand
well, when error-chain was created custom derive wasn't stable
-
muvlon
and i think error_chain does fine without it so far
-
cobrand
since then, custom derive became stable so a new, "easier" library came to life
-
muvlon
i guess you could rewrite error_chain to have #[derive(ChainedError)] or something but that wouldn't even gain that much
-
centril
We clearly need #[derive(ErrorTheCentrilWay)] that I will implement at a time of my choosing :D
-
muvlon
i think i don't even want a custom-derive-based thing
-
muvlon
because that will always give you a trait, not a magic gargantuan enum you can match against
-
centril
muvlon: nope; custom derive can give you arbitrary code that totally does not impl any trait back
-
muvlon
wait what
-
centril
^-- exactly
-
centril
-
muvlon
i mean, i knew about the proc macro hack
-
muvlon
but i just assumed it was still generating trait impls in the back
-
groks
lol
-
groks
that wait what though
-
muvlon
oh, the nightly book is actually upfront about this
-
muvlon
hmm or not
-
muvlon
"Today, the only thing you can define procedural macros for is to allow your traits to be implemented on a type by specifying the trait name in a derive annotation."
-
centril
I'm not sure it was a good idea, but well... it is stable now and with us to the very end
-
muvlon
oh, i'm looking at it now
-
groks
@centril probably will be fixed wayyyyy later.
-
groks
when someone isn't afraid to touch it
-
muvlon
you actually have to output the `impl Trait for Type {` yourself in the proc macro
-
muvlon
so nothing stops you from emitting anything else
-
muvlon
also weird: in every custom derive i've seen, you take a token stream as input, convert that to a string, then parse that string using syn or whatever
-
muvlon
_including_ supposedly lexing it back into tokens, no?
-
centril
muvlon: was this stabilization by accident?
-
centril
groks: it's on stable; can't be fixed
-
groks
bah
-
muvlon
stabilization by serde-really-needs-this-lets-get-it-out-the-door
-
scottmcm
:)
-
groks
centril that'll be a fun one years from now
-
centril
you can't break anyone's code on stable except for in very very minor cases
-
muvlon
don't get me wrong, i love to derive (De-)Serialize
-
Mutabah
What's bad about this being stabilised?
-
Mutabah
(And what is the bad bit of the proc_macro_derive system?)
-
groks
Mutabah "magic arbitrary crap" being returned
-
Mutabah
Ah, being able to return anything from the derive handler?
-
centril
Mutabah: what is bad is that 1. you can emit non-impl items in #[derive(..)] , 2. there is no namespacing, if two crates use the same trait, you are effed
-
centril
specifically non-trait-impl-items
-
groks
yep
-
muvlon
the whole thing about it having to be its own crate is weird as well
-
centril
muvlon: I thought that was a technical temporary restriction?
-
Mutabah
muvlon: That's a technical issue mostly
-
muvlon
but that one's fine since you can lift that restriction without breaking any code
-
centril
I wonder how much breakage (which we won't do..) would be hypothetically caused by requiring the emitting of a single impl-of-trait item which is named the same as the trait the custom derive macro registered for
-
groks
centril: a lot.
-
groks
Have to realize a lot of people are throwing that impl out w/out realizing it's mostly a hack
-
dtolnay
centril: serde_derive emits something that is not an impl block
-
groks
just to make it float by, and also, I hate puppies, they fart too much
-
groks
Gotta find a diet for this dog that is rust compliant lol
-
centril
dtolnay: oh :/
-
muvlon
i guess i'm just a bit salty that custom derive got stabilized in no time but i'm still waiting for slice patterns
-
groks
did any of you get the plush ferris crustacean from kickstarter?
-
groks
muvlon good luck.
-
centril
groks: no; link?
-
groks
Gotta have someone with some pull
-
groks
-
groks
totally adorable
-
centril
muvlon: honestly, I can live w/o slice patterns - custom derive is so important tho
-
groks
my dog tried to steal it
-
marmalade_
hello, question: how should one import an external crate for use in a module?
-
marmalade_
ie: i have a function in a module that uses yaml_rust to read a config file
-
muvlon
centril, yeah, it's 100% QoL, whereas custom derive is essential
-
groks
marmalade_ pull it in on main and use ....;
-
marmalade_
groks, sorry, ....;?
-
groks
specifically the calls you're trying to use
-
muvlon
marmalade_, all "extern crate" declarations need to go in the crate root
-
groks
muvlon thank you
-
centril
muvlon: custom derive is also about QoL - just that it improves it so much for a bunch of traits
-
groks
for clarifying
-
insaneinside
muvlon: "need"? Not "need"! That's the convention though.
-
marmalade_
muvlon, the crate root meaning main.rs?
-
groks
yes
-
marmalade_
tytyty
-
muvlon
insaneinside, really? it just errors when i put it anywhere else
-
groks
where the main part of the application lives
-
groks
main, default, core, blah blah blah
-
marmalade_
okay that makes a lot more sense lol
-
muvlon
oh it's the mount point thing rearing its ugly head again
-
marmalade_
i took it out of that and put it in the mod and got a crap ton of errors
-
groks
muvlon you're hitting that?
-
marmalade_
thx muvlon, groks
-
groks
not a problem
-
insaneinside
`extern crate foo;` brings the name `foo` into scope at the current location
-
muvlon
i guess i must have been, since apparently it's fine to have "extern crate" in a submodule
-
muvlon
it's like mounting that namespace at the current node in the namespace tree
-
insaneinside
but in `use PATH`, `PATH` is *always* relative to the crate root!
-
groks
im sitting here watching how engines are fabricated
-
groks
muvlon ohhhh
-
groks
insaneinside also good points
-
muvlon
insaneinside, yes, very weird
-
groks
some of that stuff drives me bonkers coming from other languages
-
muvlon
it drives me less bonkers than having to deal with headers
-
groks
ugh
-
groks
don't get me started on that
-
groks
lol
-
muvlon
but when i started out i flat out gave up on modules for like 3 months and put everything into lib.rs
-
groks
I've done linux kernel patching in the past and making patchsets in my less sane gentoo days
-
groks
rust makes me feel at home
-
muvlon
C has no namespacing at all though
-
muvlon
it's like macros but for everything
-
centril
groks: PS: torvalds doesn't hate Rust unlike Java & C++; so RIIR linux?
-
groks
if there was an MTG card for it, it'd be STRESS -10 tap for stress defence
-
groks
centril lol
-
muvlon
centril, [citation needed]
-
groks
if he hasn't said anything yet, he hasn't looked at it.
-
groks
and when he does, oh god will he light up the ML
-
» centril goes and looks for the link he knows he read a while back
-
groks
lol
-
groks
linus always has a hot flick to throw out, comment wise
-
muvlon
i will continue believing torvalds hates anything but C and perl until shown otherwise
-
groks
muvlon i sort of agree
-
centril
let's move to #rust-offtopic?
-
groks
I love C and ASM
-
groks
centril sounds good
-
emerentius
perl?
-
emerentius
that seems so weird
-
cja
On windows do people typically use powershell for rust work?
-
cja
I'm prodding vscode to get rls working, but it's not seeing my nightly toolchain. Not clear where logs are stored yet
-
emerentius
that varies quite a bit probably, I used bash that git installed
-
marmalade_
hallo is me again, what is the best way to get sort of like - a multiple return situation from a function
-
marmalade_
ie: i have a function which reads from a yaml file which is a config file
-
marmalade_
and i want to be able to pull things from that function, so like - for example say a server name, a port number, etc etc
-
muvlon
make a struct that stores those things and return that?
-
muvlon
like `struct Config { server_name: String, port: u16, ... }`
-
cja
ah seems like my nightly lacks rls right now
-
marmalade_
muvlon, oh yeah, that makes way more sense lol ty
-
cja
ah there we go, got vscode using rls stable and now I can see types and such
-
cja
That's a great help with learning
-
m4b
when i type in "elf" into docs.rs, my crate, goblin, which has elf in keywords, as well as description, doesn't even rank. however, many completely unrelated projects do. its kind of annoying. similarly for pe and mach-o; it looks like the search is literally doing string submatches in the crate name which is... not great?
-
cobrand
so as awesome as docs.rs is, it's in no way an official rust thing
-
cobrand
it's merely implemented by the community
-
cobrand
crates.io however if official
-
cobrand
is*
-
marmalade_
err sorry could anybody maybe take a look at
glot.io/snippets/exenx3o6o2 and tell me how i should be returning this information, or if i'm doing this all back asswards?
-
marmalade_
its the config file function setup i was talking about earlier
-
marmalade_
right now the only thing being returned is a token, which is a string, but i'm going to likely add more things later
-
marmalade_
but basically in main.rs i want to be able to pull that data like config.token or whatnot
-
marmalade_
if that makes a lick of sense
-
Mutabah
marmalade_: Shouldn't `read_config` return `Config`?
-
marmalade_
Mutabah, isn't it?
-
Mutabah
No, it isn't
-
marmalade_
how should it be written so it does?
-
Mutabah
marmalade_: you need to specify in the function defintion/signature what it returns - in this case `fn read_config(filename: &str) -> Config`
-
marmalade_
ahhhhhhhh
-
marmalade_
ty ill try that right now
-
thenewwazoo
what in the world does `match self.0 {}` do in a function that returns an Option<>?
-
Mutabah
And then where you have `let result = Config { ... }` you can do `return Config { ... }` (or, since it's the last statement, just `Config { ... }`
-
thenewwazoo
(I'm specifically looking at wasm32's fs libstd impl for Iterator
-
Mutabah
thenewwazoo: Depends on what `self` is?
-
Mutabah
thenewwazoo: The .0 is "tuple indexing" - Most likely the type is something like `struct Foo(Bar);`
-
thenewwazoo
it's kind of a weird scenario
-
Mutabah
thenewwazoo: In that case, `match self.0 { ... }` is matching the first (and only) field in the struct
-
thenewwazoo
right, the type here is, I think, something like `struct Bar(Void)` where Void is `enum Void{}`
-
Mutabah
thenewwazoo: Aaaah :) So, that type can never actually exist
-
Mutabah
(because Void can't exist at runtime, it has no variants)
-
thenewwazoo
right
-
thenewwazoo
so what's the objective?
-
Mutabah
The match is the way you write a function that operates on that non-existent value (which should never be able to be called, because that would require that non-existent type to exist)
-
Mutabah
It's a trait impl, right?
-
thenewwazoo
yeah
-
thenewwazoo
for Iterator, in this case
-
Mutabah
So, it's implementing that trait on this non-constructable type. I don't know _why_ it is, but odds are something needs it
-
thenewwazoo
the answer might be "because an attempt at instantiation should fail spectacularly"
-
thenewwazoo
which makes it hard to follow :D
-
thenewwazoo
this is, specifically, in src/libstd/sys/wasm/os.rs
-
marmalade_
okay so i'm now running into an issue trying to pull that data in main - the compiler is complaining that "field token of struct Config is private"
-
marmalade_
-
Mutabah
marmalade_: You can make a field public by putting `pub` before the name in the struct definition
-
marmalade_
oic so i have to explicitly define the uh
-
marmalade_
fields within a pub struct as pub?
-
Mutabah
Yes.
-
thenewwazoo
hm, so why does `match self.0 {}` as the only statement in a function that returns an Option still compile?
-
marmalade_
awesome thanks!
-
thenewwazoo
wouldn't that return ()?
-
Mutabah
marmalade_: because although the struct is pub, it might have something private
-
Mutabah
thenewwazoo: it compiles because it's effectively a diverging statement - like an infinite loop
-
thenewwazoo
curious.
-
sfackler
thenewwazoo: every arm of the match returns an Option :P
-
marmalade_
Mutabah, i see
-
Mutabah
sfackler: Good way of putting it :)
-
marmalade_
well damn its workin now!
-
thenewwazoo
sfackler: I suspect your answer is deeper than I'm grokking
-
Mutabah
thenewwazoo: That match has no arms, which is ok, because the type it's matching has no alues
-
Mutabah
thenewwazoo: Since there's no arms, it doesn't return a value (not that it returns no value - aka ())
-
thenewwazoo
oh right I guess that's true
-
thenewwazoo
this is like a Rust koan
-
thenewwazoo
what Option do you get when you match no arms? mu.
-
scottmcm
`!`
-
Mutabah
Well.., it's !
-
Mutabah
thenewwazoo: This isn't just something for Option, it works for _anything_
-
thenewwazoo
oh, so when you're implementing a trait you can't redefine the signature, so that's a way to force it to !?
-
thenewwazoo
you can't say impl Iterator for Foo { fn next(&mut self) -> ! ... because Impl requires next() to return an Option, for example?
-
Mutabah
Kinda
-
thenewwazoo
so if I manage to try to call that code (which I can't even replicate in the playground :D), do I get an abort or a panic?
-
Lokathor
the other day i talked with some folks about if requiring Copy was the only way to check for !Drop
-
Lokathor
-
Mutabah
thenewwazoo: If you soemhow manage to call taht code, you get UB
-
thenewwazoo
Mutabah: iiiiiinteresting
-
scottmcm
thenewwazoo: if you make a value of a type that has no valid values, you invoked UB somewhere
-
thenewwazoo
and if I try to instantiate a `struct Foo(Void)`, I should get a compiler error?
-
scottmcm
thenewwazoo: try it out.
-
Mutabah
thenewwazoo: How would you do that? :D
-
scottmcm
Lokathor: that's not part of the type system, though; you can't bound your generic on it
-
thenewwazoo
hahah well, yes, how would I? but there it is in libstd :D
-
Lokathor
sure, you'd have to assert on it at runtime
-
Mutabah
thenewwazoo: It exists as a type... but that type has no values
-
Lokathor
(and also it says that if it's non-Copy and non-Drop it can pick either answer)
-
thenewwazoo
-
thenewwazoo
this is as close as I can get, and it predictably fails
-
thenewwazoo
fails to compile, I mean
-
thenewwazoo
so in the context of libstd, this looks like a way to say "you cannot create a Bar for this target, even though you can elsewhere"
-
thenewwazoo
a way to force that to indeed be true
-
thenewwazoo
that's cleverer than returning None and hoping someone notices
-
thenewwazoo
thanks for the insight, Mutabah and scottmcm :)
-
thenewwazoo
okay, now that I understand this, this is a _super_ nice solution
-
scottmcm
`!` is an awesome thing to have in the type system :)
-
thenewwazoo
well, my early attempts at "you cannot have an AnonPipe", for example, was to always return an Err or None, and occasionally panic
-
thenewwazoo
but being able to say "AnonPipe is not a thing that can exist" whilst still defining it is _reeeally_ clean
-
» thenewwazoo illuminated.
-
Mutabah
scottmcm: Yeah. It's a pain in the rump to make work with typecheck (because ! can become anything), but it's a wonderful feature for a user
-
Lokathor
is there a way to make error output from compilation more compact?
-
Lokathor
ideally, "filename:line:col: error: message", one per line, none of that code block stuff to show a preview
-
Mutabah
Lokathor: What for/
-
Lokathor
i want to see more errors at once and i don't want to make my terminal taller?
-
scottmcm
Mutabah: it's harder than the other random coercions? Interesting.
-
Lokathor
Mutabah, the preview is usually useless except with specific kinds of errors
-
Lokathor
ditto with warnings
-
marmalade_
is there a way to figure out why rust can't find a file?
-
Mutabah
scottmcm: Plays in with inferrence to a greater degree
-
Mutabah
marmalade_: rustc? or user code?
-
marmalade_
erm - not sure, all i know is that the config file is in the same directory as the binary file, and when i run it it says it cant find it even though in the code it's pointing to ./config.yaml
-
marmalade_
"thread 'main' panicked at 'Couldn't open ./config.yaml: entity not found', /home/marmalade/Documents/discord-qdb/src/yconfig.rs:18:19
-
marmalade_
"
-
marmalade_
thats the full error
-
Mutabah
marmalade_: That's relative to the directory in which you run the binary, not nessesarily the directory of the binary
-
marmalade_
i'm also running it from that directory
-
marmalade_
is there a better way to reference it, maybe?
-
marmalade_
-
marmalade_
^ the code
-
marmalade_
the reading is done from that code, which is a module
-
Mutabah
So if you do `ls` it shows `config.yaml`?
-
marmalade_
yeah
-
Mutabah
And then you do `./discord-qdb` and you get that error?
-
marmalade_
yeah
-
marmalade_
the only thing i can think is that i've messed up with the string or something
-
marmalade_
because i'm hopping back and forth between String and &str i think
-
marmalade_
-
marmalade_
whoops
-
marmalade_
"let config = yconfig::read_config("./config.yaml");"
-
marmalade_
thats in the main.rs
-
marmalade_
then
-
marmalade_
" let mut client = serenity::Client::new(&config.token, Handler);"
-
Mutabah
try with `strace ./discord-qdb` just as a quick check
-
Mutabah
Maybe something is changing the directory?
-
Mutabah
However, that should work. The string stuff shouldn't be a problem
-
marmalade_
-
marmalade_
the strace
-
marmalade_
uhh the error also says to run it with ah
-
marmalade_
RUST_BACKTRACE=1
-
Mutabah
yes, that's because you used panic! (which is intended for fatal program errors that require a backtrace)
-
marmalade_
ahh
-
Mutabah
The path looks sane in the strace and there' no mention of changing directory... are you sure you're running from the right place?
-
Mutabah
and right capitalisation?
-
marmalade_
i mean ill check again
-
Mutabah
if you can't find it, run the following : `ls` `./discord-qdb` and paste the entire shell output (including the commands)
-
marmalade_
okay so it looked identical, so i tried changing the file to configuration.yaml and the call to ./configuration.yaml and now it seems to see the token but crashed with a diff exception
-
marmalade_
which is weird
-
marmalade_
maybe its because i use "config" in the code or something?
-
marmalade_
not sure
-
marmalade_
although looking at this exception it doesnt make much sense either, because the println i have to confirm it pulled the token string prints the right thing
-
Mutabah
No, but might have been capitalisation or a space or something similar
-
marmalade_
i mean its possible i moved the file around a couple of times
-
marmalade_
oh my od
-
marmalade_
god
-
marmalade_
i have brain damage
-
marmalade_
i totally just dumped the string into the yaml file
-
marmalade_
and didnt write Token: <token>
-
marmalade_
laugh at me
-
sbl
Hello :) How can I dereference i32? In the past I just used the `.abs()` fn for ids, but that, for sure, will not work with negative numbers. So any suggestions? :)
-
cjm
hi sbl, I don't quite understand your question. Are you asking how to use an i32 as an index?
-
emerentius
or do you have references to i32? &i32
-
sbl
cjm: emerentius: I have structs in a BTreeMap and I need to dereference an i32 value of a referenced struct.
-
emerentius
dereferencing is an operation you do on pointer types so I'm still not sure what you want
-
emerentius
can you show code?
-
sbl
Sorry, I will write a playground. Just a mom
-
sbl
-
emerentius
easy: don't
-
emerentius
those are values already
-
cjm
sbl: If you remove the * your code works. i32 is Copy, so you get the value for free just by referring to the field
-
sbl
Argh. Yes. That's strange. Not really strange. But I have to check, why this is in my local code not the case.
-
sbl
Hmm. Just works. Dunno, what I wanted to do in that parts of code and why I called the `.abs()` fn there. Thanks so far, @emerentius @cjm
-
kiuma
hi, I want to call the same instruction n times and get the value returned by the last iteration. I could solve this problem with an iterable function, is there another way ?
-
oli_obk_
kiuma: std::iter::repeat(()).take(n).map(|()| instruction()).last().unwrap() // there's probably a more sensible way
-
oli_obk_
kiuma: I'd personally write `for _ in 1..n { instruction() } let value = instruction()`
-
emerentius
0..n
-
emerentius
or you'll have n-1 iterations
-
oli_obk_
emerentius: no, that's one too many
-
emerentius
n is not included
-
oli_obk_
n times, value of the last iteration
-
oli_obk_
1..n runs n-1 times
-
emerentius
right, didn't read properly
-
oli_obk_
then again... trying to be overly clever is a recipe for disaster
-
oli_obk_
maybe not use the 1..n thing
-
emerentius
expected saving into a variable inside the loop
-
kiuma
oli_obk_, oh thanks I like the for trick, I didn't think about that trick
-
tilpner
kiuma - repeat_call(instruction).nth(n)
-
tilpner
(Needs itertools)
-
kiuma
tilpner, thx but I need it just for wring my tests
-
tilpner
Your tests can be pretty too :c
-
kiuma
:)
-
kiuma
yep, sold
-
pingzing
Is it possible to pre-compile a crate, and point cargo to that precompiled crate, but only for a specific target?
-
pingzing
(i.e. precompile openssl-sys for ARM, then if any dependencies need openssl-sys for ARM, they use that precompiled crate?)
-
kiuma
hi, I can't figure out how to write this
play.rust-lang.org/?gist=a9cd9a4870…ec0ac89dc1ba71618a49&version=stable with a loop. Can anybody help me please ?
-
lvkm
kiuma: you want to use MyStruct in `for item in my_struct {..}` ?
-
killercup
-
kiuma
killercup, thx I try this in my test
-
BertP
i'm confused about parsing syn::TypeTuple; say i have parsed one from this exact string "(A, B, C)" .. what operations are needed to get each referenced type?
-
BertP
i'm already iterating over syn::TypTuple.elems, but i don't get the correct way of parsing the syn::Type enum
-
BertP
also, i'm trying to print typetuple through the Debug impl, but it tells me Debug is not implemented.. but the docs say it is (i'm already compiling with 'full' feature)
-
newpavlov
it looks like doctests ignore RUSTFLAGS envvar, is it intended?
-
Yoric
There's apparently still some stuff I don't understand about `&'a mut`.
-
Yoric
-
SpaceManiac
Yoric: &mut T isn't Copy, Self is &mut T, so &self is &&mut T, a reference to a non-copy type, which you cannot dereference
-
Yoric
Ah, right, it itn't copy.
-
Yoric
It isn't even Clone, I assume.
-
Yoric
Ok, that makes sense.
-
Yoric
SpaceManiac: Thanks.
-
Yoric
pnkfelix: Would you remember where the AST-walking macros are defined in the compiler?
-
pnkfelix
-
pnkfelix
-
Yoric
pnkfelix: Thanks.
-
algesten
Why does the Read trait so much? I mean shouldn't it just read some bytes and that's it. Why things like `read_to_string`, `by_ref`, `chain`, `chars` etc. Feels like these things ought to be a higher level. Lots of convenience fluff to impose on someone trying to fulfill the trait, no?
-
SpaceManiac
algesten: those all have default implementations
-
algesten
oooooh :D
-
algesten
@SpaceManiac thanks! I totally forgot you can do that in Rust xD... Rust is awesome!
-
Guest0
Does Rust tie in with any functions-as-a-service frameworks at the moment? There's a discussion at
news.ycombinator.com/item?id=16157430 about a new framework called 1backend, but it looks like it has support for Go and Javascript right now.
-
nox
What's functions-as-a-service..?
-
Aaronepower
nox: Very simple/stripped down backend services.
-
killercup
nox: i imagine something like awe lambda, it basically starts a process whenever something like "http request" happens
-
tilpner
CGI, but with containers instead of processes :/
-
tilpner
(And apparently a need to add support for every language individually?)
-
canadaduane
I'm not sure if it's necessary--OpenFaas seems to use STDIN/STDOUT for process intercommunication. But maybe some frameworks offer things like type safety with language integration?
-
nox
What
-
lachlansneff
I mean, I guess that could work.
-
lachlansneff
Pipe 1/2 of a child process into something in our process
-
est31
Mutex<RefCell<Option<Box<
-
est31
lol why do I need so many levels of nesting ./
-
est31
my fault
-
albel727
RefCell seems redundant
-
albel727
Mutex<RefCell<>> looks like the first thought attempt to wrongly invent RwLock
-
est31
oh nice
-
est31
thanks for that
-
» est31 has one level less of abstraction
-
est31
there is a difference though
-
est31
RwLock only impls sync if the inner type is sync
-
est31
but luckily my type is sync
-
albel727
well of course
-
albel727
but it's either plain RwLock or plain Mutex. RefCell is redundant either way.
-
est31
how so? I've thought mutex doesnt let you mutate the inner value
-
albel727
why wouldn't it?
-
est31
hmm wrong
-
albel727
holding a lock means you're the exclusive owner. so there's DerefMut of course.
-
albel727
(well, one could imagine in general some convoluted cases when you actually do need Mutex<RefCell<>> but I'd find it hard to come up with one.)
-
rubdos
Wasn't there a way to go from `Iterator<Item=Result<A, B>>` to `Result<Iterator<Item=A>, B>`, somehow
-
rubdos
or am I thinking about something else?
-
steveklabnik
rubdos: collect
-
steveklabnik
it doesn't go to result<iterator though
-
steveklabnik
it gives
-
steveklabnik
result<collection<A>, b>
-
rubdos
that'd require O(n) storage, no?
-
rubdos
or can I somehow collect into an iterator? :'-)
-
rubdos
(I find this difficult to search on Google)
-
steveklabnik
dunno
-
rkruppe-phone
Since it needs to return Err if any element is Err, but also needs to yield all the values of the iterator if they're all Ok, there is no way to avoid the buffering
-
rubdos
sounds fair, yes
-
rubdos
Then, is there some way to go from `Iterator<Item=Result<A, B>>` to `Iterator<Item=A>`, *returning* in the function when something goes Err(.)?
-
rkruppe-phone
Possibly, depending on what semantics you want for sequences like OK, Err, OK, Err, ...
-
rubdos
Right, I get that what I'm after has no generic implementation, thanks :-)
-
rubdos
I'll have to call collect at the end of the thing in any case, so I'll go with that
-
rubdos
I can just defer Result to the very end
-
rkruppe-phone
Yeah usually it doesn't matter
-
upupup
i have a large enum with associated data in another crate that i'm trying to write a match statement for. is there a way to have something similar to a macro that reads the source and generates the match arms without having to write each by hand?
-
mib_bhgc8x
Hi guys, i have a question for you
-
Lnavry
so ask
-
mib_bhgc8x
I'm trying to do callback with C library
-
mib_bhgc8x
But they are async
-
mib_bhgc8x
I'm registering them but they a never triggered
-
mib_bhgc8x
I read that they maybe on another thread so they have to "join" the current channel
-
mib_bhgc8x
In the rust book, in the FFI section they say that I should use channels
-
mib_bhgc8x
-
mib_bhgc8x
But I can't find a decent example on the internet
-
albel727
if the callbacks are never triggered then it's not a problem of threads or whatever.
-
albel727
at the very least, a println!() in callback should print in any case. don't bother with channels or anything until you have at least that.
-
Rantanen
-
durka42
Rantanen: unfortunately no
-
Rantanen
Having a trait define a default implementation for a function and then calling that default implementation from the impl of a struct.
-
Rantanen
:<
-
durka42
except pulling out the default impl to a method or something
-
Rantanen
Unfortunately that default impl is in syn.
-
Rantanen
dtolnay: Bad! *Hides*
-
Rantanen
Time to copy paste it I guess. :)
-
Rantanen
dtolnay: (On the other hand, <3 for having the visitor traits built in)
-
albel727
well one can always implement a newtype delegate, I guess, that would have the unoverriden method() but call out for other methods in your struct.
-
depesz1
hi. i'm trying to return string from function, and I fail. what did I screw up:
share.riseup.net/#X_y3E8kaQ7pfaKQIEiEcZg ?
-
durka42
hey depesz1, you want to return &'static str (if it's always a string literal) or String (if it can be generated at runtime)
-
steveklabnik
depesz1: did you save?
-
steveklabnik
look at the error vs the text
-
steveklabnik
they have different signatures
-
steveklabnik
the text looks like it fixes the error
-
depesz
if I tried to return String, I'm geting: expected struct `std::string::String`, found &strm on the line that returns value.
-
steveklabnik
yes
-
depesz
what can I do about that?
-
steveklabnik
well
-
steveklabnik
you can do what durka42 said
-
steveklabnik
and return &'static str
-
steveklabnik
or, you can add .to_string() calls on the end of each of those string literals, and return String
-
depesz
sweet, thanks a lot.
-
durka42
-
depesz
-
depesz
but thanks for the links anyway
-
Rantanen
dtolnay: Actually a real question concerning syn. parse_str( "#[attribute]" ) doesn't seem to work as Attribute doesn't impl Synom. Is there a way to generate 'Attribute' other than building it as a struct by hand?
-
steveklabnik
depesz: ah, chapter 4 digs into the differences here!
-
steveklabnik
so you're close :)
-
Rantanen
I guess parsing "#[attribute] fn foo() {}" and just stealing the attribute from it would work, but that sounds a bit cludgy. :)
-
depesz
yeah, i figured, but wanted to do something "cooler" than simple loops and printing integer.
-
callym
Rantanen: I think you could generate the bits you need seperately (as a syn::Path, syn::ExprParen), then just `let attr: syn::Attribute = parse_quote!(#[#path#paren])`
-
Rantanen
callym: 'parse_quote!' return type must implement Synom trait. syn::Attribute doesn't do that.
-
callym
Rantanen: I think there's a special case for syn::Attribute? I'm doing `item_impl.attrs.push(parse_quote!(#[attribute]));` and it's working here
-
callym
I've got a proc macro that goes on a impl block and rewrites some types, but if the type exists in a attribute that's handled by a different proc macro, I get "cannot find attribute macro in this scope"?
-
callym
if I change the second macro to not be touched by my macro, then it works fine
-
urschrei
Is there a standard pattern for passing something mutable into a Rayon parallel iterator? I feel like what I want here is an Arc<RwLock<_>>, but Google is failing me:
play.rust-lang.org/?gist=7cd464bd36…78f70c90fccc27a0d1b&version=nightly
-
napoleon
Is it legal to use trait associated consts off of a generic like this?
play.rust-lang.org/?gist=de458028c5…33da316b071d0c6cd922&version=stable
-
misdreavus
urschrei: if you're only using a counter, you may be better off with an AtomicUsize/AtomicIsize or the like
-
misdreavus
urschrei: otherwise yeah, you probably need a Mutex which you send a & of into the per-item closure
-
albel727
-
stephaneyfx
!gh 42863
-
rustbot
[Issue 42863] <open> Generic associated consts can't currently be used to parameterize fixed array lengths <
rust-lang/rust #42863>
-
stephaneyfx
albel727 beat me to it :p
-
albel727
:P
-
napoleon
Thanks.
-
badmann
simple profiling tools?
-
Lnavry
what about them?
-
durka42
perf
-
kiuma
hi, is there something like setup and teardown for tests in rust? I need to start an hyper sever and stop it when all tests are terminated
-
urschrei
misdreavus: I really do just need a simple counter. Will have a look at Atomic{U, I}size. Thanks!
-
durka42
kiuma: nothing built in. one trick is to use a lazy static and do your setup there. on nightly you can use {!crate stainless} (dunno if it's updated lately)
-
rustbot
stainless (0.1.12) - Organized, flexible testing framework. ->
crates.io/crates/stainless <
docs.rs/stainless>
-
dtolnay
Rantanen: the default implementations for visitor methods are exposed in
docs.rs/syn/0.12/syn/visit/index.html
-
misdreavus
urschrei: cool! once you get your atomic ready, you can just send a & of it to your per-item closure, since all the update functions only need &self
-
dtolnay
Rantanen: this page covers parsing attributes
docs.rs/syn/0.12/syn/synom/index.html
-
dtolnay
Rantanen: but it is something like Attribute::parse_outer.parse_str(s)
-
badmann
Yaniel: i'm looking for them
-
kiuma
durka42, it seems a bit tricky to test things like http servers
-
durka42
agreed
-
Rantanen
dtolnay: Might follow with a PR to include that in the Attribute docs as well. Would neve never thought to look up something specific like attribute parsing from the synom docs.
-
Yaniel
badmann: AFAIK you can just use the same ones as you'd use for C
-
Yaniel
and then there's stuff like the flamegraph crate
-
Rantanen
And same concerning the visitor default methods. The trait docs could use an example for delegating to the default methods.
-
dtolnay
thanks Rantanen, i filed issues to follow up
-
Rantanen
dtolnay: Now that you're there.. maybe.. you might be able to tell me what's going on and how to fix it.
-
Rantanen
dtolnay: This fails: #[my_attribute] fn foo() {}, where my_attribute is quote!( #[test] fn foo() {} )
-
Rantanen
This succeeds: quote!( #[test] #orig_fn )
-
Rantanen
So I'm guessing this has something to do with the call_site/def_site hygiene?
-
Rantanen
Er. Now quote_spanned!(span=>, where span is ::call_site() works too.. :|
-
dtolnay
are you building with --features proc-macro2/nightly?
-
Rantanen
Yeah
-
dtolnay
yes it is a span difference
-
dtolnay
`quote!( #[test] fn foo() {} )` exposes foo to the "def site" only meaning nothing from the call site can see it
-
Rantanen
My full example does some ident-switching and cloning, so that must be causing the difference.
-
Rantanen
Because the ::call_site() isn't working in the non-minimal example. Trying to reproduce it now.
-
dtolnay
`quote!(fn #ident() {})` will keep whatever the span is on `ident` so it's probably def_site
-
Rantanen
There we go. If I do test_fn.ident = new_ident, then it fails with unresolved bits and cannot find value in module errors.
-
Rantanen
So I need to set the new_ident (which is created with format!(..).into()) into call_site I guess.
-
dtolnay
-
Rantanen
I'm pretty sure the span stuff and hygiene is one of the most complicated aspects of proc macros. :x
-
Rantanen
Mainly because it feels a bit arcane - especially the def_site in the context of proc macros.
-
badmann
Yaniel: do you have any suggestions apart from flamegraph? i tried cargo-profiler but the names from callgrind/cachegrind are all mangled. perf has much better output, but i still can't see any info about my rust functions. flamegraph is not that useful
-
Yaniel
you could do what xi does with chrome perf tracing
-
Yaniel
depends on what you want to profile though
-
badmann
just wanted some info on my simple command line program. I figured cargo test and cargo bench are great and I wanted to see if it was possible to gather some more info to have a complete overview of performance
-
est31
is Xi usable yet as a daily driver
-
ptolemaus
how long did you take to get mut right automatically? I always miss mut at fn parameters and pointers and the compiler complains
-
est31
it was more or less easy for me, coming from c++
-
est31
but some rules are weird
-
est31
like when you say let foo = function_call();
-
est31
then another_function_call(foo)
-
est31
and another_function_call takes mut foo :Type
-
ptolemaus
i.e. you calla function which has &mut self param and you call that function but you miss the mut on &mut self on the calling fn
-
est31
then you dont need any mut here
-
ptolemaus
hard af
-
sogard
I'm trying to run two very simple benchmarks in callgrind. The only difference between the two is that one of them has more samples in arena.c:je_arena_tcache_fill_small, but the difference is quite small. Howeverm the difference in the benchmark time is noticeable, being around 2x slower.\
-
sogard
I would guess that the culprit is some extra heap allocations.
-
Rantanen
dtolnay: Got it working, thanks for the help with the spans. \o/
-
Rantanen
-
est31
Rantanen: which kind of pastebin is that
-
sogard
The issue is that I'm finding it very hard to find out where the difference lies in. I've tried flame graphs as well and I still can't figure it out. There seems to be no difference in heap allocation between the two benchmarks.
-
Rantanen
est31: It isn't. :|
-
Rantanen
est31: Pygmentize and my own server. It's not runnable anyway as it depends on extern crates so play.rust made no sense and didn't see the benefit of throwing it on an external service.
-
est31
ok
-
Rantanen
(Plus I wrote it there so I could just run pygmentize -o ~/public_html from the command line. :p)
-
forgottenone
is there function or method to convert generator into iterator
-
mbrubeck
-
mbrubeck
forgottenone: I hope, eventually, generators will automatically implement Iterator
-
sogard
Anyone with a bit of profiling experience?
-
albel727
there are at least two sane ways to implement iterator from a generator
-
albel727
(returning and not returning Complete as the last element of the sequence)
-
albel727
the crate above seems to choose "not returning".
-
mbrubeck
and it only works for Generator<Return=()> so it won't silently drop a useful Complete value
-
albel727
I don't see any such condition there
-
cahoots
hi, if i mark an enum, MyEnum, with "#[repr(u32)]" and then i expose a fn via FFI with a signature "my_fn(my_enum: MyEnum)", and the C header for it is "my_fn(uint32_t my_enum)", will that work?
-
mbrubeck
-
mbrubeck
cahoots: Yes, but note that it is undefined behavior to call that function with an out-of-range value
-
albel727
I've been deceived by old docs. no such condition there.
docs.rs/gen-iter/0.1.2/src/gen_iter/lib.rs.html#49
-
mbrubeck
(one that doesn't match one of the enum variants)
-
cahoots
mbrubeck, makes sense thanks
-
albel727
(and even then, what if your items are also () :P)
-
mbrubeck
albel727: Ah, looks like it was a later change.
tinaun/gen-iter #1
-
bluss
what's a simple 2d graphics & keyboard events crate for rust. piston requires compiling some silly amount of crates
-
forgottenone
mbrubeck: thanks, i hope so too, Python generator-iterator model feels so intuitive
-
mbrubeck
bluss:
github.com/ggez/ggez might be good if you want something that is somewhat "batteries included"
-
mbrubeck
bluss: For something with fewer dependencies, you might need to put together your own combo of glutin + [2D rendering lib of your choice]
-
mbrubeck
bluss: Or use sdl2, which ggez is built on top of.
-
albel727
so I conclude that it's better to simply have two explicitly different generator adapters. one that would discard the last value, no matter what it is, and one that wouldn't discard the last value, provided that Yield and Complete have the same type.
-
albel727
() limiting looks like half-measure.
-
albel727
maybe just have one generator adapter that would yield GeneratorState as items, and just filter that depending on what you need.
-
albel727
filter_map, even
-
bluss
mbrubeck: thanks for the suggestion, but yes, I'll look for something smaller than ggez
-
TyOverby
mbrubeck: does sdl2 have a safe API?
-
mbrubeck
TyOverby: looks like it
-
TyOverby
that's neat; sdl2 was a pretty fun to play with when I was learning C
-
acmcarther
on the topic of sdl2: does it work out of the box for vulkan? I was trying to use it with vulkan, but was hitting issues and I couldn't tell if it was from lack of support in the rust sdl2 lib, or build system weirdness on my end.
-
acmcarther
I'm compiling sdl2 from scratch and not using cargo for various reasons
-
Rantanen
Uh. Is there a way to update README.md on crates.io without publishing a new package version? :|
-
steveklabnik
no
-
steveklabnik
releases are immutable
-
dbrgn
is there a way to debug deadlocks (when using tokio)? maybe with rust-gdb?
-
dbrgn
(mutex)
-
Rantanen
Not sure if the README.md should be immutable though. Fixing typos in the documentation shouldn't require a version increase in the actual package.
-
albel727
>tokio >mutex
-
Rantanen
But I can accept it being simpler with everything being immutable instead of making exceptions. :)
-
talchas
dbrgn: you can do that normally, yes
-
est31
Rantanen: the same could be said for fixing typos in the documentation or fixing bugs in the program code :)
-
talchas
there isn't any special help for it in displaying suspended futures or anything though
-
steveklabnik
Rantanen: typo fixes change the hash
-
steveklabnik
if you want repeatable builds, you need immutability
-
talchas
(but if you're actually using std::sync::Mutex and tokio, unless you're careful or using the Mutex specifically between separate Cores on separate threads, it's likely "don't use Mutex with tokio")
-
Rantanen
Ah, true the readme is included in the downloaded package.
-
steveklabnik
in theory, you could say that we'd store a mutable version of the metadata on crates.io
-
steveklabnik
and have it differ from the downloadable version, but that has problems
-
Rantanen
I'm just sad, because I've now went for two version bumps, just to get rid of the scroll bar:
crates.io/crates/ratcc D:
-
Rantanen
And I'm still failing. :x
-
steveklabnik
it happens :)
-
dbrgn
albel727: huh?
-
Rantanen
.. it's not there on Firefox. :|
-
dbrgn
talchas: but those suspended futures should still be on the stack, right? so I should find them with "bt"?
-
talchas
(Mutex lock suspends the thread and the entire Core with it; if you're expecting it to suspend just the future, you'll lose)
-
albel727
tokio is fundamentally incompatible with anything blocking. with very high probablility if you use a mutex, you're doing it wrong.
-
dbrgn
talchas: ah, of course :)
-
steveklabnik
it happens :)
-
steveklabnik
oops
-
steveklabnik
lol
-
talchas
dbrgn: no, "suspended" as I meant was more for "returned from and_then or something else like that and have not yet run"
-
dbrgn
albel727: the tokio based code might still have to interact with threads / pass values to other threads. of course, deadlocks are the consequence when not being careful.
-
talchas
that said, anything blocked on a Mutex will still show up
-
albel727
if they have to converse with other threads, then they should do it via future-ready channels.
-
talchas
perhaps more "suspended Tasks" is more to the point
-
dbrgn
albel727: through Remote, right?
-
dbrgn
(since channel::send returns a future)
-
forgottenone
is resuming to coroutines with value implemented, I mean equivalent of x=yield ... in python
-
talchas
doing it with the futures channels will avoid blocking all other futures while you wait for the other thread; if the other thread is in turn blocked on data coming from any other future, that's a deadlock source
-
talchas
if the other thread was just updating data entirely independently and the futures took whatever data was there via Mutex<Data>, that could be fine and less hassle than anything else
-
albel727
Remote is about spawning tasks on a core in a different thread. you can certainly do something like communication with that. but I had in mind something like using UnboundedSender from here
alexcrichton.com/futures-rs/futures/sync/mpsc/index.html
-
mbrubeck
forgottenone: I think it's planned but not yet implemented.
-
albel727
one can pass things into current generators via some shared variable, I guess.
-
albel727
but making resume take value seems like the obvious thing with a lot of prior examples. not sure why it wasn't implemented this way from the beginnig.
-
centril
Would a normal proc macro attribute on a function, like: #[proptest] fn test_add(a in 0..1000i32, b in 0..1000i32) { .. } require that `test_add` parse as a valid Rust function before the macro doing its work?
-
hdevalence
Is there a way to make a Vec whose initial storage is stack-allocated?
-
centril
Sergio: ^ maybe you know about the proc macro stuff?
-
hdevalence
What I'd like is a container that will not require a heap allocation unless the size grows too big, in which case it just does that
-
Sergio
Yes
-
mbrubeck
-
Sergio
centril: yes
-
centril
Sergio: oh that's a bit unfortunate :/ then that particular syntax wouldn't parse
-
mbrubeck
hdevalence: (`smallvec` works as you describe, and allocates on the heap if it grows too big for its initial capacity. `arrayvec` can't grow beyond its stack capacity.)
-
hdevalence
cool, thanks for the pointer!
-
centril
Sergio: hmm... what if the #[proptest] attribute is on the module enclosing the test_add function... could the proc macro be given the string for the module and do its macro on functions inside ?
-
Sergio
No
-
centril
crap :(
-
Sergio
Arbitrary tokens are only allows in macro! { .. }
-
Sergio
The rust source code must be rust source code
-
Sergio
You cannot change the syntax of Rust
-
Sergio
allowed*
-
centril
Sergio: Right... was just thinking that mod tests { <-- delimiter delimiter --> } could let me get away with the lexer stopping at { and } and just give the attribute everything inside
-
centril
hypothetically
-
Rantanen
centril: However "fn( a : foo!() ) { .. }" is allowed.
-
Rantanen
centril: "#[proptest] fn test(a: in!(0..1000i32)) { .. }" should go through I believe.
-
centril
Rantanen: is the expansion of foo!() done before or after proc macros?
-
Rantanen
After I believe, as the #[proptest] proc macro can alter it.
-
bluss
mbrubeck: sdl2 seems like the winner. At least it's easy to get started.
-
Arnavion
centril: You can have any arbitrary tts inside the attribute itself if that helps
-
centril
Rantanen: I guess #[proptest] fn test_add(a: in!(0..1000i32), b: in!(0..1000i32)) { .. } isn't as pretty, but it works at least
-
centril
Arnavion: thanks for the reminder =) but not really ^,-
-
centril
Rantanen: you could do things like #[proptest] fn test_add(a: usize, b: in!(0..1000i32)) { .. } which would be nice, then you can mix types and concrete strategies
-
Rantanen
centril: Yeah
-
SpaceNugget
Has anyone seen an example of integrating linefeed(preferably) or copperline with tui-rs? I don't really know where to start
-
Soni
is loop {} valid rust?
-
j`ey
yup
-
vurpo
I don't see why not
-
Arnavion
It's also sometimes how you implement panic_fmt for no_std
-
j`ey
LLVM doesn't like it though, there's an issue open for it
-
rkruppe
yeah that can really bite you
-
rkruppe
I once spent three hours or so tracking down a bug in a no_std crate that turned out to be due to LLVM optimizing out loop {}
-
Arnavion
Heh
-
steveklabnik
vurpo: in C, that's undefined behavior, hence Soni's question
-
j`ey
loop { unsafe { asm!("nop") } }
-
steveklabnik
actuallyl, is it UB, or just "can be optimized out"? i forget actually
-
centril
what... `loop {}` in Rust code can be optmimized out ?
-
steveklabnik
point is, in rust it's an actual inifite loop. or rather, once we got that bug fixed
-
steveklabnik
centril: no
-
steveklabnik
i was speaking of C
-
Arnavion
It's that the standard requires that every thread terminate, so infinite loops cannot exist
-
centril
steveklabnik: but there's no loop{} in C ?
-
j`ey
while(;;){}
-
centril
oh, that
-
steveklabnik
centril: "infinite loops with no side effects" is longer to type but teh same thing
-
Arnavion
which LLVM assumes is true of all languages it supports, not just C
-
steveklabnik
Arnavion: ah, ty
-
centril
steveklabnik: =P now I get it
-
steveklabnik
it's all good :)
-
misdreavus
that while loop is crying, won't you save it from its plight
-
centril
Y'all got me shit scared for a bit tho
-
rkruppe
steveklabnik: It's actual UB
-
sfackler
it can't be optimized out in modern C either, but llvm doesn't handle it properly
-
Arnavion
-
rkruppe
one of C or C++ has an exception for while(1) specifically so that's an LLVM bug
-
KiChjang
j`ey: you mean for(;;) {}
-
KiChjang
while(true) {} can work as well
-
j`ey
KiChjang: ya
-
nox
do {} while (1) for extra fanciness.
-
KiChjang
because everyone wants to do something while it's true
-
sfackler
ah yeah here we go
-
sfackler
-
sfackler
any loop that has a constant expression as its controlling expression should be handled "properly"
-
Sharlin
BTW, anyone else confused about this error every time?
-
Sharlin
16 | let x = [t, u]; | ^ expected type parameter, found a different type parameter
-
Sharlin
to me it reads that the compiler expects a literal type parameter there, not an expression of that type
-
Andlon
Er, how do I access "static" (unsure about the terminology, not tied to an instance) methods of a type in a macro? E.g. something like: macro_rules! print_maxval { ($int:ty) => { println!("{}", $int::max_value()); } }
-
steveklabnik
t needs to be a type parameter, yeah
-
j`ey
Andlon: it doesnt work?
-
steveklabnik
Sharlin: did you maybe mean [t; u]?
-
Andlon
jey, is your name hard to autocomplete on purpose? :P
-
j`ey
Andlon: yes
-
Sharlin
steveklabnik: no, I mean the array literal [t, u] where t: T and u: U
-
steveklabnik
ah, huh
-
Andlon
-
steveklabnik
well
-
steveklabnik
yeah the error could be better
-
talchas
Andlon: it's possible it will instead work if it's <$int>::max_value()
-
Sharlin
steveklabnik: the problem is really that T != U
-
steveklabnik
but like, arrays have to have the same type
-
steveklabnik
so T would ne.... yes
-
steveklabnik
right
-
talchas
if it's always one of the primitives then $int:ident will certainly work
-
Andlon
talchas, you're right!
-
steveklabnik
anywho yeah, seems good to improve that
-
Andlon
talchas, oh, u8 is an identifier and not a type? I'm confused
-
Andlon
or, er, both?
-
j_ey
both
-
Andlon
talchas seems to imply that only the primitives are both types and identifiers?
-
KiChjang
!u8
-
rustbot
playbot: macro_rules! u8 { (u8) => { mod u8 { pub fn u8<'u8>(u8: &'u8 u8) -> &'u8 u8 { "u8"; u8 } } }; } u8!(u8); let &u8: &u8 = u8::u8(&8u8); u8
-
playbot
8
-
talchas
Andlon: it's just that ident::foo() will work
-
talchas
but ty::foo() doesn't for some reason
-
Andlon
huh, I see
-
talchas
(because some types don't parse there? even though "but you know it's a type because MACROS" should really be sufficient disambiguation here)
-
Andlon
yeah, it's a little confusing to me
-
Andlon
but thanks for pointing me to the angle brackets! I tried all the other kinds of brackets before I asked here :P
-
talchas
yeah, <type>::foo is alternate syntax that you normally only use when type::foo would be ambiguous
-
talchas
(you can write things like <Vec<X>>::new() rather than Vec::<X>::new() and so on)
-
Andlon
talchas, I did not know that. Interesting!
-
Andlon
I mean, I've been using <Foo as Bar>::Something frequently, but never thought to use angle brackets without 'as'
-
Andlon
I'm still not able to generate function names in macro_rules!, am I?
-
est31
no
-
talchas
you could actually write concat_idents_cps!() now with proc macros
-
Andlon
talchas, I see. Hmm, I just want to generate some identical tests for the built-in integer types though, i.e. something like impl_uint_test!(u8), and it would generate #[test] fn u8_test() { }
-
Andlon
proc macro seems a bit overkill then..
-
talchas
concat_idents_cps!(macro:ident ! ( args:tt* ), x:ident,*) => macro!(xs_concatted, args*)
-
ambaxter
-
ambaxter
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
-
Andlon
talchas, I am not really sure what I'm looking at here
-
talchas
ambaxter: T: Eq + ?Sized
-
talchas
Andlon: someone could write a proc macro crate concat_idents_cps that does that
-
talchas
and then macro_rules macros could use it for things like this
-
Andlon
talchas, ah, I see. That... sounds useful?
-
ambaxter
talchas: will that also work for primitives? or do I need a separate function for that?
-
ambaxter
like &u8
-
talchas
yeah, someone wrote a compiler plugin that does it, but a quick crates.io search doesn't seem to show any others
-
talchas
ambaxter: that'll be fine
-
ambaxter
thanks!
-
talchas
(the compiler plugin used a very different syntax that's nicer but more fragile)
-
Andlon
I see
-
Sharlin
steveklabnik: ticket'd :)
rust-lang/rust #47499
-
Andlon
well, it seems like a very useful feature. I don't feel quite ready to take on that responsibility since I'm not so well-versed in macros, but I'd be happy to use something like that if someone publishes a crate with this functionality
-
steveklabnik
Sharlin: ty
-
Andlon
related but a little bit different: what if I already have a function name in mind and I want to generate a function body for it? I.e. something like generate_func!(my_function_name) would expand to fn myfunction_name() { } Can one do this with macro_rules?
-
sfackler
Andlon: yeah that works fine
-
sfackler
macro_rules! foo { ($name:ident) => { fn $name() { /* code here */ } } }
-
Andlon
ah, yeah, that worked directly
-
Andlon
for some reason I didn't expect it to. I thought I'd tried but I just looked at my code again and I had some angle brackets there
-
Andlon
sfackler, ok, that's great. Thanks!
-
Andlon
is "0u8" and "0 as u8" the same?
-
Andlon
specifically when used with numerical literals, I mean
-
Sergio
Yes
-
talchas
it's possible the latter will complain when in a const on stable? I forget
-
talchas
but in general, yes
-
talchas
playbot: const FOO: u8 = 0 as u8;
-
playbot
()
-
Sergio
talchas: How's that?
-
talchas
nah, even that works
-
talchas
Sergio: it's an expression, and I couldn't remember if as was on the whitelist without const_fn
-
Sergio
I'd be *gasp* shocked if {lit}u8 and {lit} as u8 were different in any context aside from parsing
-
Andlon
OK, thanks for confirming. I had a pretty hard time googling that
-
talchas
(as it happens, it works on 1.0, so yeah, it's always worked)
-
nox
playbot: const FOO: u8 = 256 as u8;
-
playbot
()
-
nox
playbot: const FOO: u8 = 256 u8;
-
playbot
error: expected one of `.`, `;`, `?`, or an operator, found `u8`
-
playbot
(output truncated; full output at
paste.rs/GWn)
-
nox
playbot: const FOO: u8 = 256u8;
-
playbot
()
-
talchas
playbot: 256u8
-
playbot
0
-
Sergio
Anyone know how to force `xargo` to recompile the sysroot?
-
j_ey
Sergio: change flags
-
Sergio
To what?
-
Sergio
I'm out of flags!
-
j_ey
delete .xargo? :P
-
Sergio
Yes, that's an option.
-
Sergio
Looks like Xargo doesn't properly detect changes to crates mentioned in Xargo.toml.
-
Sergio
Hmm.
-
j_ey
-
Sergio
Yes. That's exactly it.
-
Sergio
Thanks, j_ey.
-
Sergio
I'd actually read that issue before.
-
Sergio
Heh
-
juanpotato
Is it fine if I ask some stuff about tokio servers here
-
mbrubeck
juanpotato: yes
-
Sergio
Tokio!
-
Sergio
!tokio
-
mbrubeck
juanpotato: There's also
gitter.im/tokio-rs/tokio
-
Sergio
That's surprising.
-
juanpotato
I'll just ask here and move over there if I cant get a solution
-
juanpotato
Alright, I've been trying to find how to make a new tcp server in tokio. More specifically I want to make multiple tcp servers, some with and without ssl, and then some udp. All I'm trying to do is receive data and then store it and move on, for each of those connections. But as far as I can tell, there are a few different to make a server in tokio.
-
juanpotato
Not sure which one to even use or if I have to go a different route for each tcp, tcp ssl, and udp.
-
xrl
I am parsing a string and creating a new struct from borrows. I also take ownership of the string. how can I safely return a tuple of (String,ParsedData) with lifetime annotations? I only know how to do tick-a stuff when the function takes a ref and returns a ref. here's my code showing the parse method and my attempt at annotation:
gist.github.com/xrl/da0ece5accbe1211b84d5bea8b31c7a0
-
JuanPotato
oops, did I miss anything
-
mbrubeck
JuanPotato: nope
-
dcrewi
is there a quick and easy way to run tests locally compiled to 32-bit code?
-
Sergio
dcrewi: If your OS can run 32-bit binaries, and Rust supports a 32-bit target for your host, then yes.
-
Sergio
-
Rantanen
Wait, doesn't "cargo test --target <TRIPLE>" work?
-
Sergio
Rantanen: That's what the link describes.
-
Rantanen
Oh, nevermind. Thought it was a command line utility, crate or some such.
-
cschneid_
Say I'm using
doc.rust-lang.org/std/os/unix/net/struct.UnixListener.html -- and have the loop like it has in the code snippet, that spawns new threads per client. Is there any cleanup I need to do with those threads?
-
sedrik
Does anyone have a good example of parsing a json where the keys have varying parts in them (it's a semi strange API)
-
sedrik
Using serde ofc
-
Sergio
Varying parts?
-
talchas
cschneid_: not necessarily - each thread will exit fine when handle_client does
-
sfackler
cschneid_: what kind of cleanup are you worried about?
-
sedrik
I can make a defined list of the parts that varies (it's currency codes)
-
Sergio
What do you mean by varying parts?
-
sedrik
Sergio: like SEK:value, USD:value
-
cschneid_
sfackler, talchas: joining, or otherwise letting them die? What happens if/when they panic? Unwound and .. .forgotten?
-
talchas
if you want to be able to know when all the threads have exited or something, then you'll need to do something
-
Sergio
Like, sometimes you have one key, sometimes another?
-
talchas
cschneid_: that's fine
-
sedrik
depending on if the response concerns SEK or USD currency
-
sfackler
unless you hold onto the handle returned by spawn, the threads will be detached
-
sedrik
Sergio: yes
-
Sergio
Sounds like you want an enum, then.
-
cschneid_
talchas: awesome. I don't do enough low level thread stuff to know :)
-
sfackler
and run fine on their own
-
talchas
nothing in rust ever leaks problematically if you just do nothing with it
-
cschneid_
also, I'm really loving using rust. Thank you to everybody here, and everybody who documents & blogs & everything. Ya'll are great.
-
talchas
(that doesn't involve unsafe pointers, something named forget() with blatant warnings, etc)
-
sedrik
Sergio: That would work, but the trick is that only a limited number of them are valid depending on the context, like current currency trade value is X for currency C
-
Sharp
xrl: Do you have a test case that's contained in one file? I can tell you how to (for instance) add lifetime annotations to your type alias, but I'm not sure if that's where you're going wrong.
-
Sergio
sedrik: Maybe you can create a paste with some examples of things you want to parse.
-
Sergio
There's also #serde, by the way.
-
Sharp
Ah, wait, I think I see...
-
sedrik
Yeah I will see if I can create something small, hmm. Sounds like a good channel to join :)
-
xrl
Sharp: I think I would just push up my project and you could try compiling it. I've changed strategies to just owning the data but I'm happy to rewind to the borrowing mechanism.
-
voider1_
Hmmm, I still don't understand when you should use macros
-
Sharp
xrl: Okay, you can't do the thing you want to do without adding the lifetime somewhere in SyslogServer, AFAIK. Which isn't that bad in practice (you can generally make a wrapper struct and use PhantomData if you have to), but I believe it's needed.
-
voider1_
I was thinking about something, I had a method somewhere which basically calls another method, but just does some of the work for you. Would it be better to make that a macro?
-
Havvy
voider1_: When the boilerplate gets too much. E.g. derive macros. Or if you want to introduce new control flow constructs. E.g. if-chain
-
Sharp
I admit I can't remember why off the top of my head but I think it's because it's not clear *which* lifetime you actually mean.
-
Havvy
voider1_: Those should stay as methods -- LLVM can inline them.
-
voider1_
I see.
-
voider1_
Hmmz.
-
xrl
Sharp: I have seen some code in libraries that uses PhantomData... do you know any examples which show how to make the wrapper struct/ownership?
-
voider1_
Havvy, Only for that?
-
voider1_
Hmm, maybe as an surrogate for variadic functions.
-
Sharp
xrl: struct MyWrapper<'a>(MyStruct, ::std::marker::PhantomData<&'a ()>) will give you a wrapper of MyStruct that carries along the lifetime 'a with it, without any runtime overhead
-
Havvy
voider1_: That also works. Basically, use them as a tool when the base language doesn't suffice.
-
Sharp
Specifically that will give you a covariant 'a, which is usually what you want… there are other ways of getting other kinds of variance in there, if you need them.
-
voider1_
Havvy, Hmmm. I see.
-
xrl
Sharp: struct OwnedSyslogMessage<'a>(String, SyslogMessage3164<'a>, ::std::marker::PhantomData<&'a ()>)
-
voider1_
Havvy, I'm having a hard time figuring out when that would be.
-
voider1_
"Did I desing this badly or...?"
-
Havvy
It's kind of a rare thing to need to pull out.
-
Sharp
xrl: It's not SyslogMessage3164 that needs it
-
Sharp
It's SyslogServer
-
Sharp
But yeah.
-
xrl
so the message will carry a reference to the server?
-
xrl
struct OwnedSyslogMessage<'a>(SyslogMessage3164, SyslogServer<'a>, ::std::marker::PhantomData<&'a ()>)
-
Sharp
I don't think either the message or the server are referencing each other, are they?
-
Sharp
The 'a refers to some other daya.
-
Sharp
*data
-
xrl
the SyslogMessage3164 borrows from a String
-
Sharp
Nah, you don't need SyslogServer<'a> in your SyslogMessage at all, as far as I know.
-
Sharp
Yeah.
-
Sharp
Right, then the 'a just refers to the lifetime of that String
-
Sharp
Nothing else.
-
xrl
I just need to carry the String around as long as I want to use the SyslogMessage3164
-
Sharp
Right
-
Sharp
If you put the same 'a in the SyslogServerWrapper—just as a PhantomData—and don't change anything else, Rust will be able to keep track of the fact that they both outlive the String
-
Sharp
And then anything with that lifetime can naturally be used in any trait implementations for SyslogServerWrapper.
-
Sharp
If, on the other hand, they *don't* both outlive the String, you can't do this… but if that's the case it may not actually be safe in the first place.
-
xrl
they will never outlive the string. the parsed message is recombulated into JSON and then the message is forgotten.
-
voider1_
Havvy, Derive macros need an external crate, right?
-
Havvy
voider1_: As an implementation detail, yes.
-
voider1_
Hm.
-
Sharp
xrl: Then it's not immediately obvious to me that it's safe to talk about the Future type in general… Rust currently has some strict rules that basically don't let you talk about a lifetime unless it's valid at the point you're talking about it
-
Sharp
And that wouldn't be the case for the Future type associated with the SyslogServer (it would be a type that was only sometimes valid, somehow)
-
Sharp
So you probably do want to go with ownership.
-
Sharp
If in fact the Future type only needs to be alive for a much smaller duration than the Server itself, the Future type might need to be refactored to allow that… but I'm guessing that's a tokio Future or something so there's probably a reason for the current design (I haven't done much work with them myself).
-
Sharp
Or Server type, rather.
-
Sharp
Er… Service. I can talk, I promise.
-
Sharp
Anyway, tl;dr go with ownership.
-
talchas
xrl: there is no way to return (Foo, reference to interior Foo) in safe rust
-
Sharp
Oh, that's what's going on here, duh
-
talchas
owning_ref provides ways that would work to turn your String into a single &str with a safe interface, but there's no way to write a crate that is generic for this over all Foo<'a> rather than only working for &'a
-
Sharp
Yeah, that should be safe but it isn't :( I don't know if anyone really knows a good type level solution either.
-
talchas
you can manually write a type that is struct Message(String, SyslogMessage<'static>), where the 'static is a lie
-
talchas
you must _always_ access it only via &'a Message -> &'a SyslogMessage<'a>, and then you're ok
-
Sharp
talchas: That's rather dangerous…
-
talchas
(and SyslogMessage better not access anything lifetimed during drop(), but that's not an issue here)
-
talchas
(and I believe there's no safe lifetimes to provide a &mut SyslogMessage there)
-
Sharp
I think you'd need to transmute to satisfy the lifetime in the first place, right? Might as well just use raw pointers at that point
-
talchas
(possibly mutate<F:FnOnce(&mutSM<'a>)>(&mut self, f: F) {} )
-
talchas
Sharp: yeah, but you need to provide a struct to return that has the lifetimes with the correct layout
-
talchas
if you could do SyslogMessage<'unsafe> I'd say that
-
Sharp
Heh.
-
Sharp
Yeah, if that existed… but as is I think using raw pointers would probably be better here if only because you couldn't accidentally dereference them in safe code.
-
talchas
Sharp: the point would be to write Message and then never ever access .1 outside of impl Deref
-
talchas
you could even make a mod for the impl to make it impossible
-
Sharp
Yeah, if you did it in a mod it would be okay, I guess (given that unsafe poisons the module no matter what).
-
Soni
does diesel make all SQL interchangeable? (aka, can I trivially switch backends?)
-
panicbit
To a degree
-
panicbit
But you can't use migrations
-
panicbit
nor some features that aren't supported by all backensd you want to use
-
panicbit
e.g. "returning" is not supported by sqlite
-
panicbit
And apparently the default keyword isn't supported either
-
panicbit
-
panicbit
mysql doesn't seem to support returning either lol
-
sgrif
Yeah, only PG supports `RETURNING` on the backends Diesel supports
-
sgrif
SQLite at least has a decent reason for not supporting `DEFAULT`. There's no round trip time, so no real cost to doing one query per row.
-
sgrif
Arguably that's a decent reason to omit `RETURNING` too, but `last_insert_id` isn't really a great substitute for `RETURNING pk` -- especially if you want to abstract over it
-
sgrif
What was the original question? I only see the answer
-
sgrif
Ah. Yeah Soni, abstracting away your backend is kinda sorta possible with Diesel, but is explicitly not a goal of the project.
-
Soni
why not?
-
sgrif
A couple of reasons. First, we want it to be super obvious how our queries map to SQL. This usually means things have to look different depending on the backend. Second, switching databases on a production application is nearly impossible, and never really happens in the wild. Finally, your database does really cool things. You should take advantage of them. That requires coupling.
-
newpavlov4
I have three traits A, B and C, and I would like to write `impl<T:B> A for T {}` and `impl<T:C> A for T {}`. But it of course produces "conflicting implementations" error. Ideally I would like to use negative trait bounds to constrain C, but we don't have them...
-
newpavlov4
Is it possible to circumvent it using specialization? thus making `impl<T:B> A for T {}` "prefered" implementation if type implements both B and C traits?
-
newpavlov4
just making `default impl<T:C> A for T {}` does not do anything
-
talchas
newpavlov4: no, specialization doesn't have any way to do this at the moment iirc
-
sgrif
Soni: That said, there's a big difference between "this code has to work with all backends, including multiple backends simultaneously" vs "this code can be compiled to work with different backends". It's much easier to write the second form (see for example, any of Diesel's test suites) vs the first one (see diesel_cli or diesel_migrations)
-
talchas
it lets you have impls for T: B + C and T: B, but I believe that "possibly overlapping separate impls, and then an impl for the overlap" was on the "future work/maybe we need this" section
-
newpavlov4
talchas: shame... :( so no way to circumvent this situation currently?
-
talchas
ah, right, the lattice rule as the rfc calls it has issues with lifetimes
-
rkruppe
Lifetime specialization will be prohibited anyway. But the lattice rule won't allow this either. Neither of these two impls is "more specific" in any reasonable sense
-
KiChjang
wait wait wait
-
talchas
rkruppe: lattice would let you write T: B; T: C; T: C + B (forward to whichever)
-
KiChjang
what is this lattice rule thing?
-
rkruppe
talchas: Hm I guess
-
rkruppe
KiChjang: a smarter rule for when specialization considers one impl more specific than another
-
talchas
-
rkruppe
talchas: But while that might resolve the ambiguity, I'm not sure whether it's meaningful. It sounds like newpavlov4 wants mutually exclusive traits, which are not a thing period.
-
talchas
rkruppe: yeah
-
talchas
it is however sufficient for writing these impls
-
talchas
I wonder if you could shenanigans up a compile time error for the T: C + B impl that only happens if it's actually inhabited
-
talchas
or at least if there is a code path that invokes any of the trait methods
-
rkruppe
we really don't want that
-
talchas
yeah, I know, just horrible hacks interest me
-
Rantanen
Based on the question, the request was for "B + C" to resolve to C (making the C impl 'default impl')
-
rkruppe
talchas: No I mean, Rust language designers really don't want that and work hard to ensure it's not possible
-
talchas
but you can probably at least get a link error
-
Rantanen
So I don't think there was need for C + B to be an error.
-
talchas
yeah, I know
-
rkruppe
It's kinda pointless to guess more about what newpavlov4 was doing. They could, however, describe what they are actually trying to achieve. This sounds like an XY problem
-
Rantanen
Also curious, wouldn't something "innocent", like "impl<T:B+?Sized>" and "impl<T:C>" make the C-impl default as it's now strictly more specialized than the B-variant?
-
talchas
that's still not more specialized - it doesn't require B
-
rkruppe
under the current rule you mean? you'd need B and C to be related and in that case you don't need to mess around with ?Sized or anything
-
Rantanen
Ah, true.
-
newpavlov4
rkruppe: I was trying to write pre-RFC for using Generators with for loops, so I wanted to use this code:
play.rust-lang.org/?gist=00bc88baa3…ad995b3b1d673928666&version=nightly
-
newpavlov4
so for loop desugaring we could use `let generator = IntoGenerator::into_generator(values);`
-
newpavlov4
which will work for values, which are Generator and implement IntoIterator
-
talchas
newpavlov4: well, for this instance you could potentially hack it up by having the compiler generate specific IntoGenerator impls along with the Generator one
-
osa1
what's the most conccise way to get a String from a str literal?
-
talchas
or impl Generator for T: Iterator
-
talchas
Yield=Item, Return=()
-
rkruppe
yeah this is something that should receive proper compiler support
-
newpavlov4
talchas: yeah, but in that case we don't need IntoGenerator trait, compiler can insert conversion into iterator (which implements Generator) if its IntoIter and do nothing otherwise
-
newpavlov4
but its compiler magick...
-
rkruppe
newpavlov4: for loop desugaring is syntactic, so no it can't desugar differently depending on whether the "iterator" is actually a generator (at least not in its current form, which it has for good reasons)
-
newpavlov4
rkruppe: so no easy way to implement this feature...
-
Rantanen
osa1: "most concise"? Probably .into()
-
Rantanen
Unles you have to specify the type, at which point it becomes .to_owned()
-
dowwie
mitsuhiko: I was blaming ctypes for an issue that may instead be related to milksnake
-
mitsuhiko
dowwie: go on?
-
smaug
Someone remind me. There is/was some project to improve rustc compilation speed, right?
-
albel727
> using Generators with for loops <-- just convert generator to iterator, no? there's even a crate for that
-
rkruppe
smaug: Incremental compilation? Not really making rustc faster, but making it work smarter.
-
smaug
really talking about making it faster and less memory hungry
-
rkruppe
There are improvements here and there, and we have perf.rust-lang.org for tracking compilation times and memory usage, but I'm not aware of a big targeted effort to improve it specifically
-
» albel727 isn't sure the whole for loop for generators idea even makes sense in general
-
talchas
it makes sense for Return = ()
-
albel727
not for extended generators which have resume(self, value)
-
talchas
(and in that case, arg=())
-
albel727
well of course, but that's the same thing as saying "it doesn't make sense for them"
-
talchas
it makes sense for many of them, but not all of them
-
albel727
so what you're doing here is just treating generators as iterators. and so just make and adapter for that. there actually is one.
-
talchas
yeah, basically
-
albel727
!crate gen-iter
-
rustbot
gen-iter (0.1.2) - temporary util for creating iterators using generators ->
crates.io/crates/gen-iter <
docs.rs/gen-iter>
-
talchas
I do think that the right direction is Generator -> Iterator more than vice versa
-
» albel727 nods
-
talchas
if you were to make any direction implicit for simplicity
-
albel727
not sure when IntoGenerator would make sense
-
albel727
especially for a role as THE abstraction behind for loops.
-
talchas
you'd run into overlapping impls though even for impl<T:Generator> Iterator for T, due to &mut blanket impls for bothe Generator and Iterator
-
albel727
not even Iterator<A> -> Generator<Arg=A, Item=B, Return=()> -> Iterator<B> makes sense.
-
centril
Should one prefer a `O: From<Self>` or `Self: Into<O>` bound? It seems to me that more types can support `Into<O>` .. so go with Into ?
-
_habnabit
centril, yes
-
centril
_habnabit: cheers
-
albel727
> overlapping impls <-- no need for impls. wrapping in a newtype should be enough for everyone.
-
mbrubeck
or the compiler can generate the Iterator impl at the same time it generates the Generator impl
-
talchas
yeah
-
centril
mbrubeck: that sounds neat
-
albel727
I think the rule of thumb was implement From, and Into will be blanketed from that.
-
centril
albel727: yes, implement From - but some types can't implement From due to coherence, so you have to use Into in some cases
-
centril
But Into should afaik strictly support more conversions
-
albel727
not sure it warrants the complexity. just an IntoIterator for Generators should be fine, I guess.
-
talchas
it's just "copypasta impl Iterator for X { type Item = <Self as Generator>::Item; fn next(&mut self) -> Option<Self::Item> { self.resume().map_stuff() }}" is kinda :(
-
albel727
I just don't exactly like putting more magic into compiler for such an obscure usecase
-
albel727
if one really wants iterators from generators that much and so often, they should've not removed unfold() from stdlib
-
albel727
>2018 >no unfold() in stdlib >my face when
-
albel727
not only that. removed.
-
» albel727 shakes head
-
_habnabit
talchas, wait, is copypasta the new keyword for trait delegation?
-
mbrubeck
Like, we don't have blanket `impl<F:Fn<T,U>> FnMut<T,U> for F`
-
centril
I think unfold should be in libcore and we should in general start moving more and more of itertools into libstd/core
-
talchas
_habnabit: hah
-
thenewwazoo
yes please.
-
thenewwazoo
all the things in core
-
talchas
need another level of quoting there
-
mbrubeck
The compiler generates impls of all the FnFoo traits that apply, for each closure type
-
centril
mbrubeck: when specialization is stabilized Soon (TM) we'll be all sorts of cool stuff =P
-
jturner314
Can my examples (stuff in `examples/`) have unit tests that run with `cargo test`?
-
centril
jturner314: well you can have #[test]s, but since it is another crate, you will only be able to see and use `pub` items
-
centril
oh `examples/`
-
centril
idk
-
mbrubeck
jturner314: No, `cargo test` will build stuff in examples/*.rs but not run it
-
mbrubeck
and it won't build it in --test mode
-
albel727
>inb4 cargo run --example --test
-
albel727
(which is a non-command)
-
jturner314
Okay, thanks. I suppose I'll have to move my example into a separate crate, then.
-
mbrubeck
jturner314: "tests/foo.rs" will be built and run by `cargo test`...
-
sarnold
can you do ugly things with symlinks?
-
albel727
(that poorly thought out noncomposable build/artifact system of cargo makes anyone familiar with scala sad)
-
jturner314
mbrubeck: Right, but I can't use functions defined in `examples/` right? I can only test the main crate that way.
-
mbrubeck
jturner314: right
-
newpavlov4
albel727: you are missing the point of allowing `let result = for val in generator { .. };`
-
newpavlov4
and Generator -> Iterator does not make much sense, because Iterator is subset of Generator
-
newpavlov4
also where did you find Arg associated type for the Generator?
doc.rust-lang.org/std/ops/trait.Generator.html
-
talchas
newpavlov4: if you extended Generator to allow x = yield y; you'd have an associated type for it, or maybe an argument
-
newpavlov4
talchas: not sure why we need that, I was talking in the context of exisiting implementation
-
albel727
many generator implementations, e.g. in python and scala, have Arg. and I hear rust's generator is also supposed to get an Arg. > `let result = for val in generator { .. };` <-- introduce a for {} else {} construct first, if you need that.
-
hdevalence
is there a way to get a benchmark to print a per-item time count?
-
mbrubeck
hdevalence: The standard library #[bench] feature doesn't really have any customization hooks, currently
-
hdevalence
I'd like to get output like: bench: 789,565 ns/iter (+/- 70,126) (771 ns/item)
-
hdevalence
where I tell it that it's processing 1024 elements
-
mbrubeck
oh, it does have something along those lines...
-
scrogson
does `cargo install` compile with --release ?
-
newpavlov4
albel727: we have that we have, no sense to discuss something which AFAIK does not have even RFC. for else looks quite ugly to me, while desugaring for loops using Generator is a much better alternative
-
mbrubeck
scrogson: yes
-
centril
newpavlov4: "ugly" is not really a helpful argument and unconvincing
-
centril
can you elaborate on what you mean?
-
scrogson
mbrubeck: thought so..just thought I'd make sure :D
-
mitsuhiko
love it. failure does not work with the new termination thing
-
mitsuhiko
i really hope std::error/failure does not turn into rust's phobos vs tango
-
mbrubeck
hdevalence: or, I thought it did, now I can't find it...
-
albel727
one can argue in similar vein that "let result = for {};" is ugly. but what's happening is that at least the worth of returning values from for loops is admitted. if user is deemed justified in their desire to return values from for loops, it's weird to make them round-trip through generators whenever they want to.
-
albel727
unless generators get convenient compiler sugar for creating generators, which would ultimately amount to "for {} else {}".
-
newpavlov4
centril: ok, let's say it feels less ad hoc (yeah, I know subjective)
-
albel727
or for {} finally {}, for that matter.
-
newpavlov4
-
albel727
for {} else {} finally {}, anyone? :>
-
» albel727 hides
-
centril
albel727: what's the point of finally? just put the block below?
-
sarnold
centril: maybe for the 'exceptionish' error handling things?
-
» albel727 has no idea :>
-
durka42
try {} for {} else {} finally {} catch {} except {}
-
» albel727 runs
-
centril
sarnold: please no exceptionishisms
-
mbrubeck
We're talking about looping over generators, which can return a final value that's a different type from the Yield value
-
» albel727 afk for ~15 min
-
sarnold
durka42: full on insanity :)
-
Soni
what's this for else stuff?
-
mbrubeck
hypothetical syntax for loops over Generators instead of Iterators
-
» centril wishes sometimes that we didn't have for loops
-
Soni
can I suggest an useful for else?
-
centril
all you need is iter.for_each(...)
-
Soni
break in the for {} bit returns value directly, else the else is used to generate the value
-
endeavor
I have a vec of structs, and a reference to a struct in the vec. I would like to know the location in the vec for the referenced struct I have. The vec may have duplicates. How can I do this?
-
sarnold
and I assume finding the 'first' of the duplicates is not the correct approach?
-
endeavor
no
-
talchas
endeavor: .iter().position(|x| x as *const _ == item as *const _)
-
endeavor
thanks
-
sarnold
woo :)
-
_habnabit
-
talchas
oh TIL
-
mbrubeck
endeavor: There's also the constant-time option, ((item as *const _ as usize) - (vec.as_ptr() as usize)) / size_of::<T>()
-
_habnabit
hah
-
sarnold
wow, that's remarkably close to how I would have suggested to do it in C. I'm surprised it translates so well.