Skip to content

Incorrect substitutions for rules using Ptr parameters #220

Description

@joaotgouveia

Using the following rules for std::vector:

// src.cpp
template <typename T1> using t1 = std::vector<T1>;

template <typename T1> std::vector<T1> f1(const std::vector<T1> &a0) {
  return std::vector<T1>(a0);
}

template <typename T1> std::vector<T1> f2(std::vector<T1> &&a0) {
  return std::vector<T1>(std::move(a0));
}

template <typename T1>
std::vector<T1> &f3(std::vector<T1> &a0, std::vector<T1> &&a1) {
  return a0.operator=(std::move(a1));
}
// tgt_refcount.rs
fn t1<T1>() -> Vec<T1> {
    Vec::new()
}

fn f1<T1: Clone>(a0: Ptr<Vec<T1>>) -> Vec<T1> {
    a0.to_strong().borrow().clone()
}

fn f2<T1>(a0: Ptr<Vec<T1>>) -> Vec<T1> {
    std::mem::take(&mut *a0.to_strong().borrow_mut())
}

fn f3<T1: ByteRepr>(a0: Ptr<Vec<T1>>, a1: Ptr<Vec<T1>>) -> Ptr<Vec<T1>> {
    let moved = a1.with_mut(|v| std::mem::take(v));
    a0.with_mut(|dst| *dst = moved);
    a0
}

The following translation is generated:

int main() {
  std::vector<int> vec1;
  std::vector<int> vec2(std::move(vec1));
  std::vector<int> vec3(vec2);
  vec3 = std::move(vec2);

  return 0;
}
fn main_0() -> i32 {
    let vec1: Value<Vec<i32>> = Rc::new(RefCell::new(Vec::new()));
    let vec2: Value<Vec<i32>> = Rc::new(RefCell::new(std::mem::take(
        &mut *(*vec1.borrow_mut()).to_strong().borrow_mut(), // (*vec1.borrow_mut()) should be (vec1.as_pointer() as Ptr<...>)
    )));
    let vec3: Value<Vec<i32>> =
        Rc::new(RefCell::new(vec2.as_pointer().to_strong().borrow().clone())); // vec2.as_pointer should be (vec2.as_pointer() as Ptr<...>)
    {
        let moved = (*vec2.borrow_mut()).with_mut(|v| std::mem::take(v)); // (*vec2.borrow_mut()) should be (vec2.as_pointer() as Ptr<...>)
        (vec3.as_pointer() as Ptr<Vec<i32>>).with_mut(|dst| *dst = moved);
        (vec3.as_pointer() as Ptr<Vec<i32>>)
    };
    return 0;
}

The generated ir_refcount.json appears to be correct. All Ptr parameters are marked as is_refcount_pointer:

// f1
"params": {
  "a0": {
    "type": "Ptr<Vec<T1>>",
    "is_refcount_pointer": true
  }
},

// f2
"params": {
  "a0": {
    "type": "Ptr<Vec<T1>>",
    "is_refcount_pointer": true
    }
},

// f3
"params": {
  "a0": {
    "type": "Ptr<Vec<T1>>",
    "is_refcount_pointer": true
  },
  "a1": {
    "type": "Ptr<Vec<T1>>",
    "is_refcount_pointer": true
  }
},

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions