Skip to content

Unsoundness: Interned values can store references #985

@ibraheemdev

Description

@ibraheemdev

For example, the following test triggers Miri, because we attempt to access the previous value when re-interning.

#[salsa::input]
struct Input {
    #[returns(ref)]
    field1: Box<usize>,
}

#[salsa::interned]
struct Interned<'db> {
    field1: &'db Box<usize>,
}

#[test]
fn test() {
    #[salsa::tracked]
    fn intern<'db>(db: &'db dyn Database, input: Input) -> Interned<'db> {
        Interned::new(db, input.field1(db))
    }

    let mut db = common::LoggerDatabase::default();

    let input = Input::new(&db, Box::new(100));

    let _interned = intern(&db, input);

    input.set_field1(&mut db).to(Box::new(100));

    let interned = intern(&db, input);
    dbg!(interned.field1(&db));
}
 error: Undefined Behavior: trying to retag from <471448> for SharedReadOnly permission at alloc187151[0x0], but that tag does not exist in the borrow stack for this location
    --> /home/ibraheem/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cmp.rs:2029:27
     |
2029 |             PartialEq::eq(*self, *other)
     |                           ^^^^^ this error occurs as part of retag at alloc187151[0x0..0x8]
     |
     = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
     = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information

We probably need to enforce salsa::Update for the fields of interned values, similar to tracked structs. #681 is relevant.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions