<commit_before>import xlib::*;
import libc::*;
import cairo_xlib::*;
import xlib::bindgen::*;
import cairo::*;
import cairo::bindgen::*;
import cairo_xlib::bindgen::*;

#[test]
fn sanity_check() {
    AzSanityCheck();
}

const SIZEX: c_uint = 400 as c_uint;
const SIZEY: c_uint = 400 as c_uint;

const ExposureMask: c_long = (1 << 15) as c_long;
const ButtonPressMask: c_long = (1 << 2) as c_long;

const Expose: c_int = 12 as c_int;
const ButtonPress: c_int = 4 as c_int;

type XEventStub = {
    type_: c_int,
    padding: (
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int
    )
};

fn xexpose(event: *XEventStub) -> *XExposeEvent unsafe {
    unsafe::reinterpret_cast(ptr::addr_of((*event).padding))
}

#[test]
#[ignore]
fn cairo_it_up() {
    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str("test") {|cstr|
        XStoreName(dpy, win, cstr);
    }
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(e);

    let dt = AzCreateDrawTargetForCairoSurface(cs);

    loop unsafe {
        XNextEvent(dpy, unsafe::reinterpret_cast(ep));
        log(error, *ep);
        log(error, *xexpose(ep));
        if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
            paint(dt);
        } else if e.type_ == ButtonPress {
            break;
        } else {
            paint(dt);
        }
    }

    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);
}

fn paint(dt: AzDrawTargetRef) {
    log(error, "painting");
    let rect = {
        x: 200f as AzFloat,
        y: 200f as AzFloat,
        width: 100f as AzFloat,
        height: 100f as AzFloat
    };
    let color = {
        r: 0f as AzFloat,
        g: 1f as AzFloat,
        b: 0f as AzFloat,
        a: 1f as AzFloat
    };
    let pattern = AzCreateColorPattern(ptr::addr_of(color));
    AzDrawTargetFillRect(
        dt,
        ptr::addr_of(rect),
        unsafe { unsafe::reinterpret_cast(pattern) });
    AzReleaseColorPattern(pattern);
}

#[test]
fn test_draw_target_get_size() {
    let surface = cairo_image_surface_create(
        CAIRO_FORMAT_RGB24, 100 as c_int, 200 as c_int);
    assert surface.is_not_null();
    let dt = AzCreateDrawTargetForCairoSurface(surface);
    assert dt.is_not_null();
    let size = AzDrawTargetGetSize(dt);
    assert size.width == 100 as int32_t;
    assert size.height == 200 as int32_t;
    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(surface);
}

#[test]
fn fonts() {
    import cairo::*;
    import cairo::bindgen::*;

    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str("test") {|cstr|
        XStoreName(dpy, win, cstr);
    }
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(e);

    loop unsafe {
        XNextEvent(dpy, unsafe::reinterpret_cast(ep));
        log(error, *ep);
        log(error, *xexpose(ep));
        if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
            paint(cs);
        } else if e.type_ == ButtonPress {
            break;
        } else {
            paint(cs);
        }
    }

    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);

    fn paint(surf: *cairo_surface_t) {
        import libc::c_double;
        import cairo::*;
        import cairo::bindgen::*;

        let cr: *cairo_t = cairo_create(surf);
        assert cr.is_not_null();

        cairo_set_source_rgb(cr, 0.5 as c_double, 0.1 as c_double, 0.1 as c_double);
        cairo_paint(cr);

        let te: cairo_text_extents_t = {
            x_bearing: 0 as c_double,
            y_bearing: 0 as c_double,
            width: 0 as c_double,
            height: 0 as c_double,
            x_advance: 0 as c_double,
            y_advance: 0 as c_double
        };
        cairo_set_source_rgb(cr, 0.9 as c_double, 0.5 as c_double, 0.5 as c_double);
        str::as_c_str("Georgia") {|fontname|
            cairo_select_font_face(cr, fontname, CAIRO_FONT_SLANT_NORMAL,
                                   CAIRO_FONT_WEIGHT_BOLD);
        }
        cairo_set_font_size(cr, 20.2 as c_double);
        str::as_c_str("a") {|text|
            cairo_text_extents(cr, text, ptr::addr_of(te));
            cairo_move_to(cr,
                          100.0 + 0.5 - te.width / 2.0 - te.x_bearing,
                          100.0 + 0.5 - te.height / 2.0 - te.y_bearing);
            cairo_show_text(cr, text);
        }

        cairo_destroy(cr);
    }
}

<commit_msg>Ignore an interactive test that only works on linux<commit_after>import xlib::*;
import libc::*;
import cairo_xlib::*;
import xlib::bindgen::*;
import cairo::*;
import cairo::bindgen::*;
import cairo_xlib::bindgen::*;

#[test]
fn sanity_check() {
    AzSanityCheck();
}

const SIZEX: c_uint = 400 as c_uint;
const SIZEY: c_uint = 400 as c_uint;

const ExposureMask: c_long = (1 << 15) as c_long;
const ButtonPressMask: c_long = (1 << 2) as c_long;

const Expose: c_int = 12 as c_int;
const ButtonPress: c_int = 4 as c_int;

type XEventStub = {
    type_: c_int,
    padding: (
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int
    )
};

fn xexpose(event: *XEventStub) -> *XExposeEvent unsafe {
    unsafe::reinterpret_cast(ptr::addr_of((*event).padding))
}

#[test]
#[ignore]
fn cairo_it_up() {
    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str("test") {|cstr|
        XStoreName(dpy, win, cstr);
    }
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(e);

    let dt = AzCreateDrawTargetForCairoSurface(cs);

    loop unsafe {
        XNextEvent(dpy, unsafe::reinterpret_cast(ep));
        log(error, *ep);
        log(error, *xexpose(ep));
        if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
            paint(dt);
        } else if e.type_ == ButtonPress {
            break;
        } else {
            paint(dt);
        }
    }

    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);
}

fn paint(dt: AzDrawTargetRef) {
    log(error, "painting");
    let rect = {
        x: 200f as AzFloat,
        y: 200f as AzFloat,
        width: 100f as AzFloat,
        height: 100f as AzFloat
    };
    let color = {
        r: 0f as AzFloat,
        g: 1f as AzFloat,
        b: 0f as AzFloat,
        a: 1f as AzFloat
    };
    let pattern = AzCreateColorPattern(ptr::addr_of(color));
    AzDrawTargetFillRect(
        dt,
        ptr::addr_of(rect),
        unsafe { unsafe::reinterpret_cast(pattern) });
    AzReleaseColorPattern(pattern);
}

#[test]
fn test_draw_target_get_size() {
    let surface = cairo_image_surface_create(
        CAIRO_FORMAT_RGB24, 100 as c_int, 200 as c_int);
    assert surface.is_not_null();
    let dt = AzCreateDrawTargetForCairoSurface(surface);
    assert dt.is_not_null();
    let size = AzDrawTargetGetSize(dt);
    assert size.width == 100 as int32_t;
    assert size.height == 200 as int32_t;
    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(surface);
}

#[test]
#[ignore]
fn fonts() {
    import cairo::*;
    import cairo::bindgen::*;

    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str("test") {|cstr|
        XStoreName(dpy, win, cstr);
    }
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(e);

    loop unsafe {
        XNextEvent(dpy, unsafe::reinterpret_cast(ep));
        log(error, *ep);
        log(error, *xexpose(ep));
        if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
            paint(cs);
        } else if e.type_ == ButtonPress {
            break;
        } else {
            paint(cs);
        }
    }

    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);

    fn paint(surf: *cairo_surface_t) {
        import libc::c_double;
        import cairo::*;
        import cairo::bindgen::*;

        let cr: *cairo_t = cairo_create(surf);
        assert cr.is_not_null();

        cairo_set_source_rgb(cr, 0.5 as c_double, 0.1 as c_double, 0.1 as c_double);
        cairo_paint(cr);

        let te: cairo_text_extents_t = {
            x_bearing: 0 as c_double,
            y_bearing: 0 as c_double,
            width: 0 as c_double,
            height: 0 as c_double,
            x_advance: 0 as c_double,
            y_advance: 0 as c_double
        };
        cairo_set_source_rgb(cr, 0.9 as c_double, 0.5 as c_double, 0.5 as c_double);
        str::as_c_str("Georgia") {|fontname|
            cairo_select_font_face(cr, fontname, CAIRO_FONT_SLANT_NORMAL,
                                   CAIRO_FONT_WEIGHT_BOLD);
        }
        cairo_set_font_size(cr, 20.2 as c_double);
        str::as_c_str("a") {|text|
            cairo_text_extents(cr, text, ptr::addr_of(te));
            cairo_move_to(cr,
                          100.0 + 0.5 - te.width / 2.0 - te.x_bearing,
                          100.0 + 0.5 - te.height / 2.0 - te.y_bearing);
            cairo_show_text(cr, text);
        }

        cairo_destroy(cr);
    }
}

<|endoftext|>


<commit_before>use cortexm3;
use main::Chip;
use gpio;
use uart;

pub struct Hotel {
    mpu: cortexm3::mpu::MPU,
    systick: &'static cortexm3::systick::SysTick,
}

impl Hotel {
    pub unsafe fn new() -> Hotel {
        Hotel {
            mpu: cortexm3::mpu::MPU::new(),
            systick: cortexm3::systick::SysTick::new(),
        }
    }
}

impl Chip for Hotel {
    type MPU = cortexm3::mpu::MPU;
    type SysTick = cortexm3::systick::SysTick;

    fn has_pending_interrupts(&self) -> bool {
        unsafe { cortexm3::nvic::next_pending().is_some() }
    }

    fn service_pending_interrupts(&mut self) {
        unsafe {
            cortexm3::nvic::next_pending().map(|nvic_num| {
                match nvic_num {
                    174 => uart::UART0.handle_rx_interrupt(),
                    177 => uart::UART0.handle_tx_interrupt(),
                    181 => uart::UART1.handle_rx_interrupt(),
                    184 => uart::UART1.handle_tx_interrupt(),
                    188 => uart::UART2.handle_rx_interrupt(),
                    191 => uart::UART2.handle_tx_interrupt(),

                    pin @ 65 ... 80 => {
                        gpio::PORT0.pins[(pin - 65) as usize].handle_interrupt();
                    },
                    81 => { /* GPIO Combined interrupt... why does this remain asserted? */ },
                    _ => panic!("Unexected ISR {}", nvic_num),
                }
                cortexm3::nvic::Nvic::new(nvic_num).clear_pending();
                cortexm3::nvic::Nvic::new(nvic_num).enable();
            });
        }
    }

    fn mpu(&self) -> &Self::MPU {
        &self.mpu
    }

