Reputation: 901
I get an error referencing a boxed value:
error[E0308]: mismatched types
--> src/interpreter.rs:284:37
|
284 | table[index].function = method;
| ^^^^^^ expected struct `Box`, found `&Box<MethodType>`
|
= note: expected struct `Box<MethodType>`
found reference `&Box<MethodType>`
If I dereference it by saying *method
I get an error because MethodType
doesn't implement Copy
(which would be a pain, because it includes a couple of Vec
s and it would be very expensive to copy). Maybe I could fix it with ManuallyDrop
, but that doesn't seem very idiomatic, and I spent some time this afternoon getting rid of a ManuallyDrop
.
Perhaps I shouldn't be passing it by reference (the only two calls to addMethodToTable
are in the following method, addMethodToDispatch
but they are in loops, because I need to try allocation several times). Maybe it should be an Rc
instead.
This is part of a lot of code, so I hope this snippit is enough to show what I'm doing wrong:
#[derive(Clone)]
enum MethodType {
Function(Function),
Method(Method),
NoType,
}
#[derive(Clone)]
struct MethodMatch {
selector: usize,
function: Box<MethodType>,
}
pub struct Dispatch {
class: Object,
table: Box<[MethodMatch]>,
}
fn addMethodToTable(table:&mut Vec<MethodMatch>,selector:usize,method:&Box<MethodType>) -> bool {
let len = table.capacity();
let hash = selector%(len-DISPATCH_OVERFLOW);
for index in hash..hash+DISPATCH_OVERFLOW {
if let SelectorMatch::Other = table[index].selector_match(selector) {
// slot taken
} else {
table[index].selector = selector;
table[index].function = method;
return true
}
}
false
}
fn addMethodToDispatch(class:ClassIndex,selector:Object,method:Box<MethodType>) {
let selector = selector.raw()>>3;
while ... {
table = Vec::with_capacity(count+DISPATCH_OVERFLOW);
addMethodToTable(&mut table,selector,&method);
for mm in disp.table.iter() {
if addMethodToTable(&mut table,mm.selector,&mm.function) {unfinished = true;break}
}
}
table.resize(table.capacity(),Default::default());
disp.table=table.into_boxed_slice()
},
index => {
disp.table[index].selector = selector;
disp.table[index].function = method
},
I was having such a productive day until I hit this... thinking I was finally "getting" Rust!
Upvotes: 1
Views: 4195
Reputation: 15723
Your struct expects an owned type - function
must be a Box
:
#[derive(Clone)]
struct MethodMatch {
selector: usize,
function: Box<MethodType>,
}
but in your other method the parameter method
is a reference to a Box
which are two very different types:
`fn addMethodToTable(....,method: &Box<MethodType>)
There are two ways to fix the issue (not all may be applicable in your case):
Change the reference to an owned type: method: &Box<MethodType>
should become method: Box<MethodType>
Because your MethodType
implements Clone
, just clone it in order to get an owned type from the reference: table[index].function = method.clone();
If you are free to change the struct definition, you can use Rc<T>
instead of Box<T>
. Thus you can use Rc::clone(reference)
and clone only the pointer instead of the whole struct.
Upvotes: 2