The following C++ program:
int main() {
std::vector<std::string> v1 = {"a"};
assert(v1.back().at(0) == 'a');
return 0;
}
Is incorrectly translated to the following:
fn main_0() -> i32 {
let v1: Value<Vec<Vec<u8>>> = Rc::new(RefCell::new(vec![{
let mut __bytes = Ptr::<u8>::from_string_literal(b"a").to_c_bytes();
__bytes.push(0);
__bytes
}]));
assert!(
(((if 0_usize as usize
>= (*((v1.as_pointer() as Ptr<Vec<u8>>).to_last() as Ptr<Vec<u8>>)
.upgrade()
.deref())
.len()
.saturating_sub(1)
{
panic!("out of bounds access")
} else {
((v1.as_pointer() as Ptr<Vec<u8>>).to_last() as Ptr<Vec<u8>>)
.decay() // panic: 'ub: invalid decay'
.offset(0_usize as isize)
}
.read()) as i32)
== (('a' as u8) as i32))
);
return 0;
}
This transation is generated using the following string rule:
fn f26(a0: Ptr<Vec<u8>>, a1: usize) -> Ptr<u8> {
if a1 as usize >= (*a0.upgrade().deref()).len().saturating_sub(1) {
panic!("out of bounds access")
} else {
a0.decay().offset(a1 as isize)
}
}
This rule is written assuming that a0 is of kind StackSingle/HeapSingle, which is the case whenever this rule is applied to a plain std::string reference. However, if the std::string reference is obtained through a container (for instance, via std::vector::back), the corresponding Ptr will be of kind StackVec/HeapVec, and calling decay on it fails.
Another issue with Ptr::decay is that its invocation can be considered ambiguous under certain circunstances.
The following C++ program:
int main() {
std::vector<std::vector<int>> v1;
std::vector<int> v2 = {1};
v1.push_back(v2);
assert(v1.back().at(0) == 1);
return 0;
}
Is translated to:
fn main_0() -> i32 {
let v1: Value<Vec<Value<Vec<i32>>>> = Rc::new(RefCell::new(Vec::new()));
let v2: Value<Vec<i32>> = Rc::new(RefCell::new(vec![1]));
(v1.as_pointer() as Ptr<Vec<Value<Vec<i32>>>>).with_mut(|__v: &mut Vec<Value<Vec<i32>>>| {
__v.push(Rc::new(RefCell::new((*v2.borrow()).clone())))
});
assert!(
((((*v1.borrow())[(*v1.borrow()).len() - 1]
.as_pointer()
.decay() as Ptr<i32>) // compilation error: 'error[E0034]: multiple applicable items in scope'
.offset(0_usize as isize)
.read())
== 1)
);
return 0;
}
The decay in this translation is emitted by the converter itself.
The following C++ program:
Is incorrectly translated to the following:
This transation is generated using the following string rule:
This rule is written assuming that
a0is of kindStackSingle/HeapSingle, which is the case whenever this rule is applied to a plainstd::stringreference. However, if thestd::stringreference is obtained through a container (for instance, viastd::vector::back), the correspondingPtrwill be of kindStackVec/HeapVec, and callingdecayon it fails.Another issue with
Ptr::decayis that its invocation can be considered ambiguous under certain circunstances.The following C++ program:
Is translated to:
The
decayin this translation is emitted by the converter itself.