    fn systick(&self) -> &Self::SysTick {
        &self.systick
    }
}
<commit_msg>Add gpio port 1 interrupts to hotel<commit_after>use cortexm3;
use main::Chip;
use gpio;
use uart;

pub struct Hotel {
    mpu: cortexm3::mpu::MPU,
    systick: &'static cortexm3::systick::SysTick,
}

impl Hotel {
    pub unsafe fn new() -> Hotel {
        Hotel {
            mpu: cortexm3::mpu::MPU::new(),
            systick: cortexm3::systick::SysTick::new(),
        }
    }
}

impl Chip for Hotel {
    type MPU = cortexm3::mpu::MPU;
    type SysTick = cortexm3::systick::SysTick;

    fn has_pending_interrupts(&self) -> bool {
        unsafe { cortexm3::nvic::next_pending().is_some() }
    }

    fn service_pending_interrupts(&mut self) {
        unsafe {
            cortexm3::nvic::next_pending().map(|nvic_num| {
                match nvic_num {
                    174 => uart::UART0.handle_rx_interrupt(),
                    177 => uart::UART0.handle_tx_interrupt(),
                    181 => uart::UART1.handle_rx_interrupt(),
                    184 => uart::UART1.handle_tx_interrupt(),
                    188 => uart::UART2.handle_rx_interrupt(),
                    191 => uart::UART2.handle_tx_interrupt(),

                    pin @ 65 ... 80 => {
                        gpio::PORT0.pins[(pin - 65) as usize].handle_interrupt();
                    },
                    81 => { /* GPIO Combined interrupt... why does this remain asserted? */ },
                    pin @ 82 ... 97 => {
                        gpio::PORT1.pins[(pin - 82) as usize].handle_interrupt();
                    },
                    98 => { /* GPIO Combined interrupt... why does this remain asserted? */ },
                    _ => panic!("Unexected ISR {}", nvic_num),
                }
                cortexm3::nvic::Nvic::new(nvic_num).clear_pending();
                cortexm3::nvic::Nvic::new(nvic_num).enable();
            });
        }
    }

    fn mpu(&self) -> &Self::MPU {
        &self.mpu
    }

    fn systick(&self) -> &Self::SysTick {
        &self.systick
    }
}
<|endoftext|>


<commit_before><commit_msg>style: convert NS_STYLE_TEXT_ORIENTATION_* to an enum class in nsStyleConsts.h<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate abomonation_derive;
extern crate abomonation;

extern crate rand;
extern crate timely;
extern crate differential_dataflow;

use rand::{Rng, SeedableRng, StdRng};

use timely::dataflow::ProbeHandle;
// use timely::progress::timestamp::RootTimestamp;

use timely::dataflow::operators::unordered_input::UnorderedInput;

use differential_dataflow::AsCollection;
use differential_dataflow::operators::*;

use pair::Pair;

fn main() {

    let nodes: usize = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: usize = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: usize = std::env::args().nth(3).unwrap().parse().unwrap();
    let rounds: usize = std::env::args().nth(4).unwrap().parse().unwrap();

    timely::execute_from_args(std::env::args().skip(5), move |worker| {

        let index = worker.index();
        let peers = worker.peers();
        let mut probe = ProbeHandle::new();

        let (mut root_input, root_cap, mut edge_input, mut edge_cap) =
        worker.dataflow(|scope| {

            let ((root_input, root_cap), roots) = scope.new_unordered_input();
            let ((edge_input, edge_cap), edges) = scope.new_unordered_input();

            let roots = roots.as_collection();
            let edges = edges.as_collection()
                             // .inspect(|x| println!("edge: {:?}", x))
                             ;

            roots.iterate(|inner| {

                let edges = edges.enter(&inner.scope());
                let roots = roots.enter(&inner.scope());

                edges
                    .semijoin(&inner)
                    .map(|(_s,d)| d)
                    .concat(&roots)
                    .distinct()
            })
            .consolidate()
            .inspect(|x| println!("edge: {:?}", x))
            .map(|_| ())
            .consolidate()
            // .inspect(|x| println!("{:?}\tchanges: {:?}", x.1, x.2))
            .probe_with(&mut probe);

            (root_input, root_cap, edge_input, edge_cap)
        });

        let seed: &[_] = &[1, 2, 3, index];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        let worker_edges = edges / peers + if index < edges % peers { 1 } else { 0 };
        let worker_batch = batch / peers + if index < batch % peers { 1 } else { 0 };

        // Times: (revision, event_time)

        // load initial root.
        root_input
            .session(root_cap)
            .give((0, Pair::new(0, 0), 1));

        // load initial edges
        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_edges).map(|_|
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)),
                    Pair::new(0, 0), 1)
            ));

        let edge_cap_next = edge_cap.delayed(&Pair::new(1, 0));

        // Caps = { (1,0) , (0,1) }

        edge_cap.downgrade(&Pair::new(0, 1));
        while probe.less_than(edge_cap.time()) {
            worker.step();
        }

        println!("Initial computation complete");

        for round in 1 .. rounds {

            edge_input
                .session(edge_cap.clone())
                .give_iterator((0 .. worker_batch).flat_map(|_| {
                    let insert = ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(0, round), 1);
                    let remove = ((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)), Pair::new(0, round),-1);
                    Some(insert).into_iter().chain(Some(remove).into_iter())
                }));

            edge_cap.downgrade(&Pair::new(0, round+1));
            while probe.less_than(edge_cap.time()) {
                worker.step();
            }

            // Caps = { (1,0), (0,round+1) }
            println!("Initial round {} complete", round);
        }

        // Caps = { (1,0) }
        edge_cap = edge_cap_next;

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(1, 0), 1)
            }));

        // Caps = { (2,0) }
        edge_cap.downgrade(&Pair::new(2, 0));
        while probe.less_than(&Pair::new(1, rounds+1)) {
            worker.step();
        }

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(2, 3), 1)
            }));

        // Caps = { (3,0) }
        edge_cap.downgrade(&Pair::new(3, 0));
        while probe.less_than(&Pair::new(2, rounds+1)) {
            worker.step();
        }

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(3, 1), 1)
            }));

        // Caps = { (4,0) }
        edge_cap.downgrade(&Pair::new(4, 0));
        while probe.less_than(&Pair::new(3, rounds+1)) {
            worker.step();
        }

    }).unwrap();
}

/// This module contains a definition of a new timestamp time, a "pair" or product.
///
/// This is a minimal self-contained implementation, in that it doesn't borrow anything
/// from the rest of the library other than the traits it needs to implement. With this
/// type and its implementations, you can use it as a timestamp type.
mod pair {

    /// A pair of timestamps, partially ordered by the product order.
    #[derive(Debug, Hash, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Abomonation)]
    pub struct Pair<S, T> {
        pub first: S,
        pub second: T,
    }

    impl<S, T> Pair<S, T> {
        /// Create a new pair.
        pub fn new(first: S, second: T) -> Self {
            Pair { first, second }
        }
    }

    // Implement timely dataflow's `PartialOrder` trait.
    use timely::order::PartialOrder;
    impl<S: PartialOrder, T: PartialOrder> PartialOrder for Pair<S, T> {
        fn less_equal(&self, other: &Self) -> bool {
            self.first.less_equal(&other.first) && self.second.less_equal(&other.second)
        }
    }

    use timely::progress::timestamp::Refines;
    impl<S: Timestamp, T: Timestamp> Refines<()> for Pair<S, T> {
        fn to_inner(outer: ()) -> Self { Default::default() }
        fn to_outer(self) -> () { () }
        fn summarize(summary: <Self>::Summary) -> () { () }
    }

    // Implement timely dataflow's `PathSummary` trait.
    // This is preparation for the `Timestamp` implementation below.
    use timely::progress::PathSummary;
    // impl<S: Timestamp, T: Timestamp> PathSummary<Pair<S,T>> for Pair<<S as Timestamp>::Summary, <T as Timestamp>::Summary> {
    //     fn results_in(&self, timestamp: &Pair<S, T>) -> Option<Pair<S,T>> {
    //         if let Some(s) = self.first.results_in(&timestamp.first) {
    //             if let Some(t) = self.second.results_in(&timestamp.second) {
    //                 Some(Pair::new(s,t))
    //             }
    //             else { None }
    //         }
    //         else { None }
    //     }
    //     fn followed_by(&self, other: &Self) -> Option<Self> {
    //         if let Some(s) = self.first.followed_by(&other.first) {
    //             if let Some(t) = self.second.followed_by(&other.second) {
    //                 Some(Pair::new(s,t))
    //             }
    //             else { None }
    //         }
    //         else { None }
    //     }
    // }

    impl<S: Timestamp, T: Timestamp> PathSummary<Pair<S,T>> for () {
        fn results_in(&self, timestamp: &Pair<S, T>) -> Option<Pair<S,T>> {
            Some(timestamp.clone())
        }
        fn followed_by(&self, other: &Self) -> Option<Self> {
            Some(other.clone())
        }
    }

    // Implement timely dataflow's `Timestamp` trait.
    use timely::progress::Timestamp;
    impl<S: Timestamp, T: Timestamp> Timestamp for Pair<S, T> {
        type Summary = ();//Pair<<S as Timestamp>::Summary, <T as Timestamp>::Summary>;
    }

    // Implement differential dataflow's `Lattice` trait.
    // This extends the `PartialOrder` implementation with additional structure.
    use differential_dataflow::lattice::Lattice;
    impl<S: Lattice, T: Lattice> Lattice for Pair<S, T> {
        fn minimum() -> Self { Pair { first: S::minimum(), second: T::minimum() }}
        fn maximum() -> Self { Pair { first: S::maximum(), second: T::maximum() }}
        fn join(&self, other: &Self) -> Self {
            Pair {
                first: self.first.join(&other.first),
                second: self.second.join(&other.second),
            }
        }
        fn meet(&self, other: &Self) -> Self {
            Pair {
                first: self.first.meet(&other.first),
                second: self.second.meet(&other.second),
            }
        }
    }
}<commit_msg>multitemporal<commit_after>#[macro_use]
extern crate abomonation_derive;
extern crate abomonation;

extern crate rand;
extern crate timely;
extern crate differential_dataflow;

use rand::{Rng, SeedableRng, StdRng};

use timely::dataflow::ProbeHandle;
// use timely::progress::timestamp::RootTimestamp;

use timely::dataflow::operators::unordered_input::UnorderedInput;

use differential_dataflow::AsCollection;
use differential_dataflow::operators::*;

use pair::Pair;

