Skip to content

binding-less matches on borrowed data are incorrectly allowed #45045

Closed
@arielb1

Description

@arielb1

This is actually an unsoundness in AST borrowck: AST borrowck doesn't check things that are matched on for conflicting borrows unless there are actually pattern bindings, e.g. this compiles:

enum Xyz {
    A,
    B,
}

fn main() {
    let mut e = Xyz::A;
    let f = &mut e;
    match e {
        Xyz::A => println!("a"),
        Xyz::B => println!("b"),
    };
    *f = Xyz::B;
}

That is unsound because of e.g. data races. For example, this code compiles and runs, and semi-reliably segfaults:

#![feature(test)]
use std::{thread, time};

extern crate crossbeam;
extern crate test;

enum Xyz<'a> {
    A(&'a usize),
    B(usize),
}

fn main() {
    let mut e = Xyz::A(&0);
    crossbeam::scope(|scope| {
        scope.spawn(|| {
            let now = time::Instant::now();
            let ten_millis = time::Duration::from_millis(50);
            while now.elapsed() < ten_millis {
                for _ in 0..1000000 {
                    e = Xyz::A(&0);
                    test::black_box(()); // compiler barrier
                    e = Xyz::B(0xaaaaaaaa);
                }
            }
        });
        let ten_millis = time::Duration::from_millis(10);
        thread::sleep(ten_millis);
        match e {
            Xyz::A(&0) => println!("a"),
            _ => println!("b"),
        };
    });
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityfixed-by-NLLBugs fixed, but only when NLL is enabled.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions