These are chat archives for rust-lang/rust

3rd
Jan 2018
Hans W. Uhlig
@huhlig
Jan 03 2018 00:00
let opcode = |op: OpCode| -> bool { (word & op.mask) == op.code }; let instruction = match word { (word) if opcode(NOP) => { Instruction::Nullary { opcode: NOP } } (word) if opcode(CLK) => { Instruction::Nullary { opcode: CLK } } } Is there a batter way to do this?
Techcable
@Techcable
Jan 03 2018 03:19
@huhlig A macro might work nicely
Moggers
@Moggers
Jan 03 2018 04:37
Whats the story for rust on embedded hardware?
I'm looking at running rust on an RTL8711 using the GPIO pins and the wifi interface
I found a pretty good writeup on someone using bindgen with freertos but considering rust is all systems programming it feels like there should be something like an RTOS written in rust
the only thing I can find so far is zinc.rs
Restioson
@Restioson
Jan 03 2018 08:09
What arch? @Moggers
Hans W. Uhlig
@huhlig
Jan 03 2018 16:29
hmm
silly question... do closures have to be mutable to use them?
Restioson
@Restioson
Jan 03 2018 16:29
It depends
Fn: must have shared access to env
FnMut: must have exclusive access to env
FnOnce: must have ownership of env
So for Fn you only need &Fn, for FnMut you only need &mut, but for FnOnce you need it to be owned
error[E0595]: closure cannot assign to immutable local variable next_pc
--> src/main.rs:163:21
|
129 | let next_pc = || -> u16 {
| ------- consider changing this to mut next_pc
...
163 | let upper = || -> Value {
| ^^^^^^^^^^^ cannot borrow mutably
this is what I was meaning
Restioson
@Restioson
Jan 03 2018 16:37
hmm
Hans W. Uhlig
@huhlig
Jan 03 2018 16:37
I don't need to alter next_pc() but next_pc alters the environment it's in
is that a mutable closure then?
and how does the mutability of the function have to do with the mutability of the environment
Restioson
@Restioson
Jan 03 2018 16:38
Looks like it is Fn
idk tho
I had something like that there, i think i made it mutabel and it worked
idk why
Hans W. Uhlig
@huhlig
Jan 03 2018 16:38
hmm
mentally very unintuitive that the mutability of a binding alters the mutability of variables a function uses
Restioson
@Restioson
Jan 03 2018 16:39
Yes
Hans W. Uhlig
@huhlig
Jan 03 2018 16:39
intellij-rust calls it fn as well
Restioson
@Restioson
Jan 03 2018 16:39
Ooh try &|| -> Value
Hans W. Uhlig
@huhlig
Jan 03 2018 16:40
arrrgh
error[E0524]: two closures require unique access to self at the same time
Restioson
@Restioson
Jan 03 2018 16:41
Try changing the match to derefing the thing being matched on?
Hans W. Uhlig
@huhlig
Jan 03 2018 16:41
the thing being matched on is just a u16
there is no derefing needed
Restioson
@Restioson
Jan 03 2018 16:42
I thinkj it would be captured as a &u16
idek
Hans W. Uhlig
@huhlig
Jan 03 2018 16:42
blob
it should be copy
if anything
Restioson
@Restioson
Jan 03 2018 16:43
yeah idk sorry :(
Hans W. Uhlig
@huhlig
Jan 03 2018 16:43
no problem
the borrow checker is being a pita as usual
Restioson
@Restioson
Jan 03 2018 16:44
idk maybe try activating nll?
Hans W. Uhlig
@huhlig
Jan 03 2018 16:44
I really don't want to make the function unsafe
Restioson
@Restioson
Jan 03 2018 16:44
I have no idea but it might work
Why would you have to do that?
Hans W. Uhlig
@huhlig
Jan 03 2018 16:44
basically to avoid the borrow checking while manipulating multiple fields in a struct
it's all stemming from altering the state of multiple fields of self
Steve Klabnik
@steveklabnik
Jan 03 2018 16:46
unsafe doesn't remove borrow checking
you'd also have to convert all &Ts to *const Ts, etc
Restioson
@Restioson
Jan 03 2018 16:46
^
Hans W. Uhlig
@huhlig
Jan 03 2018 16:47
ahh I thought it would allow you to sidestep
Steve Klabnik
@steveklabnik
Jan 03 2018 16:47
i want to dig into this more but am doing too many things at once
@huhlig it does, by giving you access to non-borrow-checked things
Restioson
@Restioson
Jan 03 2018 16:47
rip
Steve Klabnik
@steveklabnik
Jan 03 2018 16:47
unsafe doesn't change the semantics of existing code at all, only unlocks new things
Hans W. Uhlig
@huhlig
Jan 03 2018 16:47
ahh gotcha
lemmie try on nightly with nll
Hans W. Uhlig
@huhlig
Jan 03 2018 18:51
can anyone help me alleviate a couple borrow checker errors
Steve Klabnik
@steveklabnik
Jan 03 2018 18:52
so, why are all of these closures?
Hans W. Uhlig
@huhlig
Jan 03 2018 18:53
simplicity and not repeating code
Steve Klabnik
@steveklabnik
Jan 03 2018 18:53
what does that give you over a function though
Hans W. Uhlig
@huhlig
Jan 03 2018 18:53
they are basically small inline functions to do a couple common things
Steve Klabnik
@steveklabnik
Jan 03 2018 18:53
is what i'm asking
Hans W. Uhlig
@huhlig
Jan 03 2018 18:54
they are functions?
Steve Klabnik
@steveklabnik
Jan 03 2018 18:54
they're closures
functions are defined with fn
Hans W. Uhlig
@huhlig
Jan 03 2018 18:54
which are functions with implicit variables
Steve Klabnik
@steveklabnik
Jan 03 2018 18:54
okay, well we can argue about terms if you'd like
Hans W. Uhlig
@huhlig
Jan 03 2018 18:54
unless rust treats a lambda closure differently than a function
Steve Klabnik
@steveklabnik
Jan 03 2018 18:54
yes
you capture the environment
this is why you're getting the errors
Hans W. Uhlig
@huhlig
Jan 03 2018 18:55
ahh, grr
Steve Klabnik
@steveklabnik
Jan 03 2018 18:55
i think this would be simpler to dis-tangle if you just used regular functions over closures
you can even define them inside, the same way
Hans W. Uhlig
@huhlig
Jan 03 2018 18:55
alright
hmm
alright, I am obvieously daft
why cant I pass a mutable borrow to one function, then after that function pass it to a different function
Steve Klabnik
@steveklabnik
Jan 03 2018 19:15
closures capture their environemnt
Hans W. Uhlig
@huhlig
Jan 03 2018 19:15
not closures
Steve Klabnik
@steveklabnik
Jan 03 2018 19:15
so, you have a &self the whole time that your closure is in scope
Hans W. Uhlig
@huhlig
Jan 03 2018 19:15
I changed it all to functions as you suggested
Steve Klabnik
@steveklabnik
Jan 03 2018 19:15
hm, there's still a lot of closures in that link
and that's what the compile errors talk about
maybe you mis-pasted?
my fault, I updated my code in the playground
Steve Klabnik
@steveklabnik
Jan 03 2018 19:16
ah ha!
no worries :)
Hans W. Uhlig
@huhlig
Jan 03 2018 19:16
and it didn't update the link
err the program AT the link
Steve Klabnik
@steveklabnik
Jan 03 2018 19:18
so
    impl<'s> Value<'s> {
    fn upper(cpu: &mut VCPU16, word: u16) -> Value {
this means that the Value you return from upper is gonna still be borrowing cpu
Hans W. Uhlig
@huhlig
Jan 03 2018 19:19
the entire function is borrowing the CPU
Steve Klabnik
@steveklabnik
Jan 03 2018 19:19
fn upper<'a>(cpu: &'a mut VCPU16, word: u16) -> Value<'a> {
if that makes it more clear
Hans W. Uhlig
@huhlig
Jan 03 2018 19:19
ok
so what is the best way to do what im trying to do
as I am quite horribly failing
Steve Klabnik
@steveklabnik
Jan 03 2018 19:20
i'm thinking
it's like a lot of code
so takes some time to grok :)
Hans W. Uhlig
@huhlig
Jan 03 2018 19:20
sorry
Steve Klabnik
@steveklabnik
Jan 03 2018 19:21
nah it happens
Hans W. Uhlig
@huhlig
Jan 03 2018 19:21
it's not actually as complex as it looks
red75prime
@red75prime
Jan 03 2018 19:21
@huhlig references doesn't work the way you intend to use them. If you store one immutable reference to a part of the structure (like you do in Value), you cannot mutate the whole structure
Hans W. Uhlig
@huhlig
Jan 03 2018 19:21
so what is the best way to do this
or is this one of those areas that rust just can't do
Steve Klabnik
@steveklabnik
Jan 03 2018 19:21
why does Value borrow things?
it's a u16; it'd be cheaper to always copy it
(there might be a good reason, as i said, still trying to grok this code)
Hans W. Uhlig
@huhlig
Jan 03 2018 19:22
Value is just a holder for either a reference to destination or a value
ok, let me back up and I can explain
the opcode is basically 3 parts
top 6 bits is upper, next 5 middle, last 5 lower
for a binary instruction, basically it parses the last 5 as the op code
then parses the top 6 and does the fetch (which may alter the CPU state)
then parses the middle 5 and does another fetch (again possibly altering CPU state)
with those two pieces, it executes the op code
the top 6 can represent a location in memory, or a value
that location in memory is potentially a virtual register or a spot in the memory array
or it could be treated as a literal value
Value as an enum is basically just a temporary holder to resolve is it a location, or a value
specifically because upper MUST be read before middle
Steve Klabnik
@steveklabnik
Jan 03 2018 19:26
hm, okay
Hans W. Uhlig
@huhlig
Jan 03 2018 19:26
I could unfold upper into each and every instruction
except that would basically replicate the code 20 some odd times
Steve Klabnik
@steveklabnik
Jan 03 2018 19:27
so, as @red75prime said, fundamentally this specific way can't work. as long as you have a Value that's referring to self, you're not going to be able to mutate self at all
since you always de-refernecing
.... sorry
derefernece
Hans W. Uhlig
@huhlig
Jan 03 2018 19:27
ok... so how would I acomplish something which is logically incredibly easy
and safe given that this is all in the context of a single function context
Steve Klabnik
@steveklabnik
Jan 03 2018 19:28
it's not just about safe today, it's about safe tomorrow
Hans W. Uhlig
@huhlig
Jan 03 2018 19:28
eh?
red75prime
@red75prime
Jan 03 2018 19:30
I would probably go with {mem: [0; 65536]; regs: [0; 14];} and enum Value { Literal(u16), Mem(u16), Reg(u8) }
Steve Klabnik
@steveklabnik
Jan 03 2018 19:34
like, you're trying to mutate something you're holding an & to
that has issues in a single threaded context too
but if you ever added threads, boom
this all blows up
Hans W. Uhlig
@huhlig
Jan 03 2018 19:34
err... no it doesn't
this is all literally inside a single function call
Steve Klabnik
@steveklabnik
Jan 03 2018 19:34
                &Value::Location(l) => { *l = value; }
being in a single function call has nothing to do with it
Hans W. Uhlig
@huhlig
Jan 03 2018 19:35
the functions inside the function are there explicitly as helpers to reduce code duplication
they could be expanded out and this would magically work
I just don't want the same 50 lines 30 times over
David McGillicuddy
@djmcgill
Jan 03 2018 20:05

Is there an alternative to &*foo when using a Deref conversion to a reference you can't move? Currently I have

let ref connection: &Connection = &*pooled_connection;

where pooled_connection implements Deref with Deref::Target = Connection

Which works, but I thought that as_ref did the same thing? It's not working when I try it though.
Steve Klabnik
@steveklabnik
Jan 03 2018 20:06
that ref is supsicious
David McGillicuddy
@djmcgill
Jan 03 2018 20:07
yep, not needed
thanks
Steve Klabnik
@steveklabnik
Jan 03 2018 20:07
i just use &* personally
this is how I got it to copmpile
very much feels like having to work around a bad compiler but it compiles
I need to get some other stuff working before I can test it
David Harvey-Macaulay
@alteous
Jan 03 2018 21:25
[dependencies]
foo = { optional = true, ... }
bar = { optional = true, dependencies = ["foo"], ... } # needs to be enabled with `foo`
Is it possible to enable crate bar by just enabling crate foo?
Erik Hedvall
@Ogeon
Jan 03 2018 22:52
Doesn't look like it, judging by the documentation, but you could specify a feature use-foo = ["foo", "bar"]