fn main() {

    let nodes: usize = std::env::args().nth(1).unwrap().parse().unwrap();
    let edges: usize = std::env::args().nth(2).unwrap().parse().unwrap();
    let batch: usize = std::env::args().nth(3).unwrap().parse().unwrap();
    let rounds: usize = std::env::args().nth(4).unwrap().parse().unwrap();

    timely::execute_from_args(std::env::args().skip(5), move |worker| {

        let index = worker.index();
        let peers = worker.peers();
        let mut probe = ProbeHandle::new();

        let (mut root_input, root_cap, mut edge_input, mut edge_cap) =
        worker.dataflow(|scope| {

            let ((root_input, root_cap), roots) = scope.new_unordered_input();
            let ((edge_input, edge_cap), edges) = scope.new_unordered_input();

            let roots = roots.as_collection();
            let edges = edges.as_collection()
                             // .inspect(|x| println!("edge: {:?}", x))
                             ;

            roots.iterate(|inner| {

                let edges = edges.enter(&inner.scope());
                let roots = roots.enter(&inner.scope());

                edges
                    .semijoin(&inner)
                    .map(|(_s,d)| d)
                    .concat(&roots)
                    .distinct()
            })
            .consolidate()
            // .inspect(|x| println!("edge: {:?}", x))
            .map(|_| ())
            .consolidate()
            .inspect(|x| println!("{:?}\tchanges: {:?}", x.1, x.2))
            .probe_with(&mut probe);

            (root_input, root_cap, edge_input, edge_cap)
        });

        let seed: &[_] = &[1, 2, 3, index];
        let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
        let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

        let worker_edges = edges / peers + if index < edges % peers { 1 } else { 0 };
        let worker_batch = batch / peers + if index < batch % peers { 1 } else { 0 };

        // Times: (revision, event_time)

        // load initial root.
        root_input
            .session(root_cap)
            .give((0, Pair::new(0, 0), 1));

        // load initial edges
        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_edges).map(|_|
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)),
                    Pair::new(0, 0), 1)
            ));

        let edge_cap_next = edge_cap.delayed(&Pair::new(1, 0));

        // Caps = { (1,0) , (0,1) }

        edge_cap.downgrade(&Pair::new(0, 1));
        while probe.less_than(edge_cap.time()) {
            worker.step();
        }

        println!("Initial computation complete");

        for round in 1 .. rounds {

            edge_input
                .session(edge_cap.clone())
                .give_iterator((0 .. worker_batch).flat_map(|_| {
                    let insert = ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(0, round), 1);
                    let remove = ((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)), Pair::new(0, round),-1);
                    Some(insert).into_iter().chain(Some(remove).into_iter())
                }));

            edge_cap.downgrade(&Pair::new(0, round+1));
            while probe.less_than(edge_cap.time()) {
                worker.step();
            }

            // Caps = { (1,0), (0,round+1) }
            println!("Initial round {} complete", round);
        }

        // Caps = { (1,0) }
        let edge_cap0 = edge_cap;
        println!("{:?}", edge_cap0);
        edge_cap = edge_cap_next;

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(1, 0), 1)
            }));

        // Caps = { (2,0) }
        edge_cap.downgrade(&Pair::new(2, 0));
        while probe.less_equal(&Pair::new(1, rounds-1)) {
            worker.step();
        }

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(2, 3), 1)
            }));

        // Caps = { (3,0) }
        edge_cap.downgrade(&Pair::new(3, 0));
        while probe.less_equal(&Pair::new(2, rounds-1)) {
            worker.step();
        }

        edge_input
            .session(edge_cap.clone())
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(3, 1), 1)
            }));

        // Caps = { (4,0) }
        edge_cap.downgrade(&Pair::new(4, 0));
        while probe.less_equal(&Pair::new(3, rounds-1)) {
            worker.step();
        }

        edge_input
            .session(edge_cap0)
            .give_iterator((0 .. worker_batch).map(|_| {
                ((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), Pair::new(0, 10), 1)
            }));

    }).unwrap();
}

/// This module contains a definition of a new timestamp time, a "pair" or product.
///
/// This is a minimal self-contained implementation, in that it doesn't borrow anything
/// from the rest of the library other than the traits it needs to implement. With this
/// type and its implementations, you can use it as a timestamp type.
mod pair {

    /// A pair of timestamps, partially ordered by the product order.
    #[derive(Hash, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Abomonation)]
    pub struct Pair<S, T> {
        pub first: S,
        pub second: T,
    }

    impl<S, T> Pair<S, T> {
        /// Create a new pair.
        pub fn new(first: S, second: T) -> Self {
            Pair { first, second }
        }
    }

    // Implement timely dataflow's `PartialOrder` trait.
    use timely::order::PartialOrder;
    impl<S: PartialOrder, T: PartialOrder> PartialOrder for Pair<S, T> {
        fn less_equal(&self, other: &Self) -> bool {
            self.first.less_equal(&other.first) && self.second.less_equal(&other.second)
        }
    }

    use timely::progress::timestamp::Refines;
    impl<S: Timestamp, T: Timestamp> Refines<()> for Pair<S, T> {
        fn to_inner(_outer: ()) -> Self { Default::default() }
        fn to_outer(self) -> () { () }
        fn summarize(_summary: <Self>::Summary) -> () { () }
    }

    // Implement timely dataflow's `PathSummary` trait.
    // This is preparation for the `Timestamp` implementation below.
    use timely::progress::PathSummary;
    // impl<S: Timestamp, T: Timestamp> PathSummary<Pair<S,T>> for Pair<<S as Timestamp>::Summary, <T as Timestamp>::Summary> {
    //     fn results_in(&self, timestamp: &Pair<S, T>) -> Option<Pair<S,T>> {
    //         if let Some(s) = self.first.results_in(&timestamp.first) {
    //             if let Some(t) = self.second.results_in(&timestamp.second) {
    //                 Some(Pair::new(s,t))
    //             }
    //             else { None }
    //         }
    //         else { None }
    //     }
    //     fn followed_by(&self, other: &Self) -> Option<Self> {
    //         if let Some(s) = self.first.followed_by(&other.first) {
    //             if let Some(t) = self.second.followed_by(&other.second) {
    //                 Some(Pair::new(s,t))
    //             }
    //             else { None }
    //         }
    //         else { None }
    //     }
    // }

    impl<S: Timestamp, T: Timestamp> PathSummary<Pair<S,T>> for () {
        fn results_in(&self, timestamp: &Pair<S, T>) -> Option<Pair<S,T>> {
            Some(timestamp.clone())
        }
        fn followed_by(&self, other: &Self) -> Option<Self> {
            Some(other.clone())
        }
    }

    // Implement timely dataflow's `Timestamp` trait.
    use timely::progress::Timestamp;
    impl<S: Timestamp, T: Timestamp> Timestamp for Pair<S, T> {
        type Summary = ();//Pair<<S as Timestamp>::Summary, <T as Timestamp>::Summary>;
    }

    // Implement differential dataflow's `Lattice` trait.
    // This extends the `PartialOrder` implementation with additional structure.
    use differential_dataflow::lattice::Lattice;
    impl<S: Lattice, T: Lattice> Lattice for Pair<S, T> {
        fn minimum() -> Self { Pair { first: S::minimum(), second: T::minimum() }}
        fn maximum() -> Self { Pair { first: S::maximum(), second: T::maximum() }}
        fn join(&self, other: &Self) -> Self {
            Pair {
                first: self.first.join(&other.first),
                second: self.second.join(&other.second),
            }
        }
        fn meet(&self, other: &Self) -> Self {
            Pair {
                first: self.first.meet(&other.first),
                second: self.second.meet(&other.second),
            }
        }
    }

    use std::fmt::{Formatter, Error, Debug};

    /// Debug implementation to avoid seeing fully qualified path names.
    impl<TOuter: Debug, TInner: Debug> Debug for Pair<TOuter, TInner> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        f.write_str(&format!("({:?}, {:?})", self.first, self.second))
    }
}

}<|endoftext|>


<commit_before><commit_msg>Add main function file of assembling.<commit_after>fn main() {
  println!("A new git server developed with Rust")
}
<|endoftext|>


<commit_before><commit_msg>Replace the closure in `layout_in_flow_non_replaced_block_level` with an enum<commit_after><|endoftext|>


<commit_before><commit_msg>Move ingest into an object.<commit_after><|endoftext|>


<commit_before><commit_msg>removed unused variable in build.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Rename the main shader in Planet as 'land' to match 'water'<commit_after><|endoftext|>


