Skip to content

Facet implementation for type with invariants #80

Closed
@tyilo

Description

@tyilo

Is it supposed to be safe to implement Facet with #[derive(Facet)] for a type that has internal invariants?

If so, then facet_json::from_str needs to be unsafe:

use facet::Facet;

type T = u64;

#[derive(Facet)]
pub struct MyVec {
    pub inner: Vec<T>,
}

#[derive(Facet)]
pub struct AtLeastTwoVec {
    inner: Vec<T>,
}

impl AtLeastTwoVec {
    pub fn new(v: Vec<T>) -> Option<Self> {
        if v.len() < 2 {
            None
        } else {
            Some(Self { inner: v })
        }
    }

    pub fn second(&self) -> &T {
        // SAFETY: `inner` has at least length 2
        unsafe { self.inner.get_unchecked(1) }
    }
}

fn main() {
    assert!(MyVec::type_eq::<AtLeastTwoVec>());

    let v = MyVec { inner: vec![1] };
    let peek = facet_peek::Peek::new(&v);
    let json = facet_json::to_json_string(peek, false);

    let v: AtLeastTwoVec = facet_json::from_str(&json).unwrap();
    dbg!(v.second()); // Undefined behavior
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✋ questionFurther information is requested🎺 soundnessUnsoundness in the code or design, we're doing UB / breaking invariants

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions