I use https://github.com/dtolnay/clang-ast to parse the JSON produced by Clang representing an AST to be available as a Rust data type, specifically the Node
. I'd like to insert the nodes from the tree (Node<T>
is recursive structure) into a HashSet
. I could not even insert the root note:
use std::collections::HashSet;
use log::debug;
use std::env;
use serde::Deserialize;
pub type Node = clang_ast::Node<Clang>;
#[derive(Deserialize)]
#[derive(Debug)]
pub enum Clang {
BinaryOperator(BinaryOperator),
Other,
}
#[derive(Deserialize, Debug)]
pub struct BinaryOperator {
pub opcode: String,
pub range: clang_ast::SourceRange,
}
fn main() {
env_logger::init();
let json = std::fs::read_to_string("ast.json").unwrap();
let node :Node = serde_json::from_str(&json).unwrap();
let mut node_set = HashSet::new();
node_set.insert(node);
}
this fails the compilation with:
error[E0277]: the trait bound `clang_ast::Node<Clang>: Eq` is not satisfied
--> src/main.rs:28:21
|
28 | node_set.insert(node);
| ------ ^^^^ the trait `Eq` is not implemented for `clang_ast::Node<Clang>`
| |
| required by a bound introduced by this call
|
note: required by a bound in `HashSet::<T, S>::insert`
...
So, I tried to add the Eq
and PartialEq
implementations using (following some advice from How to implement Eq and Hash for my own structs to use them as a HashMap key?):
impl PartialEq for Node {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Node {}
however this fails with:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:8:1
|
8 | impl PartialEq for Node {
| ^^^^^---------^^^^^----
| | | |
| | | `clang_ast::Node` is not defined in the current crate
| | `clang_ast::Node` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
How do I make this work ? Also, why does the language/compiler imposes such limit ?
Following the answers on Implement foreign trait for foreign type does not really help because there are more pieces to the puzzle (implementing Eq
, PartialEq
, the Hash
trait, dealing with the recursive nature of clang_ast::Note<T>
).