<commit_before><commit_msg>Use match rather than if/else if (#192)<commit_after><|endoftext|>


<commit_before><commit_msg>chars are in glyphs guaranteed<commit_after><|endoftext|>


<commit_before><commit_msg>Add lints<commit_after><|endoftext|>


<commit_before><commit_msg>Got the CLI working<commit_after><|endoftext|>


<commit_before><commit_msg>Move CtlFlags to its own file<commit_after>// ctl_flags.rs

use super::consts::*;

// Represents control flags of a sysctl
bitflags! {
    pub struct CtlFlags : libc::c_uint {
        /// Allow reads of variable
        const RD = CTLFLAG_RD;

        /// Allow writes to the variable
        const WR = CTLFLAG_WR;

        const RW = Self::RD.bits | Self::WR.bits;

        /// This sysctl is not active yet
        const DORMANT = CTLFLAG_DORMANT;

        /// All users can set this var
        const ANYBODY = CTLFLAG_ANYBODY;

        /// Permit set only if securelevel<=0
        const SECURE = CTLFLAG_SECURE;

        /// Prisoned roots can fiddle
        const PRISON = CTLFLAG_PRISON;

        /// Dynamic oid - can be freed
        const DYN = CTLFLAG_DYN;

        /// Skip this sysctl when listing
        const SKIP = CTLFLAG_DORMANT;

        /// Secure level
        const SECURE_MASK = 0x00F00000;

        /// Default value is loaded from getenv()
        const TUN = CTLFLAG_TUN;

        /// Readable tunable
        const RDTUN = Self::RD.bits | Self::TUN.bits;

        /// Readable and writeable tunable
        const RWTUN = Self::RW.bits | Self::TUN.bits;

        /// Handler is MP safe
        const MPSAFE = CTLFLAG_MPSAFE;

        /// Prisons with vnet can fiddle
        const VNET = CTLFLAG_VNET;

        /// Oid is being removed
        const DYING = CTLFLAG_DYING;

        /// Can be read in capability mode
        const CAPRD = CTLFLAG_CAPRD;

        /// Can be written in capability mode
        const CAPWR = CTLFLAG_CAPWR;

        /// Statistics; not a tuneable
        const STATS = CTLFLAG_STATS;

        /// Don't fetch tunable from getenv()
        const NOFETCH = CTLFLAG_NOFETCH;

        /// Can be read and written in capability mode
        const CAPRW = Self::CAPRD.bits | Self::CAPWR.bits;
    }
}

#[cfg(test)]
mod tests {
    use crate::Sysctl;

    #[test]
    fn ctl_flags() {
        // This sysctl should be read-only.
        #[cfg(any(target_os = "freebsd", target_os = "macos"))]
        let ctl: crate::Ctl = crate::Ctl::new("kern.ostype").unwrap();
        #[cfg(any(target_os = "android", target_os = "linux"))]
        let ctl: crate::Ctl = crate::Ctl::new("kernel.ostype").unwrap();

        let flags: crate::CtlFlags = ctl.flags().unwrap();

        assert_eq!(flags.bits() & crate::CTLFLAG_RD, crate::CTLFLAG_RD);
        assert_eq!(flags.bits() & crate::CTLFLAG_WR, 0);
    }
}
<|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before>use std::process::Command;
use std::env;

fn main() {
    let curr_dir = Path::new(env::var("CARGO_MANIFEST_DIR").unwrap());
    Command::new("git").arg("submodule").arg("update").arg("--init")
        .current_dir(&curr_dir).status().unwrap();
}
<commit_msg>Silence warnings<commit_after>#![feature(path)]

use std::path::Path;
use std::process::Command;
use std::env;

fn main() {
    let curr_path_str = env::var("CARGO_MANIFEST_DIR").unwrap();
    let curr_path = Path::new(&curr_path_str);
    Command::new("git").arg("submodule").arg("update").arg("--init")
        .current_dir(&curr_path).status().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>add module for testing tags<commit_after>use crate::query_testing::{parse_position_comments, Assertion};
use ansi_term::Colour;
use anyhow::{anyhow, Result};
use std::fs;
use std::path::Path;
use tree_sitter::Point;
use tree_sitter_loader::Loader;
use tree_sitter_tags::{TagsConfiguration, TagsContext};

#[derive(Debug)]
pub struct Failure {
    row: usize,
    column: usize,
    expected_tag: String,
    actual_tags: Vec<String>,
}

impl std::error::Error for Failure {}

impl std::fmt::Display for Failure {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(
            f,
            "Failure - row: {}, column: {}, expected tag: '{}', actual tag: ",
            self.row, self.column, self.expected_tag
        )?;
        if self.actual_tags.is_empty() {
            write!(f, "none.")?;
        } else {
            for (i, actual_tag) in self.actual_tags.iter().enumerate() {
                if i > 0 {
                    write!(f, ", ")?;
                }
                write!(f, "'{}'", actual_tag)?;
            }
        }
        Ok(())
    }
}

pub fn test_tags(loader: &Loader, directory: &Path) -> Result<()> {
    let mut failed = false;
    let mut tags_context = TagsContext::new();

    println!("tags:");
    for tag_test_file in fs::read_dir(directory)? {
        let tag_test_file = tag_test_file?;
        let test_file_path = tag_test_file.path();
        let test_file_name = tag_test_file.file_name();
        let (language, language_config) = loader
            .language_configuration_for_file_name(&test_file_path)?
            .ok_or_else(|| anyhow!("No language found for path {:?}", test_file_path))?;
        let tags_config = language_config
            .tags_config(language)?
            .ok_or_else(|| anyhow!("No tags config found for {:?}", test_file_path))?;
        match test_tag(
            &mut tags_context,
            tags_config,
            fs::read(&test_file_path)?.as_slice(),
        ) {
            Ok(assertion_count) => {
                println!(
                    "  ✓ {} ({} assertions)",
                    Colour::Green.paint(test_file_name.to_string_lossy().as_ref()),
                    assertion_count
                );
            }
            Err(e) => {
                println!(
                    "  ✗ {}",
                    Colour::Red.paint(test_file_name.to_string_lossy().as_ref())
                );
                println!("    {}", e);
                failed = true;
            }
        }
    }

    if failed {
        Err(anyhow!(""))
    } else {
        Ok(())
    }
}

pub fn test_tag(
    tags_context: &mut TagsContext,
    tags_config: &TagsConfiguration,
    source: &[u8],
) -> Result<usize> {
    let (tags_iter, _has_error) = tags_context.generate_tags(&tags_config, &source, None)?;
    let tags: Vec<Tag> = tags_iter.filter_map(|t| t.ok()).collect();
    let assertions = parse_position_comments(tags_context.parser(), tags_config.language, source)?;

    // Iterate through all of the assertions, checking against the actual tags.
    let mut i = 0;
    let mut actual_tags = Vec::<String>::new();
    for Assertion {
        position,
        expected_capture_name: expected_tag,
    } in &assertions
    {
        let mut passed = false;

        'tag_loop: loop {
            if let Some(tag) = tags.get(i) {
                if tag.span.end <= *position {
                    i += 1;
                    continue;
                }

                // Iterate through all of the tags that start at or before this assertion's
                // position, looking for one that matches the assertion
                let mut j = i;
                while let (false, Some(tag)) = (passed, tags.get(j)) {
                    if tag.span.start > *position {
                        break 'tag_loop;
                    }

                    let tag_postfix = tags_config.syntax_type_name(tag.syntax_type_id).to_string();
                    let tag_name = if tag.is_definition {
                        format!("definition.{}", tag_postfix)
                    } else {
                        format!("reference.{}", tag_postfix)
                    };

                    if tag_name == *expected_tag {
                        passed = true;
                        break 'tag_loop;
                    } else {
                        actual_tags.push(tag_name);
                    }

                    j += 1;
                }
            } else {
                break;
            }
        }

        if !passed {
            return Err(Failure {
                row: position.row,
                column: position.column,
                expected_tag: expected_tag.clone(),
                actual_tags: actual_tags.into_iter().collect(),
            }
            .into());
        }
    }

    Ok(assertions.len())
}
<|endoftext|>


<commit_before><commit_msg>Dummy Commit<commit_after><|endoftext|>


<commit_before><commit_msg>bash/fish<commit_after>#![allow(unused_mut)]
#![allow(unused_imports)]
#![allow(unused_variables)]

#[macro_use] extern crate clap;

use clap::Shell;
use clap::App;

fn main() {

    // load configuration
    let yaml = load_yaml!("src/options-en.yml");
    let mut app = App::from_yaml(yaml).version(crate_version!());

    // generate bash completions if desired
    #[cfg(feature = "bash")]
    app.gen_completions("sniff",          // We need to specify the bin name manually
                        Shell::Bash,      // Then say which shell to build completions for
                        env!("BASH_COMPLETIONS_DIR")); // Then say where write the completions to

    // generate fish completions if desired
    let mut app_snd = App::from_yaml(yaml).version(crate_version!());
    #[cfg(feature = "fish")]
    app_snd.gen_completions("sniff",          // We need to specify the bin name manually
                        Shell::Fish,      // Then say which shell to build completions for
                        env!("FISH_COMPLETIONS_DIR")); // Then say where write the completions to

}
<|endoftext|>


<commit_before><commit_msg>mingw build work<commit_after><|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Types dealing with unsafe actions.

use cast;
use kinds::marker;

/// Unsafe type that wraps a type T and indicates unsafe interior operations on the
/// wrapped type. Types with an `Unsafe<T>` field are considered to have an *unsafe
/// interior*. The Unsafe type is the only legal way to obtain aliasable data that is
/// considered mutable. In general, transmuting an &T type into an &mut T is considered
/// undefined behavior.
///
/// Although it is possible to put an Unsafe<T> into static item, it is not permitted to
/// take the address of the static item if the item is not declared as mutable. This rule
/// exists because immutable static items are stored in read-only memory, and thus any
/// attempt to mutate their interior can cause segfaults. Immutable static items containing
/// Unsafe<T> instances are still useful as read-only initializers, however, so we do not
/// forbid them altogether.
///
/// Types like `Cell` and `RefCell` use this type to wrap their internal data.
///
/// Unsafe doesn't opt-out from any kind, instead, types with an `Unsafe` interior
/// are expected to opt-out from kinds themselves.
///
/// # Example:
///
/// ```rust
/// use std::ty::Unsafe;
/// use std::kinds::marker;
///
/// struct NotThreadSafe<T> {
///     value: Unsafe<T>,
///     marker1: marker::NoShare
/// }
/// ```
///
/// **NOTE:** Unsafe<T> fields are public to allow static initializers. It is not recommended
/// to access its fields directly, `get` should be used instead.
#[lang="unsafe"]
pub struct Unsafe<T> {
    /// Wrapped value
    pub value: T,

    /// Invariance marker
    pub marker1: marker::InvariantType<T>
}

impl<T> Unsafe<T> {

    /// Static constructor
    pub fn new(value: T) -> Unsafe<T> {
        Unsafe{value: value, marker1: marker::InvariantType}
    }

    /// Gets a mutable pointer to the wrapped value
    #[inline]
    pub unsafe fn get(&self) -> *mut T { cast::transmute(&self.value) }

    /// Unwraps the value
    #[inline]
    pub unsafe fn unwrap(self) -> T { self.value }
}
<commit_msg>auto merge of #13343 : tbu-/rust/pr_smallfix, r=pcwalton<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Types dealing with unsafe actions.

use cast;
use kinds::marker;

/// Unsafe type that wraps a type T and indicates unsafe interior operations on the
/// wrapped type. Types with an `Unsafe<T>` field are considered to have an *unsafe
/// interior*. The Unsafe type is the only legal way to obtain aliasable data that is
/// considered mutable. In general, transmuting an &T type into an &mut T is considered
/// undefined behavior.
///
/// Although it is possible to put an Unsafe<T> into static item, it is not permitted to
/// take the address of the static item if the item is not declared as mutable. This rule
/// exists because immutable static items are stored in read-only memory, and thus any
/// attempt to mutate their interior can cause segfaults. Immutable static items containing
/// Unsafe<T> instances are still useful as read-only initializers, however, so we do not
/// forbid them altogether.
///
/// Types like `Cell` and `RefCell` use this type to wrap their internal data.
///
/// Unsafe doesn't opt-out from any kind, instead, types with an `Unsafe` interior
/// are expected to opt-out from kinds themselves.
///
/// # Example:
///
/// ```rust
/// use std::ty::Unsafe;
/// use std::kinds::marker;
///
/// struct NotThreadSafe<T> {
///     value: Unsafe<T>,
///     marker1: marker::NoShare
/// }
/// ```
///
/// **NOTE:** Unsafe<T> fields are public to allow static initializers. It is not recommended
/// to access its fields directly, `get` should be used instead.
#[lang="unsafe"]
pub struct Unsafe<T> {
    /// Wrapped value
    pub value: T,

    /// Invariance marker
    pub marker1: marker::InvariantType<T>
}

impl<T> Unsafe<T> {

    /// Static constructor
    pub fn new(value: T) -> Unsafe<T> {
        Unsafe{value: value, marker1: marker::InvariantType}
    }

    /// Gets a mutable pointer to the wrapped value
    #[inline]
    pub unsafe fn get(&self) -> *mut T { cast::transmute_mut_unsafe(&self.value) }

    /// Unwraps the value
    #[inline]
    pub unsafe fn unwrap(self) -> T { self.value }
}
<|endoftext|>


<commit_before><commit_msg>Add problem #89<commit_after>use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 89,
    answer: "743",
    solver: solve
};

static roman_pairs: &'static [(&'static str, uint)] = &[
    ("IV", 4),
    ("IX", 9),
    ("XL", 40),
    ("XC", 90),
    ("CD", 400),
    ("CM", 900),
    ("I", 1),
    ("V", 5),
    ("X", 10),
    ("L", 50),
    ("C", 100),
    ("D", 500),
    ("M", 1000)
];

fn from_roman(mut s: &str) -> Option<uint> {
    let mut last_d = uint::max_value;

    let mut n = 0;
    while !s.is_empty() {
        match roman_pairs.find(|&(ds, _d)| s.starts_with(ds)) {
            Some((ds, d)) => {
                if d > last_d { return None; }
                n += d;
                s = s.slice(ds.len(), s.len());
            }
            None => { return None; }
        }
    }

    return Some(n);
}

fn to_roman(mut n: uint) -> ~str {
    let mut s = ~"";
    while n >= 1000 { n -= 1000; s += "M"; }
    if n >= 900 { n -= 900; s += "CM"; }
    if n >= 500 { n -= 500; s += "D"; }
    if n >= 400 { n -= 400; s += "CD"; }
    while n >= 100 { n -= 100; s += "C"; }
    if n >= 90 { n -= 90; s += "XC"; }
    if n >= 50 { n -= 50; s += "L"; }
    if n >= 40 { n -= 40; s += "XL"; }
    while n >= 10 { n -= 10; s += "X"; }
    if n >= 9 { n -= 9; s += "IX"; }
    if n >= 5 { n -= 5; s += "V"; }
    if n >= 4 { n -= 4; s += "IV"; }
    while n > 0 { n -= 1; s += "I"; }
    return s;
}

fn solve() -> ~str {
    let result = io::file_reader(&Path("files/roman.txt")).map(|file| {
        let mut sum = 0;
        for file.each_line |line| {
            sum += line.len() - to_roman(from_roman(line).get()).len();
        }
        sum
    });

    match result {
        Err(msg) => fail!(msg),
        Ok(value) => return value.to_str()
    }
}
<|endoftext|>


<commit_before><commit_msg>Working recursive datatype<commit_after>fn main() {

	struct GoalExplore {
		name: ~str
	}

	struct GoalRest {
		name: ~str
	}

	trait Goal {
		fn new() -> Self;
		fn process(&self) { }
	}

	impl Goal for GoalExplore {
		fn new() -> GoalExplore {
			GoalExplore { name: ~"GoalExplore" }
		}

		fn process(&self) {
			println(fmt!("Exploring"));
		}
	}

	impl Goal for GoalRest {
		fn new() -> GoalRest {
			GoalRest { name: ~"GoalRest"}
		}

		fn process(&self) {
			println(fmt!("Resting"))
		}
	}

	enum Tree<T> {
		Leaf(T),
		Node(~[Tree<T>]),
	}

	//fn foo<G: Goal>(goal: &G) { .. }

	impl<T> Tree<T> {
		fn push(&mut self, node: Tree<T>) {
			match *self {
				Node(ref mut children) => children.push(node),
				Leaf(_) => fail!(~"Cannot add node to leaf node")
			}
		}

		/*fn to_str(&mut self) {
			match *self {
				Node(ref mut children) => for x in children.iter() { x.to_str() },
				Leaf(v) => ()//println!("{:?}", v)
			}
		}*/
	}

	let t: @GoalExplore = @Goal::new();
	t.process();
	let rest: @GoalRest = @Goal::new();
	rest.process();

	let mut tree: Tree<@Goal> = Node(~[]);

	tree.push(Leaf(t as @Goal));

	println!("{:?}", tree);
}
/*
enum Tree<T> {
	Leaf(T),
	Node { children: ~[Tree<T>] }
}

let mut my_tree: Tree<uint> = Node { children: ~[] };

match my_tree {
	Node { children: ref mut children } => children.push(Leaf(1u)),
	_ => ()
}

my_tree  */<|endoftext|>


<commit_before><commit_msg>Move the definition of the Renderer trait for clarity<commit_after><|endoftext|>


<commit_before><commit_msg>Add benchmark<commit_after>extern crate avro;

use std::time::Duration;
use std::time::Instant;

use avro::schema::Schema;
use avro::reader::Reader;
use avro::types::{Record, ToAvro, Value};
use avro::writer::Writer;

fn nanos(duration: Duration) -> u64 {
    duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64
}

fn seconds(nanos: u64) -> f64 {
    (nanos as f64) / 1_000_000_000f64
}

/*
fn duration(nanos: u64) -> Duration {
    Duration::new(nanos / 1_000_000_000, (nanos % 1_000_000_000) as u32)
}
*/

fn benchmark(schema: &Schema, record: &Value, count: usize, runs: usize) {
    let mut records = Vec::new();
    for __ in 0..count {
        records.push(record.clone());
    }

    let mut durations = Vec::with_capacity(runs);

    let mut bytes = None;
    for _ in 0..runs {
        let records = records.clone();

        let start = Instant::now();
        let mut writer = Writer::new(&schema, Vec::new());
        writer.extend(records.into_iter()).unwrap();

        let duration = Instant::now().duration_since(start);
        durations.push(duration);

        bytes = Some(writer.into_inner());
    }

    let total_duration = durations
        .into_iter()
        .fold(0u64, |a, b| a + nanos(b));

    println!("Write: {} {} {:?}", count, runs, seconds(total_duration));

    let bytes = bytes.unwrap();

    let mut durations = Vec::with_capacity(runs);

    for _ in 0..runs {
        let start = Instant::now();
        let reader = Reader::with_schema(schema, &bytes[..]);

        let mut read_records = Vec::with_capacity(count);
        for record in reader {
            read_records.push(record);
        }

        let duration = Instant::now().duration_since(start);
        durations.push(duration);

        // assert_eq!(count, read_records.len());
    }

    let total_duration = durations
        .into_iter()
        .fold(0u64, |a, b| a + nanos(b));

    println!("Read: {} {} {:?}", count, runs, seconds(total_duration));
}

fn main() {
    let raw_small_schema = r#"
        {"namespace": "test", "type": "record", "name": "Test", "fields": [{"type": {"type": "string"}, "name": "field"}]}
    "#;

    let raw_big_schema = r#"
        {"namespace": "my.example", "type": "record", "name": "userInfo", "fields": [{"default": "NONE", "type": "string", "name": "username"}, {"default": -1, "type": "int", "name": "age"}, {"default": "NONE", "type": "string", "name": "phone"}, {"default": "NONE", "type": "string", "name": "housenum"}, {"default": {}, "type": {"fields": [{"default": "NONE", "type": "string", "name": "street"}, {"default": "NONE", "type": "string", "name": "city"}, {"default": "NONE", "type": "string", "name": "state_prov"}, {"default": "NONE", "type": "string", "name": "country"}, {"default": "NONE", "type": "string", "name": "zip"}], "type": "record", "name": "mailing_address"}, "name": "address"}]}
    "#;

    let small_schema = Schema::parse_str(raw_small_schema).unwrap();
    let big_schema = Schema::parse_str(raw_big_schema).unwrap();

    println!("{:?}", small_schema);
    println!("{:?}", big_schema);

    let mut small_record = Record::new(&small_schema).unwrap();
    small_record.put("field", "foo");
    let small_record = small_record.avro();

    let raw_address_schema = r#"{"fields": [{"default": "NONE", "type": "string", "name": "street"}, {"default": "NONE", "type": "string", "name": "city"}, {"default": "NONE", "type": "string", "name": "state_prov"}, {"default": "NONE", "type": "string", "name": "country"}, {"default": "NONE", "type": "string", "name": "zip"}], "type": "record", "name": "mailing_address"}"#;
    let address_schema = Schema::parse_str(raw_address_schema).unwrap();
    let mut address = Record::new(&address_schema).unwrap();
    address.put("street", "street");
    address.put("city", "city");
    address.put("state_prov", "state_prov");
    address.put("country", "country");
    address.put("zip", "zip");

    let mut big_record = Record::new(&big_schema).unwrap();
    big_record.put("username", "username");
    big_record.put("age", 10i32);
    big_record.put("phone", "000000000");
    big_record.put("housenum", "0000");
    big_record.put("address", address);
    let big_record = big_record.avro();

    benchmark(&small_schema, &small_record, 10000, 1);
    benchmark(&big_schema, &big_record, 10000, 1);

    benchmark(&small_schema, &small_record, 1, 100000);
    benchmark(&small_schema, &small_record, 100, 1000);
    benchmark(&small_schema, &small_record, 10000, 10);

    benchmark(&big_schema, &big_record, 1, 100000);
    benchmark(&big_schema, &big_record, 100, 1000);
    benchmark(&big_schema, &big_record, 10000, 10);
}<|endoftext|>


<commit_before><commit_msg>Add doc comment for percent_encoding::from_hex<commit_after><|endoftext|>


<commit_before>use alloc::boxed::Box;

use arch::memory;

use collections::slice;
use collections::vec::Vec;
use collections::vec_deque::VecDeque;

use core::cell::UnsafeCell;
use core::ptr;

use drivers::pci::config::PciConfig;
use drivers::io::{Io, Pio};

use network::common::*;
use network::scheme::*;

use fs::{KScheme, Resource, Url};

use system::error::Result;

bitflags! {
    flags TsrFlags: u32 {
        const TSR_OWN = 1 << 13
    }
}

bitflags! {
    flags CrFlags: u8 {
        const CR_RST = 1 << 4,
        const CR_RE = 1 << 3,
        const CR_TE = 1 << 2,
        const CR_BUFE = 1 << 0
    }
}

bitflags! {
    flags IsrFlags: u16 {
        const ISR_SERR = 1 << 15,
        const ISR_TIMEOUT = 1 << 14,
        const ISR_LENCHG = 1 << 13,
        const ISR_FOVW = 1 << 6,
        const ISR_PUN_LINKCHG = 1 << 5,
        const ISR_RXOVW = 1 << 4,
        const ISR_TER = 1 << 3,
        const ISR_TOK = 1 << 2,
        const ISR_RER = 1 << 1,
        const ISR_ROK = 1 << 0
    }
}

bitflags! {
    flags TcrFlags: u32 {
        const TCR_IFG = 0b11 << 24
    }
}

bitflags! {
    flags RcrFlags: u32 {
        const RCR_WRAP = 1 << 7,
        const RCR_AR = 1 << 4,
        const RCR_AB = 1 << 3,
        const RCR_AM = 1 << 2,
        const RCR_APM = 1 << 1
    }
}

#[repr(packed)]
struct Txd {
    pub address_port: Pio<u32>,
    pub status_port: Pio<u32>,
    pub buffer: usize,
}

pub struct Rtl8139Port {
    pub idr: [Pio<u8>; 6],
    pub rbstart: Pio<u32>,
    pub cr: Pio<u8>,
    pub capr: Pio<u16>,
    pub cbr: Pio<u16>,
    pub imr: Pio<u16>,
    pub isr: Pio<u16>,
    pub tcr: Pio<u32>,
    pub rcr: Pio<u32>,
    pub config1: Pio<u8>,
}

impl Rtl8139Port {
    pub fn new(base: u16) -> Self {
        return Rtl8139Port {
            idr: [Pio::<u8>::new(base + 0x00),
                  Pio::<u8>::new(base + 0x01),
                  Pio::<u8>::new(base + 0x02),
                  Pio::<u8>::new(base + 0x03),
                  Pio::<u8>::new(base + 0x04),
                  Pio::<u8>::new(base + 0x05)],
            rbstart: Pio::<u32>::new(base + 0x30),
            cr: Pio::<u8>::new(base + 0x37),
            capr: Pio::<u16>::new(base + 0x38),
            cbr: Pio::<u16>::new(base + 0x3A),
            imr: Pio::<u16>::new(base + 0x3C),
            isr: Pio::<u16>::new(base + 0x3E),
            tcr: Pio::<u32>::new(base + 0x40),
            rcr: Pio::<u32>::new(base + 0x44),
            config1: Pio::<u8>::new(base + 0x52),
        };
    }
}

pub struct Rtl8139 {
    pci: PciConfig,
    base: usize,
    memory_mapped: bool,
    irq: u8,
    resources: UnsafeCell<Vec<*mut NetworkResource>>,
    inbound: VecDeque<Vec<u8>>,
    outbound: VecDeque<Vec<u8>>,
    txds: Vec<Txd>,
    txd_i: usize,
    port: Rtl8139Port,
}

impl Rtl8139 {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let pci_id = unsafe { pci.read(0x00) };
        let revision = (unsafe { pci.read(0x08) } & 0xFF) as u8;
        if pci_id == 0x813910EC && revision < 0x20 {
            debugln!("Not an 8139C+ compatible chip");
        }

        let base = unsafe { pci.read(0x10) as usize };
        let irq = unsafe { pci.read(0x3C) as u8 & 0xF };

        let mut module = box Rtl8139 {
            pci: pci,
            base: base & 0xFFFFFFF0,
            memory_mapped: base & 1 == 0,
            irq: irq,
            resources: UnsafeCell::new(Vec::new()),
            inbound: VecDeque::new(),
            outbound: VecDeque::new(),
            txds: Vec::new(),
            txd_i: 0,
            port: Rtl8139Port::new((base & 0xFFFFFFF0) as u16),
        };

        unsafe { module.init() };

        module
    }

    unsafe fn init(&mut self) {
        syslog_info!(" + RTL8139 on: {:X}, IRQ: {:X}", self.base, self.irq);

        self.pci.flag(4, 4, true); // Bus mastering

        let base = self.base as u16;

        self.port.config1.write(0);
        self.port.cr.write(CR_RST.bits);
        while self.port.cr.read() & CR_RST.bits != 0 {}

        MAC_ADDR = MacAddr {
            bytes: [self.port.idr[0].read(),
                    self.port.idr[1].read(),
                    self.port.idr[2].read(),
                    self.port.idr[3].read(),
                    self.port.idr[4].read(),
                    self.port.idr[5].read()],
        };
        syslog_info!("   - MAC: {}", &MAC_ADDR.to_string());

        let receive_buffer = memory::alloc(10240);
        self.port.rbstart.write(receive_buffer as u32);

        for i in 0..4 {
            self.txds.push(Txd {
                address_port: Pio::<u32>::new(base + 0x20 + (i as u16) * 4),
                status_port: Pio::<u32>::new(base + 0x10 + (i as u16) * 4),
                buffer: memory::alloc(4096),
            });
        }

        self.port.imr.write((ISR_TOK | ISR_ROK).bits);
        self.port.cr.write((CR_RE | CR_TE).bits);
        self.port.rcr.write((RCR_WRAP | RCR_AR | RCR_AB | RCR_AM | RCR_APM).bits);
        self.port.tcr.writef(TCR_IFG.bits, true);
    }

    unsafe fn receive_inbound(&mut self) {
        let receive_buffer = self.port.rbstart.read() as usize;
        let mut capr = (self.port.capr.read() + 16) as usize;
        let cbr = self.port.cbr.read() as usize;

        while capr != cbr {
            let frame_addr = receive_buffer + capr + 4;
            //let frame_status = ptr::read((receive_buffer + capr) as *const u16) as usize;
            let frame_len = ptr::read((receive_buffer + capr + 2) as *const u16) as usize;

            self.inbound.push_back(Vec::from(slice::from_raw_parts(frame_addr as *const u8, frame_len - 4)));

            capr = capr + frame_len + 4;
            capr = (capr + 3) & (0xFFFFFFFF - 3);
            if capr >= 8192 {
                capr -= 8192
            }

            self.port.capr.write((capr as u16) - 16);
        }
    }

    unsafe fn send_outbound(&mut self) {
        while let Some(bytes) = self.outbound.pop_front() {
            if let Some(ref mut txd) = self.txds.get_mut(self.txd_i) {
                if bytes.len() < 4096 {
                    while !txd.status_port.readf(TSR_OWN.bits) {}

                    ::memcpy(txd.buffer as *mut u8, bytes.as_ptr(), bytes.len());

                    txd.address_port.write(txd.buffer as u32);
                    txd.status_port.write(bytes.len() as u32 & 0xFFF);

                    self.txd_i = (self.txd_i + 1) % 4;
                } else {
                    debugln!("RTL8139: Frame too long for transmit: {}", bytes.len());
                }
            } else {
                debugln!("RTL8139: TXD Overflow!");
                self.txd_i = 0;
            }
        }
    }
}

impl KScheme for Rtl8139 {
    fn scheme(&self) -> &str {
        "network"
    }

    fn open(&mut self, _: Url, _: usize) -> Result<Box<Resource>> {
        Ok(NetworkResource::new(self))
    }

    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            let isr = self.port.isr.read();
            self.port.isr.write(isr);

            // dh(isr as usize);
            // dl();

            self.sync();
        }
    }
}

impl NetworkScheme for Rtl8139 {
    fn add(&mut self, resource: *mut NetworkResource) {
        unsafe { &mut *self.resources.get() }.push(resource);
    }

    fn remove(&mut self, resource: *mut NetworkResource) {
        let mut resources = unsafe { &mut *self.resources.get() };

        let mut i = 0;
        while i < resources.len() {
            let mut remove = false;

            match resources.get(i) {
                Some(ptr) => if *ptr == resource {
                    remove = true;
                } else {
                    i += 1;
                },
                None => break,
            }

            if remove {
                resources.remove(i);
            }
        }
    }

    fn sync(&mut self) {
        {
            let resources = unsafe { &mut *self.resources.get() };

            for resource in resources.iter() {
                while let Some(bytes) = unsafe { &mut *(**resource).outbound.get() }.pop_front() {
                    self.outbound.push_back(bytes);
                }
            }
        }

        unsafe { self.send_outbound(); }

        unsafe { self.receive_inbound(); }

        {
            let resources = unsafe { &mut *self.resources.get() };

            while let Some(bytes) = self.inbound.pop_front() {
                for resource in resources.iter() {
                    unsafe { (**resource).inbound.send(bytes.clone(), "Rtl8139::sync") };
                }
            }
        }
    }
}
<commit_msg>Check for overflow in rtl8139<commit_after>use alloc::boxed::Box;

use arch::memory;

use collections::slice;
use collections::vec::Vec;
use collections::vec_deque::VecDeque;

use core::cell::UnsafeCell;
use core::ptr;

use drivers::pci::config::PciConfig;
use drivers::io::{Io, Pio};

use network::common::*;
use network::scheme::*;

use fs::{KScheme, Resource, Url};

use system::error::Result;

bitflags! {
    flags TsrFlags: u32 {
        const TSR_OWN = 1 << 13
    }
}

bitflags! {
    flags CrFlags: u8 {
        const CR_RST = 1 << 4,
        const CR_RE = 1 << 3,
        const CR_TE = 1 << 2,
        const CR_BUFE = 1 << 0
    }
}

bitflags! {
    flags IsrFlags: u16 {
        const ISR_SERR = 1 << 15,
        const ISR_TIMEOUT = 1 << 14,
        const ISR_LENCHG = 1 << 13,
        const ISR_FOVW = 1 << 6,
        const ISR_PUN_LINKCHG = 1 << 5,
        const ISR_RXOVW = 1 << 4,
        const ISR_TER = 1 << 3,
        const ISR_TOK = 1 << 2,
        const ISR_RER = 1 << 1,
        const ISR_ROK = 1 << 0
    }
}

bitflags! {
    flags TcrFlags: u32 {
        const TCR_IFG = 0b11 << 24
    }
}

bitflags! {
    flags RcrFlags: u32 {
        const RCR_WRAP = 1 << 7,
        const RCR_AR = 1 << 4,
        const RCR_AB = 1 << 3,
        const RCR_AM = 1 << 2,
        const RCR_APM = 1 << 1
    }
}

#[repr(packed)]
struct Txd {
    pub address_port: Pio<u32>,
    pub status_port: Pio<u32>,
    pub buffer: usize,
}

pub struct Rtl8139Port {
    pub idr: [Pio<u8>; 6],
    pub rbstart: Pio<u32>,
    pub cr: Pio<u8>,
    pub capr: Pio<u16>,
    pub cbr: Pio<u16>,
    pub imr: Pio<u16>,
    pub isr: Pio<u16>,
    pub tcr: Pio<u32>,
    pub rcr: Pio<u32>,
    pub config1: Pio<u8>,
}

impl Rtl8139Port {
    pub fn new(base: u16) -> Self {
        return Rtl8139Port {
            idr: [Pio::<u8>::new(base + 0x00),
                  Pio::<u8>::new(base + 0x01),
                  Pio::<u8>::new(base + 0x02),
                  Pio::<u8>::new(base + 0x03),
                  Pio::<u8>::new(base + 0x04),
                  Pio::<u8>::new(base + 0x05)],
            rbstart: Pio::<u32>::new(base + 0x30),
            cr: Pio::<u8>::new(base + 0x37),
            capr: Pio::<u16>::new(base + 0x38),
            cbr: Pio::<u16>::new(base + 0x3A),
            imr: Pio::<u16>::new(base + 0x3C),
            isr: Pio::<u16>::new(base + 0x3E),
            tcr: Pio::<u32>::new(base + 0x40),
            rcr: Pio::<u32>::new(base + 0x44),
            config1: Pio::<u8>::new(base + 0x52),
        };
    }
}

pub struct Rtl8139 {
    pci: PciConfig,
    base: usize,
    memory_mapped: bool,
    irq: u8,
    resources: UnsafeCell<Vec<*mut NetworkResource>>,
    inbound: VecDeque<Vec<u8>>,
    outbound: VecDeque<Vec<u8>>,
    txds: Vec<Txd>,
    txd_i: usize,
    port: Rtl8139Port,
}

impl Rtl8139 {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { pci.read(0x10) as usize };
        let irq = unsafe { pci.read(0x3C) as u8 & 0xF };

        let mut module = box Rtl8139 {
            pci: pci,
            base: base & 0xFFFFFFF0,
            memory_mapped: base & 1 == 0,
            irq: irq,
            resources: UnsafeCell::new(Vec::new()),
            inbound: VecDeque::new(),
            outbound: VecDeque::new(),
            txds: Vec::new(),
            txd_i: 0,
            port: Rtl8139Port::new((base & 0xFFFFFFF0) as u16),
        };

        unsafe { module.init() };

        module
    }

    unsafe fn init(&mut self) {
        syslog_info!(" + RTL8139 on: {:X}, IRQ: {:X}", self.base, self.irq);

        let pci_id = self.pci.read(0x00);
        let revision = (self.pci.read(0x08) & 0xFF) as u8;

        if pci_id == 0x813910EC && revision < 0x20 {
            syslog_info!("   - Not an 8139C+ compatible chip");
        }

        self.pci.flag(4, 4, true); // Bus mastering

        let base = self.base as u16;

        self.port.config1.write(0);
        self.port.cr.write(CR_RST.bits);
        while self.port.cr.read() & CR_RST.bits != 0 {}

        MAC_ADDR = MacAddr {
            bytes: [self.port.idr[0].read(),
                    self.port.idr[1].read(),
                    self.port.idr[2].read(),
                    self.port.idr[3].read(),
                    self.port.idr[4].read(),
                    self.port.idr[5].read()],
        };
        syslog_info!("   - MAC: {}", &MAC_ADDR.to_string());

        let receive_buffer = memory::alloc(10240);
        self.port.rbstart.write(receive_buffer as u32);

        for i in 0..4 {
            self.txds.push(Txd {
                address_port: Pio::<u32>::new(base + 0x20 + (i as u16) * 4),
                status_port: Pio::<u32>::new(base + 0x10 + (i as u16) * 4),
                buffer: memory::alloc(4096),
            });
        }

        self.port.imr.write((ISR_TOK | ISR_ROK).bits);
        self.port.cr.write((CR_RE | CR_TE).bits);
        self.port.rcr.write((RCR_WRAP | RCR_AR | RCR_AB | RCR_AM | RCR_APM).bits);
        self.port.tcr.writef(TCR_IFG.bits, true);
    }

    unsafe fn receive_inbound(&mut self) {
        let receive_buffer = self.port.rbstart.read() as usize;
        let mut capr = (self.port.capr.read() + 16) as usize;
        let cbr = self.port.cbr.read() as usize;

        while capr != cbr {
            let frame_addr = receive_buffer + capr + 4;
            let frame_status = ptr::read((receive_buffer + capr) as *const u16) as usize;
            let frame_len = ptr::read((receive_buffer + capr + 2) as *const u16) as usize;

            if frame_len >= 4 {
                self.inbound.push_back(Vec::from(slice::from_raw_parts(frame_addr as *const u8, frame_len - 4)));
            } else {
                debugln!("RTL8139: Empty packet: ADDR {:X} STATUS {:X} LEN {}", frame_addr, frame_status, frame_len);
            }

            capr = capr + frame_len + 4;
            capr = (capr + 3) & (0xFFFFFFFF - 3);
            if capr >= 8192 {
                capr -= 8192
            }

            self.port.capr.write((capr as u16) - 16);
        }
    }

    unsafe fn send_outbound(&mut self) {
        while let Some(bytes) = self.outbound.pop_front() {
            if let Some(ref mut txd) = self.txds.get_mut(self.txd_i) {
                if bytes.len() < 4096 {
                    while !txd.status_port.readf(TSR_OWN.bits) {}

                    ::memcpy(txd.buffer as *mut u8, bytes.as_ptr(), bytes.len());

                    txd.address_port.write(txd.buffer as u32);
                    txd.status_port.write(bytes.len() as u32 & 0xFFF);

                    self.txd_i = (self.txd_i + 1) % 4;
                } else {
                    debugln!("RTL8139: Frame too long for transmit: {}", bytes.len());
                }
            } else {
                debugln!("RTL8139: TXD Overflow!");
                self.txd_i = 0;
            }
        }
    }
}

impl KScheme for Rtl8139 {
    fn scheme(&self) -> &str {
        "network"
    }

    fn open(&mut self, _: Url, _: usize) -> Result<Box<Resource>> {
        Ok(NetworkResource::new(self))
    }

    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            let isr = self.port.isr.read();
            self.port.isr.write(isr);

            // dh(isr as usize);
            // dl();

            self.sync();
        }
    }
}

impl NetworkScheme for Rtl8139 {
    fn add(&mut self, resource: *mut NetworkResource) {
        unsafe { &mut *self.resources.get() }.push(resource);
    }

    fn remove(&mut self, resource: *mut NetworkResource) {
        let mut resources = unsafe { &mut *self.resources.get() };

        let mut i = 0;
        while i < resources.len() {
            let mut remove = false;

            match resources.get(i) {
                Some(ptr) => if *ptr == resource {
                    remove = true;
                } else {
                    i += 1;
                },
                None => break,
            }

            if remove {
                resources.remove(i);
            }
        }
    }

    fn sync(&mut self) {
        {
            let resources = unsafe { &mut *self.resources.get() };

            for resource in resources.iter() {
                while let Some(bytes) = unsafe { &mut *(**resource).outbound.get() }.pop_front() {
                    self.outbound.push_back(bytes);
                }
            }
        }

        unsafe { self.send_outbound(); }

        unsafe { self.receive_inbound(); }

        {
            let resources = unsafe { &mut *self.resources.get() };

            while let Some(bytes) = self.inbound.pop_front() {
                for resource in resources.iter() {
                    unsafe { (**resource).inbound.send(bytes.clone(), "Rtl8139::sync") };
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Code for the 'normalization' query. This consists of a wrapper
//! which folds deeply, invoking the underlying
//! `normalize_projection_ty` query when it encounters projections.

use infer::{InferCtxt, InferOk};
use infer::at::At;
use infer::canonical::{Canonical, Canonicalize, QueryResult};
use middle::const_val::ConstVal;
use mir::interpret::GlobalId;
use rustc_data_structures::sync::Lrc;
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use traits::query::CanonicalProjectionGoal;
use traits::project::Normalized;
use ty::{self, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::{Subst, Substs};

use super::NoSolution;

impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
    /// Normalize `value` in the context of the inference context,
    /// yielding a resulting type, or an error if `value` cannot be
    /// normalized. If you don't care about regions, you should prefer
    /// `normalize_erasing_regions`, which is more efficient.
    ///
    /// If the normalization succeeds and is unambiguous, returns back
    /// the normalized value along with various outlives relations (in
    /// the form of obligations that must be discharged).
    ///
    /// NB. This will *eventually* be the main means of
    /// normalizing, but for now should be used only when we actually
    /// know that normalization will succeed, since error reporting
    /// and other details are still "under development".
    pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>,
    {
        debug!(
            "normalize::<{}>(value={:?}, param_env={:?})",
            unsafe { ::std::intrinsics::type_name::<T>() },
            value,
            self.param_env,
        );
        let mut normalizer = QueryNormalizer {
            infcx: self.infcx,
            cause: self.cause,
            param_env: self.param_env,
            obligations: vec![],
            error: false,
            anon_depth: 0,
        };
        if !value.has_projections() {
            return Ok(Normalized {
                value: value.clone(),
                obligations: vec![],
            });
        }

        let value1 = value.fold_with(&mut normalizer);
        if normalizer.error {
            Err(NoSolution)
        } else {
            Ok(Normalized {
                value: value1,
                obligations: normalizer.obligations,
            })
        }
    }
}

/// Result from the `normalize_projection_ty` query.
#[derive(Clone, Debug)]
pub struct NormalizationResult<'tcx> {
    /// Result of normalization.
    pub normalized_ty: Ty<'tcx>,
}

struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
    cause: &'cx ObligationCause<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    obligations: Vec<PredicateObligation<'tcx>>,
    error: bool,
    anon_depth: usize,
}

impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx> {
    fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'tcx> {
        self.infcx.tcx
    }

    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
        let ty = ty.super_fold_with(self);
        match ty.sty {
            ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => {
                // (*)
                // Only normalize `impl Trait` after type-checking, usually in codegen.
                match self.param_env.reveal {
                    Reveal::UserFacing => ty,

                    Reveal::All => {
                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                        if self.anon_depth >= recursion_limit {
                            let obligation = Obligation::with_depth(
                                self.cause.clone(),
                                recursion_limit,
                                self.param_env,
                                ty,
                            );
                            self.infcx.report_overflow_error(&obligation, true);
                        }

                        let generic_ty = self.tcx().type_of(def_id);
                        let concrete_ty = generic_ty.subst(self.tcx(), substs);
                        self.anon_depth += 1;
                        if concrete_ty == ty {
                            println!("generic_ty: {:#?}", generic_ty);
                            println!("substs {:#?}", substs);
                        }
                        assert_ne!(concrete_ty, ty, "infinite recursion");
                        let folded_ty = self.fold_ty(concrete_ty);
                        self.anon_depth -= 1;
                        folded_ty
                    }
                }
            }

            ty::TyProjection(ref data) if !data.has_escaping_regions() => {
                // (*)
                // (*) This is kind of hacky -- we need to be able to
                // handle normalization within binders because
                // otherwise we wind up a need to normalize when doing
                // trait matching (since you can have a trait
                // obligation like `for<'a> T::B : Fn(&'a int)`), but
                // we can't normalize with bound regions in scope. So
                // far now we just ignore binders but only normalize
                // if all bound regions are gone (and then we still
                // have to renormalize whenever we instantiate a
                // binder). It would be better to normalize in a
                // binding-aware fashion.

                let gcx = self.infcx.tcx.global_tcx();

                let (c_data, orig_values) =
                    self.infcx.canonicalize_query(&self.param_env.and(*data));
                debug!("QueryNormalizer: c_data = {:#?}", c_data);
                debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                match gcx.normalize_projection_ty(c_data) {
                    Ok(result) => {
                        // We don't expect ambiguity.
                        if result.is_ambiguous() {
                            self.error = true;
                            return ty;
                        }

                        match self.infcx.instantiate_query_result(
                            self.cause,
                            self.param_env,
                            &orig_values,
                            &result,
                        ) {
                            Ok(InferOk {
                                value: result,
                                obligations,
                            }) => {
                                debug!("QueryNormalizer: result = {:#?}", result);
                                debug!("QueryNormalizer: obligations = {:#?}", obligations);
                                self.obligations.extend(obligations);
                                return result.normalized_ty;
                            }

                            Err(_) => {
                                self.error = true;
                                return ty;
                            }
                        }
                    }

                    Err(NoSolution) => {
                        self.error = true;
                        ty
                    }
                }
            }

            _ => ty,
        }
    }

    fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
        if let ConstVal::Unevaluated(def_id, substs) = constant.val {
            let tcx = self.infcx.tcx.global_tcx();
            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
                if substs.needs_infer() || substs.has_skol() {
                    let identity_substs = Substs::identity_for_item(tcx, def_id);
                    let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
                    if let Some(instance) = instance {
                        let cid = GlobalId {
                            instance,
                            promoted: None,
                        };
                        match tcx.const_eval(param_env.and(cid)) {
                            Ok(evaluated) => {
                                let evaluated = evaluated.subst(self.tcx(), substs);
                                return self.fold_const(evaluated);
                            }
                            Err(_) => {}
                        }
                    }
                } else {
                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
                        let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                        if let Some(instance) = instance {
                            let cid = GlobalId {
                                instance,
                                promoted: None,
                            };
                            match tcx.const_eval(param_env.and(cid)) {
                                Ok(evaluated) => return self.fold_const(evaluated),
                                Err(_) => {}
                            }
                        }
                    }
                }
            }
        }
        constant
    }
}

BraceStructTypeFoldableImpl! {
    impl<'tcx> TypeFoldable<'tcx> for NormalizationResult<'tcx> {
        normalized_ty
    }
}

BraceStructLiftImpl! {
    impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> {
        type Lifted = NormalizationResult<'tcx>;
        normalized_ty
    }
}

impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>> {
    type Canonicalized = CanonicalProjectionGoal<'gcx>;

    fn intern(
        _gcx: TyCtxt<'_, 'gcx, 'gcx>,
        value: Canonical<'gcx, Self::Lifted>,
    ) -> Self::Canonicalized {
        value
    }
}

impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> {
    // we ought to intern this, but I'm too lazy just now
    type Canonicalized = Lrc<Canonical<'gcx, QueryResult<'gcx, NormalizationResult<'gcx>>>>;

    fn intern(
        _gcx: TyCtxt<'_, 'gcx, 'gcx>,
        value: Canonical<'gcx, Self::Lifted>,
    ) -> Self::Canonicalized {
        Lrc::new(value)
    }
}

impl_stable_hash_for!(struct NormalizationResult<'tcx> {
    normalized_ty
});
<commit_msg>Use proper debugging statements for infinite recursion assertion<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Code for the 'normalization' query. This consists of a wrapper
//! which folds deeply, invoking the underlying
//! `normalize_projection_ty` query when it encounters projections.

use infer::{InferCtxt, InferOk};
use infer::at::At;
use infer::canonical::{Canonical, Canonicalize, QueryResult};
use middle::const_val::ConstVal;
use mir::interpret::GlobalId;
use rustc_data_structures::sync::Lrc;
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
use traits::query::CanonicalProjectionGoal;
use traits::project::Normalized;
use ty::{self, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::{Subst, Substs};

use super::NoSolution;

impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
    /// Normalize `value` in the context of the inference context,
    /// yielding a resulting type, or an error if `value` cannot be
    /// normalized. If you don't care about regions, you should prefer
    /// `normalize_erasing_regions`, which is more efficient.
    ///
    /// If the normalization succeeds and is unambiguous, returns back
    /// the normalized value along with various outlives relations (in
    /// the form of obligations that must be discharged).
    ///
    /// NB. This will *eventually* be the main means of
    /// normalizing, but for now should be used only when we actually
    /// know that normalization will succeed, since error reporting
    /// and other details are still "under development".
    pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
    where
        T: TypeFoldable<'tcx>,
    {
        debug!(
            "normalize::<{}>(value={:?}, param_env={:?})",
            unsafe { ::std::intrinsics::type_name::<T>() },
            value,
            self.param_env,
        );
        let mut normalizer = QueryNormalizer {
            infcx: self.infcx,
            cause: self.cause,
            param_env: self.param_env,
            obligations: vec![],
            error: false,
            anon_depth: 0,
        };
        if !value.has_projections() {
            return Ok(Normalized {
                value: value.clone(),
                obligations: vec![],
            });
        }

        let value1 = value.fold_with(&mut normalizer);
        if normalizer.error {
            Err(NoSolution)
        } else {
            Ok(Normalized {
                value: value1,
                obligations: normalizer.obligations,
            })
        }
    }
}

/// Result from the `normalize_projection_ty` query.
#[derive(Clone, Debug)]
pub struct NormalizationResult<'tcx> {
    /// Result of normalization.
    pub normalized_ty: Ty<'tcx>,
}

struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
    cause: &'cx ObligationCause<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    obligations: Vec<PredicateObligation<'tcx>>,
    error: bool,
    anon_depth: usize,
}

impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx> {
    fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'tcx> {
        self.infcx.tcx
    }

    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
        let ty = ty.super_fold_with(self);
        match ty.sty {
            ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => {
                // (*)
                // Only normalize `impl Trait` after type-checking, usually in codegen.
                match self.param_env.reveal {
                    Reveal::UserFacing => ty,

                    Reveal::All => {
                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                        if self.anon_depth >= recursion_limit {
                            let obligation = Obligation::with_depth(
                                self.cause.clone(),
                                recursion_limit,
                                self.param_env,
                                ty,
                            );
                            self.infcx.report_overflow_error(&obligation, true);
                        }

                        let generic_ty = self.tcx().type_of(def_id);
                        let concrete_ty = generic_ty.subst(self.tcx(), substs);
                        self.anon_depth += 1;
                        if concrete_ty == ty {
                            bug!("infinite recursion generic_ty: {:#?}, substs: {:#?}, \
                                  concrete_ty: {:#?}, ty: {:#?}", generic_ty, substs, concrete_ty,
                                  ty);
                        }
                        let folded_ty = self.fold_ty(concrete_ty);
                        self.anon_depth -= 1;
                        folded_ty
                    }
                }
            }

            ty::TyProjection(ref data) if !data.has_escaping_regions() => {
                // (*)
                // (*) This is kind of hacky -- we need to be able to
                // handle normalization within binders because
                // otherwise we wind up a need to normalize when doing
                // trait matching (since you can have a trait
                // obligation like `for<'a> T::B : Fn(&'a int)`), but
                // we can't normalize with bound regions in scope. So
                // far now we just ignore binders but only normalize
                // if all bound regions are gone (and then we still
                // have to renormalize whenever we instantiate a
                // binder). It would be better to normalize in a
                // binding-aware fashion.

                let gcx = self.infcx.tcx.global_tcx();

                let (c_data, orig_values) =
                    self.infcx.canonicalize_query(&self.param_env.and(*data));
                debug!("QueryNormalizer: c_data = {:#?}", c_data);
                debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
                match gcx.normalize_projection_ty(c_data) {
                    Ok(result) => {
                        // We don't expect ambiguity.
                        if result.is_ambiguous() {
                            self.error = true;
                            return ty;
                        }

                        match self.infcx.instantiate_query_result(
                            self.cause,
                            self.param_env,
                            &orig_values,
                            &result,
                        ) {
                            Ok(InferOk {
                                value: result,
                                obligations,
                            }) => {
                                debug!("QueryNormalizer: result = {:#?}", result);
                                debug!("QueryNormalizer: obligations = {:#?}", obligations);
                                self.obligations.extend(obligations);
                                return result.normalized_ty;
                            }

                            Err(_) => {
                                self.error = true;
                                return ty;
                            }
                        }
                    }

                    Err(NoSolution) => {
                        self.error = true;
                        ty
                    }
                }
            }

            _ => ty,
        }
    }

    fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
        if let ConstVal::Unevaluated(def_id, substs) = constant.val {
            let tcx = self.infcx.tcx.global_tcx();
            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
                if substs.needs_infer() || substs.has_skol() {
                    let identity_substs = Substs::identity_for_item(tcx, def_id);
                    let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
                    if let Some(instance) = instance {
                        let cid = GlobalId {
                            instance,
                            promoted: None,
                        };
                        match tcx.const_eval(param_env.and(cid)) {
                            Ok(evaluated) => {
                                let evaluated = evaluated.subst(self.tcx(), substs);
                                return self.fold_const(evaluated);
                            }
                            Err(_) => {}
                        }
                    }
                } else {
                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
                        let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                        if let Some(instance) = instance {
                            let cid = GlobalId {
                                instance,
                                promoted: None,
                            };
                            match tcx.const_eval(param_env.and(cid)) {
                                Ok(evaluated) => return self.fold_const(evaluated),
                                Err(_) => {}
                            }
                        }
                    }
                }
            }
        }
        constant
    }
}

BraceStructTypeFoldableImpl! {
    impl<'tcx> TypeFoldable<'tcx> for NormalizationResult<'tcx> {
        normalized_ty
    }
}

BraceStructLiftImpl! {
    impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> {
        type Lifted = NormalizationResult<'tcx>;
        normalized_ty
    }
}

impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>> {
    type Canonicalized = CanonicalProjectionGoal<'gcx>;

    fn intern(
        _gcx: TyCtxt<'_, 'gcx, 'gcx>,
        value: Canonical<'gcx, Self::Lifted>,
    ) -> Self::Canonicalized {
        value
    }
}

impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> {
    // we ought to intern this, but I'm too lazy just now
    type Canonicalized = Lrc<Canonical<'gcx, QueryResult<'gcx, NormalizationResult<'gcx>>>>;

    fn intern(
        _gcx: TyCtxt<'_, 'gcx, 'gcx>,
        value: Canonical<'gcx, Self::Lifted>,
    ) -> Self::Canonicalized {
        Lrc::new(value)
    }
}

impl_stable_hash_for!(struct NormalizationResult<'tcx> {
    normalized_ty
});
<|endoftext|>