<commit_before>//! An IRC transport that wraps an IRC-framed stream to provide a number of features including
//! automatic PING replies, automatic sending of PINGs, and message rate-limiting.
use std::collections::VecDeque;
use std::sync::{Arc, RwLock, RwLockReadGuard};
use std::time::{Duration, Instant};

use futures::{Async, AsyncSink, Future, Poll, Sink, StartSend, Stream};
use chrono::prelude::*;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::Framed;
use tokio_timer;
use tokio_timer::{Interval, Sleep, Timer};

use error;
use client::data::Config;
use proto::{Command, IrcCodec, Message};

/// An IRC transport that handles core functionality.
pub struct IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    inner: Framed<T, IrcCodec>,
    burst_timer: Timer,
    rolling_burst_window: VecDeque<Sleep>,
    burst_window_length: u64,
    max_burst_messages: u64,
    current_burst_messages: u64,
    ping_timer: Interval,
    ping_timeout: u64,
    last_ping_data: String,
    last_ping_sent: Instant,
    last_pong_received: Instant,
}

impl<T> IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    /// Creates a new `IrcTransport` from the given IRC stream.
    pub fn new(config: &Config, inner: Framed<T, IrcCodec>) -> IrcTransport<T> {
        let timer = tokio_timer::wheel().build();
        IrcTransport {
            inner: inner,
            burst_timer: tokio_timer::wheel().build(),
            rolling_burst_window: VecDeque::new(),
            burst_window_length: u64::from(config.burst_window_length()),
            max_burst_messages: u64::from(config.max_messages_in_burst()),
            current_burst_messages: 0,
            ping_timer: timer.interval(Duration::from_secs(u64::from(config.ping_time()))),
            ping_timeout: u64::from(config.ping_timeout()),
            last_ping_data: String::new(),
            last_ping_sent: Instant::now(),
            last_pong_received: Instant::now(),
        }
    }

    /// Gets the inner stream underlying the `IrcTransport`.
    pub fn into_inner(self) -> Framed<T, IrcCodec> {
        self.inner
    }

    fn ping_timed_out(&self) -> bool {
        if self.last_pong_received < self.last_ping_sent {
            self.last_ping_sent.elapsed().as_secs() >= self.ping_timeout
        } else {
            false
        }
    }

    fn send_ping(&mut self) -> error::Result<()> {
        self.last_ping_sent = Instant::now();
        self.last_ping_data = format!("{}", Local::now().timestamp());
        let data = self.last_ping_data.clone();
        let result = self.start_send(Command::PING(data, None).into())?;
        assert!(result.is_ready());
        self.poll_complete()?;
        Ok(())
    }

    fn rolling_burst_window_front(&mut self) -> Result<Async<()>, tokio_timer::TimerError> {
        self.rolling_burst_window.front_mut().map(|w| w.poll()).unwrap_or(Ok(Async::NotReady))
    }
}

impl<T> Stream for IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    type Item = Message;
    type Error = error::IrcError;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        if self.ping_timed_out() {
            self.close()?;
            return Err(error::IrcError::PingTimeout)
        }

        let timer_poll = self.ping_timer.poll()?;
        let inner_poll = self.inner.poll()?;

        match (inner_poll, timer_poll) {
            (Async::NotReady, Async::NotReady) => Ok(Async::NotReady),
            (Async::NotReady, Async::Ready(msg)) => {
                assert!(msg.is_some());
                self.send_ping()?;
                Ok(Async::NotReady)
            }
            (Async::Ready(None), _) => Ok(Async::Ready(None)),
            (Async::Ready(Some(msg)), _) => {
                if let Async::Ready(msg) = timer_poll {
                    assert!(msg.is_some());
                    self.send_ping()?;
                }

                match msg.command {
                    // Automatically respond to PINGs from the server.
                    Command::PING(ref data, _) => {
                        let result = self.start_send(Command::PONG(data.to_owned(), None).into())?;
                        assert!(result.is_ready());
                        self.poll_complete()?;
                    }
                    // Check PONG responses from the server.
                    Command::PONG(ref data, None) |
                    Command::PONG(_, Some(ref data)) => {
                        if self.last_ping_data == data[..] {
                            self.last_pong_received = Instant::now();
                        }
                    }
                    _ => (),
                }

                Ok(Async::Ready(Some(msg)))
            }
        }
    }
}

impl<T> Sink for IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    type SinkItem = Message;
    type SinkError = error::IrcError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        if self.ping_timed_out() {
            self.close()?;
            Err(error::IrcError::PingTimeout)
        } else {
            // Check if the oldest message in the rolling window is discounted.
            if let Async::Ready(()) = self.rolling_burst_window_front()? {
                self.current_burst_messages -= 1;
                self.rolling_burst_window.pop_front();
            }

            // Throttling if too many messages have been sent recently.
            if self.current_burst_messages >= self.max_burst_messages {
                // When throttled, we know we need to finish sending what's already queued up.
                self.poll_complete()?;
                return Ok(AsyncSink::NotReady(item))
            }

            match self.inner.start_send(item)? {
                AsyncSink::NotReady(item) => Ok(AsyncSink::NotReady(item)),
                AsyncSink::Ready => {
                    self.current_burst_messages += 1;
                    self.rolling_burst_window.push_back(self.burst_timer.sleep(Duration::from_secs(
                        self.burst_window_length
                    )));
                    Ok(AsyncSink::Ready)
                }
            }
        }
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        if self.ping_timed_out() {
            self.close()?;
            Err(error::IrcError::PingTimeout)
        } else {
            // If it's time to send a ping, we should do it! This is necessary to ensure that the
            // sink half will close even if the stream half closed without a ping timeout.
            if let Async::Ready(msg) = self.ping_timer.poll()? {
                assert!(msg.is_some());
                self.send_ping()?;
            }

            Ok(self.inner.poll_complete()?)
        }
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.inner.close()
    }
}

/// A view of the logs from a particular `Logged` transport.
#[derive(Clone, Debug)]
pub struct LogView {
    sent: Arc<RwLock<Vec<Message>>>,
    received: Arc<RwLock<Vec<Message>>>,
}

impl LogView {
    /// Gets a read guard for all the messages sent on the transport.
    pub fn sent(&self) -> error::Result<RwLockReadGuard<Vec<Message>>> {
        self.sent.read().map_err(|_| error::IrcError::PoisonedLog)
    }

    /// Gets a read guard for all the messages received on the transport.
    pub fn received(&self) -> error::Result<RwLockReadGuard<Vec<Message>>> {
        self.received.read().map_err(|_| error::IrcError::PoisonedLog)
    }
}

/// A logged version of the `IrcTransport` that records all sent and received messages.
/// Note: this will introduce some performance overhead by cloning all messages.
pub struct Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    inner: IrcTransport<T>,
    view: LogView,
}

impl<T> Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    /// Wraps the given `IrcTransport` in logging.
    pub fn wrap(inner: IrcTransport<T>) -> Logged<T> {
        Logged {
            inner: inner,
            view: LogView {
                sent: Arc::new(RwLock::new(vec![])),
                received: Arc::new(RwLock::new(vec![])),
            },
        }
    }

    /// Gets a view of the logging for this transport.
    pub fn view(&self) -> LogView {
        self.view.clone()
    }
}

impl<T> Stream for Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    type Item = Message;
    type Error = error::IrcError;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match try_ready!(self.inner.poll()) {
            Some(msg) => {
                let recv: error::Result<_> = self.view.received.write().map_err(|_| {
                    error::IrcError::PoisonedLog
                });
                recv?.push(msg.clone());
                Ok(Async::Ready(Some(msg)))
            }
            None => Ok(Async::Ready(None)),
        }
    }
}

impl<T> Sink for Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    type SinkItem = Message;
    type SinkError = error::IrcError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        let res = self.inner.start_send(item.clone())?;
        let sent: error::Result<_> = self.view.sent.write().map_err(|_| {
            error::IrcError::PoisonedLog
        });
        sent?.push(item);
        Ok(res)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        Ok(self.inner.poll_complete()?)
    }
}
<commit_msg>Changed ping logic to eliminate a rare panic under heavy load (fixes #120).<commit_after>//! An IRC transport that wraps an IRC-framed stream to provide a number of features including
//! automatic PING replies, automatic sending of PINGs, and message rate-limiting.
use std::collections::VecDeque;
use std::sync::{Arc, RwLock, RwLockReadGuard};
use std::time::{Duration, Instant};

use futures::{Async, AsyncSink, Future, Poll, Sink, StartSend, Stream};
use chrono::prelude::*;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::Framed;
use tokio_timer;
use tokio_timer::{Interval, Sleep, Timer};

use error;
use client::data::Config;
use proto::{Command, IrcCodec, Message};

/// An IRC transport that handles core functionality.
pub struct IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    inner: Framed<T, IrcCodec>,
    burst_timer: Timer,
    rolling_burst_window: VecDeque<Sleep>,
    burst_window_length: u64,
    max_burst_messages: u64,
    current_burst_messages: u64,
    ping_timer: Interval,
    ping_timeout: u64,
    last_ping_data: String,
    last_ping_sent: Instant,
    last_pong_received: Instant,
}

impl<T> IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    /// Creates a new `IrcTransport` from the given IRC stream.
    pub fn new(config: &Config, inner: Framed<T, IrcCodec>) -> IrcTransport<T> {
        let timer = tokio_timer::wheel().build();
        IrcTransport {
            inner: inner,
            burst_timer: tokio_timer::wheel().build(),
            rolling_burst_window: VecDeque::new(),
            burst_window_length: u64::from(config.burst_window_length()),
            max_burst_messages: u64::from(config.max_messages_in_burst()),
            current_burst_messages: 0,
            ping_timer: timer.interval(Duration::from_secs(u64::from(config.ping_time()))),
            ping_timeout: u64::from(config.ping_timeout()),
            last_ping_data: String::new(),
            last_ping_sent: Instant::now(),
            last_pong_received: Instant::now(),
        }
    }

    /// Gets the inner stream underlying the `IrcTransport`.
    pub fn into_inner(self) -> Framed<T, IrcCodec> {
        self.inner
    }

    fn ping_timed_out(&self) -> bool {
        if self.last_pong_received < self.last_ping_sent {
            self.last_ping_sent.elapsed().as_secs() >= self.ping_timeout
        } else {
            false
        }
    }

    fn send_ping(&mut self) -> error::Result<()> {
        let last_ping_data = format!("{}", Local::now().timestamp());
        let data = last_ping_data.clone();
        let result = self.start_send(Command::PING(data, None).into())?;
        if let AsyncSink::Ready = result {
            self.poll_complete()?;
            self.last_ping_sent = Instant::now();
            self.last_ping_data = last_ping_data;
        }
        Ok(())
    }

    fn rolling_burst_window_front(&mut self) -> Result<Async<()>, tokio_timer::TimerError> {
        self.rolling_burst_window.front_mut().map(|w| w.poll()).unwrap_or(Ok(Async::NotReady))
    }
}

impl<T> Stream for IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    type Item = Message;
    type Error = error::IrcError;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        if self.ping_timed_out() {
            self.close()?;
            return Err(error::IrcError::PingTimeout)
        }

        let timer_poll = self.ping_timer.poll()?;
        let inner_poll = self.inner.poll()?;

        match (inner_poll, timer_poll) {
            (Async::NotReady, Async::NotReady) => Ok(Async::NotReady),
            (Async::NotReady, Async::Ready(msg)) => {
                assert!(msg.is_some());
                self.send_ping()?;
                Ok(Async::NotReady)
            }
            (Async::Ready(None), _) => Ok(Async::Ready(None)),
            (Async::Ready(Some(msg)), _) => {
                if let Async::Ready(msg) = timer_poll {
                    assert!(msg.is_some());
                    self.send_ping()?;
                }

                match msg.command {
                    // Automatically respond to PINGs from the server.
                    Command::PING(ref data, _) => {
                        let result = self.start_send(Command::PONG(data.to_owned(), None).into())?;
                        assert!(result.is_ready());
                        self.poll_complete()?;
                    }
                    // Check PONG responses from the server.
                    Command::PONG(ref data, None) |
                    Command::PONG(_, Some(ref data)) => {
                        if self.last_ping_data == data[..] {
                            self.last_pong_received = Instant::now();
                        }
                    }
                    _ => (),
                }

                Ok(Async::Ready(Some(msg)))
            }
        }
    }
}

impl<T> Sink for IrcTransport<T>
where
    T: AsyncRead + AsyncWrite,
{
    type SinkItem = Message;
    type SinkError = error::IrcError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        if self.ping_timed_out() {
            self.close()?;
            Err(error::IrcError::PingTimeout)
        } else {
            // Check if the oldest message in the rolling window is discounted.
            if let Async::Ready(()) = self.rolling_burst_window_front()? {
                self.current_burst_messages -= 1;
                self.rolling_burst_window.pop_front();
            }

            // Throttling if too many messages have been sent recently.
            if self.current_burst_messages >= self.max_burst_messages {
                // When throttled, we know we need to finish sending what's already queued up.
                self.poll_complete()?;
                return Ok(AsyncSink::NotReady(item))
            }

            match self.inner.start_send(item)? {
                AsyncSink::NotReady(item) => Ok(AsyncSink::NotReady(item)),
                AsyncSink::Ready => {
                    self.current_burst_messages += 1;
                    self.rolling_burst_window.push_back(self.burst_timer.sleep(Duration::from_secs(
                        self.burst_window_length
                    )));
                    Ok(AsyncSink::Ready)
                }
            }
        }
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        if self.ping_timed_out() {
            self.close()?;
            Err(error::IrcError::PingTimeout)
        } else {
            // If it's time to send a ping, we should do it! This is necessary to ensure that the
            // sink half will close even if the stream half closed without a ping timeout.
            if let Async::Ready(msg) = self.ping_timer.poll()? {
                assert!(msg.is_some());
                self.send_ping()?;
            }

            Ok(self.inner.poll_complete()?)
        }
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.inner.close()
    }
}

/// A view of the logs from a particular `Logged` transport.
#[derive(Clone, Debug)]
pub struct LogView {
    sent: Arc<RwLock<Vec<Message>>>,
    received: Arc<RwLock<Vec<Message>>>,
}

impl LogView {
    /// Gets a read guard for all the messages sent on the transport.
    pub fn sent(&self) -> error::Result<RwLockReadGuard<Vec<Message>>> {
        self.sent.read().map_err(|_| error::IrcError::PoisonedLog)
    }

    /// Gets a read guard for all the messages received on the transport.
    pub fn received(&self) -> error::Result<RwLockReadGuard<Vec<Message>>> {
        self.received.read().map_err(|_| error::IrcError::PoisonedLog)
    }
}

/// A logged version of the `IrcTransport` that records all sent and received messages.
/// Note: this will introduce some performance overhead by cloning all messages.
pub struct Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    inner: IrcTransport<T>,
    view: LogView,
}

impl<T> Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    /// Wraps the given `IrcTransport` in logging.
    pub fn wrap(inner: IrcTransport<T>) -> Logged<T> {
        Logged {
            inner: inner,
            view: LogView {
                sent: Arc::new(RwLock::new(vec![])),
                received: Arc::new(RwLock::new(vec![])),
            },
        }
    }

    /// Gets a view of the logging for this transport.
    pub fn view(&self) -> LogView {
        self.view.clone()
    }
}

impl<T> Stream for Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    type Item = Message;
    type Error = error::IrcError;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match try_ready!(self.inner.poll()) {
            Some(msg) => {
                let recv: error::Result<_> = self.view.received.write().map_err(|_| {
                    error::IrcError::PoisonedLog
                });
                recv?.push(msg.clone());
                Ok(Async::Ready(Some(msg)))
            }
            None => Ok(Async::Ready(None)),
        }
    }
}

impl<T> Sink for Logged<T>
where
    T: AsyncRead + AsyncWrite,
{
    type SinkItem = Message;
    type SinkError = error::IrcError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        let res = self.inner.start_send(item.clone())?;
        let sent: error::Result<_> = self.view.sent.write().map_err(|_| {
            error::IrcError::PoisonedLog
        });
        sent?.push(item);
        Ok(res)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        Ok(self.inner.poll_complete()?)
    }
}
<|endoftext|>


<commit_before>use codegen::buffer::Buffer;
use super::reg::Reg;

pub fn emit_movl_imm_reg(buf: &mut Buffer, val: u32, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, (0xB8 as u8) + reg.and7());
    emit_u32(buf, val);
}

pub fn emit_movq_reg_reg(buf: &mut Buffer, src: Reg, dest: Reg) {
    emit_rex(buf, 1, src.msb(), 0, dest.msb());
    emit_op(buf, 0x89);
    emit_modrm(buf, 0b11, src.and7(), dest.and7());
}

pub fn emit_pushq_reg(buf: &mut Buffer, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, 0x50 + reg.and7());
}

pub fn emit_popq_reg(buf: &mut Buffer, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, 0x58 + reg.and7());
}

pub fn emit_retq(buf: &mut Buffer) {
    emit_op(buf, 0xC3);
}

pub fn emit_u32(buf: &mut Buffer, val: u32) {
    buf.emit_u32(val)
}

pub fn emit_op(buf: &mut Buffer, opcode: u8) {
    buf.emit_u8(opcode);
}

fn emit_rex(buf: &mut Buffer, w: u8, r: u8, x: u8, b: u8) {
    assert!(w == 0 || w == 1);
    assert!(r == 0 || r == 1);
    assert!(x == 0 || x == 1);
    assert!(b == 0 || b == 1);

    buf.emit_u8(0x4 << 4 | w << 3 | r << 2 | x << 1 | b);
}

fn emit_modrm(buf: &mut Buffer, mod_: u8, reg: u8, rm: u8) {
    assert!(mod_ <= 3);
    assert!(reg <= 7);
    assert!(rm <= 7);

    buf.emit_u8(mod_ << 6 | reg << 3 | rm);
}

#[cfg(test)]
mod tests {
    use codegen::buffer::Buffer;
    use codegen::x64::reg::Reg::*;
    use super::*;

    macro_rules! assert_emit {
        (
            $($expr:expr),*;
            $name:ident
        ) => {{
            let mut buf = Buffer::new();
            $name(&mut buf);
            let expected = vec![$($expr,)*];

            assert_eq!(expected, buf.data());
        }};

        (
            $($expr:expr),*;
            $name:ident
            (
                    $($param:expr),+
            )
        ) => {{
            let mut buf = Buffer::new();
            $name(&mut buf, $($param,)*);
            let expected = vec![$($expr,)*];

            assert_eq!(expected, buf.data());
        }};
    }

    #[test]
    fn test_emit_retq() {
        assert_emit!(0xc3; emit_retq);
    }

    #[test]
    fn test_emit_popq_reg() {
        assert_emit!(0x58; emit_popq_reg(RAX));
        assert_emit!(0x5c; emit_popq_reg(RSP));
        assert_emit!(0x41, 0x58; emit_popq_reg(R8));
        assert_emit!(0x41, 0x5F; emit_popq_reg(R15));
    }

    #[test]
    fn test_emit_pushq_reg() {
        assert_emit!(0x50; emit_pushq_reg(RAX));
        assert_emit!(0x54; emit_pushq_reg(RSP));
        assert_emit!(0x41, 0x50; emit_pushq_reg(R8));
        assert_emit!(0x41, 0x57; emit_pushq_reg(R15));
    }

    #[test]
    fn test_emit_movq_reg_reg() {
        assert_emit!(0x4c, 0x89, 0xf8; emit_movq_reg_reg(R15, RAX));
        assert_emit!(0x49, 0x89, 0xc7; emit_movq_reg_reg(RAX, R15));
    }

    #[test]
    fn test_emit_movl_imm_reg() {
        assert_emit!(0xb8, 2, 0, 0, 0; emit_movl_imm_reg(2, RAX));
        assert_emit!(0x41, 0xbe, 3, 0, 0, 0; emit_movl_imm_reg(3, R14));
    }
}
<commit_msg>codegen: added emit_subq_imm_req<commit_after>use codegen::buffer::Buffer;
use super::reg::Reg;
use super::reg::Reg::*;

pub fn emit_movl_imm_reg(buf: &mut Buffer, val: u32, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, (0xB8 as u8) + reg.and7());
    emit_u32(buf, val);
}

pub fn emit_subq_imm_reg(buf: &mut Buffer, imm: i32, reg: Reg) {
    emit_rex(buf, 1, 0, 0, reg.msb());

    if fits_i8(imm) {
        emit_op(buf, 0x83);
        emit_modrm(buf, 0b11, 0b101, reg.and7());
        emit_u8(buf, imm as u8);
    } else if reg == RAX {
        emit_op(buf, 0x2d);
        emit_u32(buf, imm as u32);
    } else {
        emit_op(buf, 0x81);
        emit_modrm(buf, 0b11, 0b101, reg.and7());
        emit_u32(buf, imm as u32);
    }
}

pub fn emit_movq_reg_reg(buf: &mut Buffer, src: Reg, dest: Reg) {
    emit_rex(buf, 1, src.msb(), 0, dest.msb());
    emit_op(buf, 0x89);
    emit_modrm(buf, 0b11, src.and7(), dest.and7());
}

pub fn emit_pushq_reg(buf: &mut Buffer, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, 0x50 + reg.and7());
}

pub fn emit_popq_reg(buf: &mut Buffer, reg: Reg) {
    if reg.msb() != 0 {
        emit_rex(buf, 0, 0, 0, 1);
    }

    emit_op(buf, 0x58 + reg.and7());
}

pub fn emit_retq(buf: &mut Buffer) {
    emit_op(buf, 0xC3);
}

pub fn emit_u32(buf: &mut Buffer, val: u32) {
    buf.emit_u32(val)
}

pub fn emit_u8(buf: &mut Buffer, val: u8) {
    buf.emit_u8(val)
}

pub fn emit_op(buf: &mut Buffer, opcode: u8) {
    buf.emit_u8(opcode);
}

fn emit_rex(buf: &mut Buffer, w: u8, r: u8, x: u8, b: u8) {
    assert!(w == 0 || w == 1);
    assert!(r == 0 || r == 1);
    assert!(x == 0 || x == 1);
    assert!(b == 0 || b == 1);

    buf.emit_u8(0x4 << 4 | w << 3 | r << 2 | x << 1 | b);
}

fn emit_modrm(buf: &mut Buffer, mod_: u8, reg: u8, rm: u8) {
    assert!(mod_ < 4);
    assert!(reg < 8);
    assert!(rm < 8);

    buf.emit_u8(mod_ << 6 | reg << 3 | rm);
}

fn emit_sib(buf: &mut Buffer, scale: u8, index: u8, base: u8) {
    assert!(scale < 4);
    assert!(index < 4);
    assert!(base < 8);

    assert!(index != RSP.int() && index != R12.int());
    buf.emit_u8(scale << 6 | index << 3 | base);
}

pub fn fits_i8(imm: i32) -> bool {
    imm == (imm as i8) as i32
}

#[cfg(test)]
mod tests {
    use codegen::buffer::Buffer;
    use codegen::x64::reg::Reg::*;
    use super::*;

    macro_rules! assert_emit {
        (
            $($expr:expr),*;
            $name:ident
        ) => {{
            let mut buf = Buffer::new();
            $name(&mut buf);
            let expected = vec![$($expr,)*];

            assert_eq!(expected, buf.data());
        }};

        (
            $($expr:expr),*;
            $name:ident
            (
                    $($param:expr),+
            )
        ) => {{
            let mut buf = Buffer::new();
            $name(&mut buf, $($param,)*);
            let expected = vec![$($expr,)*];

            assert_eq!(expected, buf.data());
        }};
    }

    #[test]
    fn test_fits8() {
        assert!(fits_i8(1));
        assert!(fits_i8(0));
        assert!(fits_i8(-1));
        assert!(fits_i8(127));
        assert!(fits_i8(-128));

        assert!(!fits_i8(128));
        assert!(!fits_i8(-129));
    }

    #[test]
    fn test_emit_retq() {
        assert_emit!(0xc3; emit_retq);
    }

    #[test]
    fn test_emit_popq_reg() {
        assert_emit!(0x58; emit_popq_reg(RAX));
        assert_emit!(0x5c; emit_popq_reg(RSP));
        assert_emit!(0x41, 0x58; emit_popq_reg(R8));
        assert_emit!(0x41, 0x5F; emit_popq_reg(R15));
    }

    #[test]
    fn test_emit_pushq_reg() {
        assert_emit!(0x50; emit_pushq_reg(RAX));
        assert_emit!(0x54; emit_pushq_reg(RSP));
        assert_emit!(0x41, 0x50; emit_pushq_reg(R8));
        assert_emit!(0x41, 0x57; emit_pushq_reg(R15));
    }

    #[test]
    fn test_emit_movq_reg_reg() {
        assert_emit!(0x4c, 0x89, 0xf8; emit_movq_reg_reg(R15, RAX));
        assert_emit!(0x49, 0x89, 0xc7; emit_movq_reg_reg(RAX, R15));
    }

    #[test]
    fn test_emit_movl_imm_reg() {
        assert_emit!(0xb8, 2, 0, 0, 0; emit_movl_imm_reg(2, RAX));
        assert_emit!(0x41, 0xbe, 3, 0, 0, 0; emit_movl_imm_reg(3, R14));
    }

    #[test]
    fn test_emit_subq_imm_reg() {
        assert_emit!(0x48, 0x83, 0xe8, 0x11; emit_subq_imm_reg(0x11, RAX));
        assert_emit!(0x49, 0x83, 0xef, 0x11; emit_subq_imm_reg(0x11, R15));
        assert_emit!(0x48, 0x2d, 0x11, 0x22, 0, 0; emit_subq_imm_reg(0x2211, RAX));
        assert_emit!(0x48, 0x81, 0xe9, 0x11, 0x22, 0, 0; emit_subq_imm_reg(0x2211, RCX));
        assert_emit!(0x49, 0x81, 0xef, 0x11, 0x22, 0, 0; emit_subq_imm_reg(0x2211, R15));
    }
}
<|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.

//! Implementations of serialization for structures found in libcollections

use std::uint;
use std::default::Default;
use std::hash::{Hash, Hasher};

use {Decodable, Encodable, Decoder, Encoder};
use std::collections::{BTreeMap, BTreeSet, DList, RingBuf, HashMap, HashSet, VecMap};
use std::collections::enum_set::{EnumSet, CLike};

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E>
> Encodable<S, E> for DList<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
            }
            Ok(())
        })
    }
}

impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for DList<T> {
    fn decode(d: &mut D) -> Result<DList<T>, E> {
        d.read_seq(|d, len| {
            let mut list = DList::new();
            for i in range(0u, len) {
                list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(list)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E>
> Encodable<S, E> for RingBuf<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
            }
            Ok(())
        })
    }
}

impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for RingBuf<T> {
    fn decode(d: &mut D) -> Result<RingBuf<T>, E> {
        d.read_seq(|d, len| {
            let mut deque: RingBuf<T> = RingBuf::new();
            for i in range(0u, len) {
                deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(deque)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    K: Encodable<S, E> + PartialEq + Ord,
    V: Encodable<S, E> + PartialEq
> Encodable<S, E> for BTreeMap<K, V> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
            let mut i = 0;
            for (key, val) in self.iter() {
                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    K: Decodable<D, E> + PartialEq + Ord,
    V: Decodable<D, E> + PartialEq
> Decodable<D, E> for BTreeMap<K, V> {
    fn decode(d: &mut D) -> Result<BTreeMap<K, V>, E> {
        d.read_map(|d, len| {
            let mut map = BTreeMap::new();
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + PartialEq + Ord
> Encodable<S, E> for BTreeSet<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            let mut i = 0;
            for e in self.iter() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + PartialEq + Ord
> Decodable<D, E> for BTreeSet<T> {
    fn decode(d: &mut D) -> Result<BTreeSet<T>, E> {
        d.read_seq(|d, len| {
            let mut set = BTreeSet::new();
            for i in range(0u, len) {
                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(set)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + CLike
> Encodable<S, E> for EnumSet<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        let mut bits = 0;
        for item in self.iter() {
            bits |= item.to_uint();
        }
        s.emit_uint(bits)
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + CLike
> Decodable<D, E> for EnumSet<T> {
    fn decode(d: &mut D) -> Result<EnumSet<T>, E> {
        let bits = try!(d.read_uint());
        let mut set = EnumSet::new();
        for bit in range(0, uint::BITS) {
            if bits & (1 << bit) != 0 {
                set.insert(CLike::from_uint(1 << bit));
            }
        }
        Ok(set)
    }
}

impl<
    E,
    S: Encoder<E>,
    K: Encodable<S, E> + Hash<X> + Eq,
    V: Encodable<S, E>,
    X,
    H: Hasher<X>
> Encodable<S, E> for HashMap<K, V, H> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
            let mut i = 0;
            for (key, val) in self.iter() {
                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    K: Decodable<D, E> + Hash<S> + Eq,
    V: Decodable<D, E>,
    S,
    H: Hasher<S> + Default
> Decodable<D, E> for HashMap<K, V, H> {
    fn decode(d: &mut D) -> Result<HashMap<K, V, H>, E> {
        d.read_map(|d, len| {
            let hasher = Default::default();
            let mut map = HashMap::with_capacity_and_hasher(len, hasher);
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + Hash<X> + Eq,
    X,
    H: Hasher<X>
> Encodable<S, E> for HashSet<T, H> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            let mut i = 0;
            for e in self.iter() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + Hash<S> + Eq,
    S,
    H: Hasher<S> + Default
> Decodable<D, E> for HashSet<T, H> {
    fn decode(d: &mut D) -> Result<HashSet<T, H>, E> {
        d.read_seq(|d, len| {
            let mut set = HashSet::with_capacity_and_hasher(len, Default::default());
            for i in range(0u, len) {
                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(set)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    V: Encodable<S, E>
> Encodable<S, E> for TrieMap<V> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
                for (i, (key, val)) in self.iter().enumerate() {
                    try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                    try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                }
                Ok(())
            })
    }
}

impl<
    E,
    D: Decoder<E>,
    V: Decodable<D, E>
> Decodable<D, E> for TrieMap<V> {
    fn decode(d: &mut D) -> Result<TrieMap<V>, E> {
        d.read_map(|d, len| {
            let mut map = TrieMap::new();
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}

impl<E, S: Encoder<E>> Encodable<S, E> for TrieSet {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
                for (i, e) in self.iter().enumerate() {
                    try!(s.emit_seq_elt(i, |s| e.encode(s)));
                }
                Ok(())
            })
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for TrieSet {
    fn decode(d: &mut D) -> Result<TrieSet, E> {
        d.read_seq(|d, len| {
            let mut set = TrieSet::new();
            for i in range(0u, len) {
                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(set)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    V: Encodable<S, E>
> Encodable<S, E> for VecMap<V> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
                for (i, (key, val)) in self.iter().enumerate() {
                    try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                    try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                }
                Ok(())
            })
    }
}

impl<
    E,
    D: Decoder<E>,
    V: Decodable<D, E>
> Decodable<D, E> for VecMap<V> {
    fn decode(d: &mut D) -> Result<VecMap<V>, E> {
        d.read_map(|d, len| {
            let mut map = VecMap::new();
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}
<commit_msg>Farewell to the `Trie` collections ...<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.

//! Implementations of serialization for structures found in libcollections

use std::uint;
use std::default::Default;
use std::hash::{Hash, Hasher};

use {Decodable, Encodable, Decoder, Encoder};
use std::collections::{BTreeMap, BTreeSet, DList, RingBuf, HashMap, HashSet, VecMap};
use std::collections::enum_set::{EnumSet, CLike};

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E>
> Encodable<S, E> for DList<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
            }
            Ok(())
        })
    }
}

impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for DList<T> {
    fn decode(d: &mut D) -> Result<DList<T>, E> {
        d.read_seq(|d, len| {
            let mut list = DList::new();
            for i in range(0u, len) {
                list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(list)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E>
> Encodable<S, E> for RingBuf<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            for (i, e) in self.iter().enumerate() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
            }
            Ok(())
        })
    }
}

impl<E, D:Decoder<E>,T:Decodable<D, E>> Decodable<D, E> for RingBuf<T> {
    fn decode(d: &mut D) -> Result<RingBuf<T>, E> {
        d.read_seq(|d, len| {
            let mut deque: RingBuf<T> = RingBuf::new();
            for i in range(0u, len) {
                deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(deque)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    K: Encodable<S, E> + PartialEq + Ord,
    V: Encodable<S, E> + PartialEq
> Encodable<S, E> for BTreeMap<K, V> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
            let mut i = 0;
            for (key, val) in self.iter() {
                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    K: Decodable<D, E> + PartialEq + Ord,
    V: Decodable<D, E> + PartialEq
> Decodable<D, E> for BTreeMap<K, V> {
    fn decode(d: &mut D) -> Result<BTreeMap<K, V>, E> {
        d.read_map(|d, len| {
            let mut map = BTreeMap::new();
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + PartialEq + Ord
> Encodable<S, E> for BTreeSet<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            let mut i = 0;
            for e in self.iter() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + PartialEq + Ord
> Decodable<D, E> for BTreeSet<T> {
    fn decode(d: &mut D) -> Result<BTreeSet<T>, E> {
        d.read_seq(|d, len| {
            let mut set = BTreeSet::new();
            for i in range(0u, len) {
                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(set)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + CLike
> Encodable<S, E> for EnumSet<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        let mut bits = 0;
        for item in self.iter() {
            bits |= item.to_uint();
        }
        s.emit_uint(bits)
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + CLike
> Decodable<D, E> for EnumSet<T> {
    fn decode(d: &mut D) -> Result<EnumSet<T>, E> {
        let bits = try!(d.read_uint());
        let mut set = EnumSet::new();
        for bit in range(0, uint::BITS) {
            if bits & (1 << bit) != 0 {
                set.insert(CLike::from_uint(1 << bit));
            }
        }
        Ok(set)
    }
}

impl<
    E,
    S: Encoder<E>,
    K: Encodable<S, E> + Hash<X> + Eq,
    V: Encodable<S, E>,
    X,
    H: Hasher<X>
> Encodable<S, E> for HashMap<K, V, H> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
            let mut i = 0;
            for (key, val) in self.iter() {
                try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    K: Decodable<D, E> + Hash<S> + Eq,
    V: Decodable<D, E>,
    S,
    H: Hasher<S> + Default
> Decodable<D, E> for HashMap<K, V, H> {
    fn decode(d: &mut D) -> Result<HashMap<K, V, H>, E> {
        d.read_map(|d, len| {
            let hasher = Default::default();
            let mut map = HashMap::with_capacity_and_hasher(len, hasher);
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    T: Encodable<S, E> + Hash<X> + Eq,
    X,
    H: Hasher<X>
> Encodable<S, E> for HashSet<T, H> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_seq(self.len(), |s| {
            let mut i = 0;
            for e in self.iter() {
                try!(s.emit_seq_elt(i, |s| e.encode(s)));
                i += 1;
            }
            Ok(())
        })
    }
}

impl<
    E,
    D: Decoder<E>,
    T: Decodable<D, E> + Hash<S> + Eq,
    S,
    H: Hasher<S> + Default
> Decodable<D, E> for HashSet<T, H> {
    fn decode(d: &mut D) -> Result<HashSet<T, H>, E> {
        d.read_seq(|d, len| {
            let mut set = HashSet::with_capacity_and_hasher(len, Default::default());
            for i in range(0u, len) {
                set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d))));
            }
            Ok(set)
        })
    }
}

impl<
    E,
    S: Encoder<E>,
    V: Encodable<S, E>
> Encodable<S, E> for VecMap<V> {
    fn encode(&self, e: &mut S) -> Result<(), E> {
        e.emit_map(self.len(), |e| {
                for (i, (key, val)) in self.iter().enumerate() {
                    try!(e.emit_map_elt_key(i, |e| key.encode(e)));
                    try!(e.emit_map_elt_val(i, |e| val.encode(e)));
                }
                Ok(())
            })
    }
}

impl<
    E,
    D: Decoder<E>,
    V: Decodable<D, E>
> Decodable<D, E> for VecMap<V> {
    fn decode(d: &mut D) -> Result<VecMap<V>, E> {
        d.read_map(|d, len| {
            let mut map = VecMap::new();
            for i in range(0u, len) {
                let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d)));
                let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d)));
                map.insert(key, val);
            }
            Ok(map)
        })
    }
}
<|endoftext|>


<commit_before>mod terminal;
mod ansi;

use std::io::{self, Write};
use self::terminal::{Terminal, Event, Key};
use self::ansi::{clear, cursor};
use rff::choice::Choice;

pub struct Interface {
    choices: Vec<String>,
    matching: Vec<Choice>,
    search: String,
    terminal: Terminal
}

impl Interface {
    /// Creates a new Interface with the provided input choices.
    pub fn with_choices(choices: Vec<String>) -> Interface {
        let mut term = Terminal::from("/dev/tty").unwrap();
        term.set_raw_mode().unwrap();

        Interface {
            choices: choices,
            matching: Vec::new(),
            search: String::new(),
            terminal: term
        }
    }

    // Starts the interface
    pub fn run(&mut self) {
        self.filter_choices();
        self.render().expect("Unable to render");

        for event in self.terminal.events().unwrap() {
            match event {
                Ok(Event::Key(Key::Ctrl('c'))) => {
                    return;
                },

                Ok(Event::Key(Key::Char(ch))) => {
                    self.search.push(ch);
                    self.filter_choices();
                    self.render().expect("Unable to render");
                },

                Ok(Event::Key(Key::Backspace)) => {
                    self.search.pop();
                    self.filter_choices();
                    self.render().expect("Unable to render");
                },

                Ok(_) => {}
                Err(err) => write!(self.terminal, "{:?}", err).unwrap(),
            };
        }
    }

    fn filter_choices(&mut self) {
        let mut matches = self.choices.
            iter().
            cloned().
            filter_map(|choice| Choice::new(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(&a).unwrap());

        self.matching = matches;
    }

    fn render(&mut self) -> io::Result<()> {
        let ref mut term = self.terminal;
        write!(term, "{}{}", clear::Line, cursor::Column(1))?;
        write!(term, "> {}", self.search)?;

        for choice in self.matching.iter().take(10) {
            write!(term, "\r\n{}", clear::Line)?;
            write!(term, "{}", choice)?;
        }

        let column = format!("> {}", self.search).len() as u16;
        write!(term, "{}{}", cursor::Up(10), cursor::Column(column + 1))?;

        Ok(())
    }
}
<commit_msg>Respect number of matches when returning cursor<commit_after>mod terminal;
mod ansi;

use std::io::{self, Write};
use self::terminal::{Terminal, Event, Key};
use self::ansi::{clear, cursor};
use rff::choice::Choice;

pub struct Interface {
    choices: Vec<String>,
    matching: Vec<Choice>,
    search: String,
    terminal: Terminal
}

impl Interface {
    /// Creates a new Interface with the provided input choices.
    pub fn with_choices(choices: Vec<String>) -> Interface {
        let mut term = Terminal::from("/dev/tty").unwrap();
        term.set_raw_mode().unwrap();

        Interface {
            choices: choices,
            matching: Vec::new(),
            search: String::new(),
            terminal: term
        }
    }

    // Starts the interface
    pub fn run(&mut self) {
        self.filter_choices();
        self.render().expect("Unable to render");

        for event in self.terminal.events().unwrap() {
            match event {
                Ok(Event::Key(Key::Ctrl('c'))) => {
                    return;
                },

                Ok(Event::Key(Key::Char(ch))) => {
                    self.search.push(ch);
                    self.filter_choices();
                    self.render().expect("Unable to render");
                },

                Ok(Event::Key(Key::Backspace)) => {
                    self.search.pop();
                    self.filter_choices();
                    self.render().expect("Unable to render");
                },

                Ok(_) => {}
                Err(err) => write!(self.terminal, "{:?}", err).unwrap(),
            };
        }
    }

    fn filter_choices(&mut self) {
        let mut matches = self.choices.
            iter().
            cloned().
            filter_map(|choice| Choice::new(&self.search, choice)).
            collect::<Vec<_>>();

        matches.sort_by(|a, b| b.partial_cmp(&a).unwrap());

        self.matching = matches;
    }

    fn render(&mut self) -> io::Result<()> {
        let ref mut term = self.terminal;
        write!(term, "{}{}", clear::Line, cursor::Column(1))?;
        write!(term, "> {}", self.search)?;

        let choices = self.matching.iter().take(10);
        let num_choices = choices.len() as u16;

        for choice in choices {
            write!(term, "\r\n{}{}", clear::Line, choice)?;
        }

        let column = format!("> {}", self.search).len() as u16;
        write!(term, "{}{}", cursor::Up(num_choices), cursor::Column(column + 1))?;

        Ok(())
    }
}
<|endoftext|>


<commit_before>use hir::def_id::DefId;
use hir::HirId;
use hir::ItemKind;
use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{Adt, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::Underscore;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;

use crate::check::{
    method::probe::{self, Pick},
    FnCtxt,
};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    pub(super) fn lint_dot_call_from_2018(
        &self,
        self_ty: Ty<'tcx>,
        segment: &hir::PathSegment<'_>,
        span: Span,
        call_expr: &'tcx hir::Expr<'tcx>,
        self_expr: &'tcx hir::Expr<'tcx>,
        pick: &Pick<'tcx>,
        args: &'tcx [hir::Expr<'tcx>],
    ) {
        debug!(
            "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
            segment.ident, self_ty, call_expr, self_expr
        );

        // Rust 2021 and later is already using the new prelude
        if span.rust_2021() {
            return;
        }

        // These are the method names that were added to prelude in Rust 2021
        if !matches!(segment.ident.name, sym::try_into) {
            return;
        }

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick) {
            // avoid repeatedly adding unneeded `&*`s
            if pick.autoderefs == 1
                && matches!(
                    pick.autoref_or_ptr_adjustment,
                    Some(probe::AutorefOrPtrAdjustment::Autoref { .. })
                )
                && matches!(self_ty.kind(), Ref(..))
            {
                return;
            }

            // if it's an inherent `self` method (not `&self` or `&mut self`), it will take
            // precedence over the `TryInto` impl, and thus won't break in 2021 edition
            if pick.autoderefs == 0 && pick.autoref_or_ptr_adjustment.is_none() {
                return;
            }

            // Inherent impls only require not relying on autoref and autoderef in order to
            // ensure that the trait implementation won't be used
            self.tcx.struct_span_lint_hir(
                RUST_2021_PRELUDE_COLLISIONS,
                self_expr.hir_id,
                self_expr.span,
                |lint| {
                    let sp = self_expr.span;

                    let mut lint = lint.build(&format!(
                        "trait method `{}` will become ambiguous in Rust 2021",
                        segment.ident.name
                    ));

                    let derefs = "*".repeat(pick.autoderefs);

                    let autoref = match pick.autoref_or_ptr_adjustment {
                        Some(probe::AutorefOrPtrAdjustment::Autoref {
                            mutbl: Mutability::Mut,
                            ..
                        }) => "&mut ",
                        Some(probe::AutorefOrPtrAdjustment::Autoref {
                            mutbl: Mutability::Not,
                            ..
                        }) => "&",
                        Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
                    };
                    if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span)
                    {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{}{} as *const _", derefs, self_expr)
                        } else {
                            format!("{}{}{}", autoref, derefs, self_expr)
                        };

                        lint.span_suggestion(
                            sp,
                            "disambiguate the method call",
                            format!("({})", self_adjusted),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{}(...) as *const _", derefs)
                        } else {
                            format!("{}{}...", autoref, derefs)
                        };
                        lint.span_help(
                            sp,
                            &format!("disambiguate the method call with `({})`", self_adjusted,),
                        );
                    }

                    lint.emit();
                },
            );
        } else {
            // trait implementations require full disambiguation to not clash with the new prelude
            // additions (i.e. convert from dot-call to fully-qualified call)
            self.tcx.struct_span_lint_hir(
                RUST_2021_PRELUDE_COLLISIONS,
                call_expr.hir_id,
                call_expr.span,
                |lint| {
                    let sp = call_expr.span;
                    let trait_name = self.trait_path_or_bare_name(
                        span,
                        call_expr.hir_id,
                        pick.item.container.id(),
                    );

                    let mut lint = lint.build(&format!(
                        "trait method `{}` will become ambiguous in Rust 2021",
                        segment.ident.name
                    ));

                    let (self_adjusted, precise) = self.adjust_expr(pick, self_expr);
                    if precise {
                        let args = args
                            .iter()
                            .skip(1)
                            .map(|arg| {
                                format!(
                                    ", {}",
                                    self.sess().source_map().span_to_snippet(arg.span).unwrap()
                                )
                            })
                            .collect::<String>();

                        lint.span_suggestion(
                            sp,
                            "disambiguate the associated function",
                            format!(
                                "{}::{}({}{})",
                                trait_name, segment.ident.name, self_adjusted, args
                            ),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        lint.span_help(
                            sp,
                            &format!(
                                "disambiguate the associated function with `{}::{}(...)`",
                                trait_name, segment.ident,
                            ),
                        );
                    }

                    lint.emit();
                },
            );
        }
    }

    pub(super) fn lint_fully_qualified_call_from_2018(
        &self,
        span: Span,
        method_name: Ident,
        self_ty: Ty<'tcx>,
        self_ty_span: Span,
        expr_id: hir::HirId,
        pick: &Pick<'tcx>,
    ) {
        // Rust 2021 and later is already using the new prelude
        if span.rust_2021() {
            return;
        }

        // These are the fully qualified methods added to prelude in Rust 2021
        if !matches!(method_name.name, sym::try_into | sym::try_from | sym::from_iter) {
            return;
        }

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        // For from_iter, check if the type actually implements FromIterator.
        // If we know it does not, we don't need to warn.
        if method_name.name == sym::from_iter {
            if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) {
                if !self
                    .infcx
                    .type_implements_trait(
                        trait_def_id,
                        self_ty,
                        InternalSubsts::empty(),
                        self.param_env,
                    )
                    .may_apply()
                {
                    return;
                }
            }
        }

        // No need to lint if this is an inherent method called on a specific type, like `Vec::foo(...)`,
        // since such methods take precedence over trait methods.
        if matches!(pick.kind, probe::PickKind::InherentImplPick) {
            return;
        }

        self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
            // "type" refers to either a type or, more likely, a trait from which
            // the associated function or method is from.
            let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
            let trait_generics = self.tcx.generics_of(pick.item.container.id());

            let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
            let trait_name = if parameter_count == 0 {
                trait_path
            } else {
                format!(
                    "{}<{}>",
                    trait_path,
                    std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
                )
            };

            let mut lint = lint.build(&format!(
                "trait-associated function `{}` will become ambiguous in Rust 2021",
                method_name.name
            ));

            let self_ty_name = self
                .sess()
                .source_map()
                .span_to_snippet(self_ty_span)
                .unwrap_or_else(|_| self_ty.to_string());

            let self_ty_generics_count = match self_ty.kind() {
                // Get the number of generics the self type has (if an Adt) unless we can determine that
                // the user has written the self type with generics already which we (naively) do by looking
                // for a "<" in `self_ty_name`.
                Adt(def, _) if !self_ty_name.contains('<') => self.tcx.generics_of(def.did).count(),
                _ => 0,
            };
            let self_ty_generics = if self_ty_generics_count > 0 {
                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
            } else {
                String::new()
            };
            lint.span_suggestion(
                span,
                "disambiguate the associated function",
                format!(
                    "<{}{} as {}>::{}",
                    self_ty_name, self_ty_generics, trait_name, method_name.name,
                ),
                Applicability::MachineApplicable,
            );

            lint.emit();
        });
    }

    fn trait_path_or_bare_name(
        &self,
        span: Span,
        expr_hir_id: HirId,
        trait_def_id: DefId,
    ) -> String {
        self.trait_path(span, expr_hir_id, trait_def_id).unwrap_or_else(|| {
            let key = self.tcx.def_key(trait_def_id);
            format!("{}", key.disambiguated_data.data)
        })
    }

    fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Option<String> {
        let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?;
        let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?;
        if applicable_trait.import_ids.is_empty() {
            // The trait was declared within the module, we only need to use its name.
            return None;
        }

        let import_items: Vec<_> = applicable_trait
            .import_ids
            .iter()
            .map(|&import_id| {
                let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id);
                self.tcx.hir().expect_item(hir_id)
            })
            .collect();

        // Find an identifier with which this trait was imported (note that `_` doesn't count).
        let any_id = import_items
            .iter()
            .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None })
            .next();
        if let Some(any_id) = any_id {
            return Some(format!("{}", any_id));
        }

        // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
        // so just take the first one.
        match import_items[0].kind {
            ItemKind::Use(path, _) => Some(
                path.segments
                    .iter()
                    .map(|segment| segment.ident.to_string())
                    .collect::<Vec<_>>()
                    .join("::"),
            ),
            _ => {
                span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind);
            }
        }
    }

    /// Creates a string version of the `expr` that includes explicit adjustments.
    /// Returns the string and also a bool indicating whther this is a *precise*
    /// suggestion.
    fn adjust_expr(&self, pick: &Pick<'tcx>, expr: &hir::Expr<'tcx>) -> (String, bool) {
        let derefs = "*".repeat(pick.autoderefs);

        let autoref = match pick.autoref_or_ptr_adjustment {
            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Mut, .. }) => "&mut ",
            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Not, .. }) => "&",
            Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
        };

        let (expr_text, precise) =
            if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
                (expr_text, true)
            } else {
                ("(..)".to_string(), false)
            };

        let adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
            pick.autoref_or_ptr_adjustment
        {
            format!("{}{} as *const _", derefs, expr_text)
        } else {
            format!("{}{}{}", autoref, derefs, expr_text)
        };

        (adjusted_text, precise)
    }
}
<commit_msg>Keep turbofish in prelude collision lint.<commit_after>use hir::def_id::DefId;
use hir::HirId;
use hir::ItemKind;
use rustc_ast::Mutability;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{Adt, Ref, Ty};
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
use rustc_span::symbol::kw::Underscore;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;

use crate::check::{
    method::probe::{self, Pick},
    FnCtxt,
};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
    pub(super) fn lint_dot_call_from_2018(
        &self,
        self_ty: Ty<'tcx>,
        segment: &hir::PathSegment<'_>,
        span: Span,
        call_expr: &'tcx hir::Expr<'tcx>,
        self_expr: &'tcx hir::Expr<'tcx>,
        pick: &Pick<'tcx>,
        args: &'tcx [hir::Expr<'tcx>],
    ) {
        debug!(
            "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})",
            segment.ident, self_ty, call_expr, self_expr
        );

        // Rust 2021 and later is already using the new prelude
        if span.rust_2021() {
            return;
        }

        // These are the method names that were added to prelude in Rust 2021
        if !matches!(segment.ident.name, sym::try_into) {
            return;
        }

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick) {
            // avoid repeatedly adding unneeded `&*`s
            if pick.autoderefs == 1
                && matches!(
                    pick.autoref_or_ptr_adjustment,
                    Some(probe::AutorefOrPtrAdjustment::Autoref { .. })
                )
                && matches!(self_ty.kind(), Ref(..))
            {
                return;
            }

            // if it's an inherent `self` method (not `&self` or `&mut self`), it will take
            // precedence over the `TryInto` impl, and thus won't break in 2021 edition
            if pick.autoderefs == 0 && pick.autoref_or_ptr_adjustment.is_none() {
                return;
            }

            // Inherent impls only require not relying on autoref and autoderef in order to
            // ensure that the trait implementation won't be used
            self.tcx.struct_span_lint_hir(
                RUST_2021_PRELUDE_COLLISIONS,
                self_expr.hir_id,
                self_expr.span,
                |lint| {
                    let sp = self_expr.span;

                    let mut lint = lint.build(&format!(
                        "trait method `{}` will become ambiguous in Rust 2021",
                        segment.ident.name
                    ));

                    let derefs = "*".repeat(pick.autoderefs);

                    let autoref = match pick.autoref_or_ptr_adjustment {
                        Some(probe::AutorefOrPtrAdjustment::Autoref {
                            mutbl: Mutability::Mut,
                            ..
                        }) => "&mut ",
                        Some(probe::AutorefOrPtrAdjustment::Autoref {
                            mutbl: Mutability::Not,
                            ..
                        }) => "&",
                        Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
                    };
                    if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span)
                    {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{}{} as *const _", derefs, self_expr)
                        } else {
                            format!("{}{}{}", autoref, derefs, self_expr)
                        };

                        lint.span_suggestion(
                            sp,
                            "disambiguate the method call",
                            format!("({})", self_adjusted),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
                            pick.autoref_or_ptr_adjustment
                        {
                            format!("{}(...) as *const _", derefs)
                        } else {
                            format!("{}{}...", autoref, derefs)
                        };
                        lint.span_help(
                            sp,
                            &format!("disambiguate the method call with `({})`", self_adjusted,),
                        );
                    }

                    lint.emit();
                },
            );
        } else {
            // trait implementations require full disambiguation to not clash with the new prelude
            // additions (i.e. convert from dot-call to fully-qualified call)
            self.tcx.struct_span_lint_hir(
                RUST_2021_PRELUDE_COLLISIONS,
                call_expr.hir_id,
                call_expr.span,
                |lint| {
                    let sp = call_expr.span;
                    let trait_name = self.trait_path_or_bare_name(
                        span,
                        call_expr.hir_id,
                        pick.item.container.id(),
                    );

                    let mut lint = lint.build(&format!(
                        "trait method `{}` will become ambiguous in Rust 2021",
                        segment.ident.name
                    ));

                    let (self_adjusted, precise) = self.adjust_expr(pick, self_expr);
                    if precise {
                        let args = args
                            .iter()
                            .skip(1)
                            .map(|arg| {
                                format!(
                                    ", {}",
                                    self.sess().source_map().span_to_snippet(arg.span).unwrap()
                                )
                            })
                            .collect::<String>();

                        lint.span_suggestion(
                            sp,
                            "disambiguate the associated function",
                            format!(
                                "{}::{}{}({}{})",
                                trait_name,
                                segment.ident.name,
                                if let Some(args) = segment.args.as_ref().and_then(|args| self
                                    .sess()
                                    .source_map()
                                    .span_to_snippet(args.span_ext)
                                    .ok())
                                {
                                    // Keep turbofish.
                                    format!("::{}", args)
                                } else {
                                    String::new()
                                },
                                self_adjusted,
                                args,
                            ),
                            Applicability::MachineApplicable,
                        );
                    } else {
                        lint.span_help(
                            sp,
                            &format!(
                                "disambiguate the associated function with `{}::{}(...)`",
                                trait_name, segment.ident,
                            ),
                        );
                    }

                    lint.emit();
                },
            );
        }
    }

    pub(super) fn lint_fully_qualified_call_from_2018(
        &self,
        span: Span,
        method_name: Ident,
        self_ty: Ty<'tcx>,
        self_ty_span: Span,
        expr_id: hir::HirId,
        pick: &Pick<'tcx>,
    ) {
        // Rust 2021 and later is already using the new prelude
        if span.rust_2021() {
            return;
        }

        // These are the fully qualified methods added to prelude in Rust 2021
        if !matches!(method_name.name, sym::try_into | sym::try_from | sym::from_iter) {
            return;
        }

        // No need to lint if method came from std/core, as that will now be in the prelude
        if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
            return;
        }

        // For from_iter, check if the type actually implements FromIterator.
        // If we know it does not, we don't need to warn.
        if method_name.name == sym::from_iter {
            if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) {
                if !self
                    .infcx
                    .type_implements_trait(
                        trait_def_id,
                        self_ty,
                        InternalSubsts::empty(),
                        self.param_env,
                    )
                    .may_apply()
                {
                    return;
                }
            }
        }

        // No need to lint if this is an inherent method called on a specific type, like `Vec::foo(...)`,
        // since such methods take precedence over trait methods.
        if matches!(pick.kind, probe::PickKind::InherentImplPick) {
            return;
        }

        self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
            // "type" refers to either a type or, more likely, a trait from which
            // the associated function or method is from.
            let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
            let trait_generics = self.tcx.generics_of(pick.item.container.id());

            let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
            let trait_name = if parameter_count == 0 {
                trait_path
            } else {
                format!(
                    "{}<{}>",
                    trait_path,
                    std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
                )
            };

            let mut lint = lint.build(&format!(
                "trait-associated function `{}` will become ambiguous in Rust 2021",
                method_name.name
            ));

            let self_ty_name = self
                .sess()
                .source_map()
                .span_to_snippet(self_ty_span)
                .unwrap_or_else(|_| self_ty.to_string());

            let self_ty_generics_count = match self_ty.kind() {
                // Get the number of generics the self type has (if an Adt) unless we can determine that
                // the user has written the self type with generics already which we (naively) do by looking
                // for a "<" in `self_ty_name`.
                Adt(def, _) if !self_ty_name.contains('<') => self.tcx.generics_of(def.did).count(),
                _ => 0,
            };
            let self_ty_generics = if self_ty_generics_count > 0 {
                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
            } else {
                String::new()
            };
            lint.span_suggestion(
                span,
                "disambiguate the associated function",
                format!(
                    "<{}{} as {}>::{}",
                    self_ty_name, self_ty_generics, trait_name, method_name.name,
                ),
                Applicability::MachineApplicable,
            );

            lint.emit();
        });
    }

    fn trait_path_or_bare_name(
        &self,
        span: Span,
        expr_hir_id: HirId,
        trait_def_id: DefId,
    ) -> String {
        self.trait_path(span, expr_hir_id, trait_def_id).unwrap_or_else(|| {
            let key = self.tcx.def_key(trait_def_id);
            format!("{}", key.disambiguated_data.data)
        })
    }

    fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Option<String> {
        let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?;
        let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?;
        if applicable_trait.import_ids.is_empty() {
            // The trait was declared within the module, we only need to use its name.
            return None;
        }

        let import_items: Vec<_> = applicable_trait
            .import_ids
            .iter()
            .map(|&import_id| {
                let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id);
                self.tcx.hir().expect_item(hir_id)
            })
            .collect();

        // Find an identifier with which this trait was imported (note that `_` doesn't count).
        let any_id = import_items
            .iter()
            .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None })
            .next();
        if let Some(any_id) = any_id {
            return Some(format!("{}", any_id));
        }

        // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
        // so just take the first one.
        match import_items[0].kind {
            ItemKind::Use(path, _) => Some(
                path.segments
                    .iter()
                    .map(|segment| segment.ident.to_string())
                    .collect::<Vec<_>>()
                    .join("::"),
            ),
            _ => {
                span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind);
            }
        }
    }

    /// Creates a string version of the `expr` that includes explicit adjustments.
    /// Returns the string and also a bool indicating whther this is a *precise*
    /// suggestion.
    fn adjust_expr(&self, pick: &Pick<'tcx>, expr: &hir::Expr<'tcx>) -> (String, bool) {
        let derefs = "*".repeat(pick.autoderefs);

        let autoref = match pick.autoref_or_ptr_adjustment {
            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Mut, .. }) => "&mut ",
            Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Not, .. }) => "&",
            Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
        };

        let (expr_text, precise) =
            if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) {
                (expr_text, true)
            } else {
                ("(..)".to_string(), false)
            };

        let adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
            pick.autoref_or_ptr_adjustment
        {
            format!("{}{} as *const _", derefs, expr_text)
        } else {
            format!("{}{}{}", autoref, derefs, expr_text)
        };

        (adjusted_text, precise)
    }
}
<|endoftext|>


<commit_before>
use ram::{AddressBus, SUPERVISOR_PROGRAM, SUPERVISOR_DATA, USER_PROGRAM, USER_DATA};
use super::effective_address;
use super::Core;

pub fn ay_pd_8(core: &mut Core) -> u32 {
	let ea = effective_address::predecrement_ay(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn ax_pd_8(core: &mut Core) -> (u32, u32) {
	let ea = effective_address::predecrement_ax(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	(core.mem.read_byte(address_space, ea), ea)
}
pub fn ay_pi_8(core: &mut Core) -> u32 {
	let ea = effective_address::postincrement_ay(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn ay_ai_8(core: &mut Core) -> u32 {
	let ea = effective_address::address_indirect_ay(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn ay_di_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_ay(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn ay_ix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_ay(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn aw_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_word(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn al_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_long(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_DATA} else {USER_DATA};
	core.mem.read_byte(address_space, ea)
}
pub fn pcdi_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_pc(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_PROGRAM} else {USER_PROGRAM};
	core.mem.read_byte(address_space, ea)
}
pub fn pcix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_pc(core);
	let address_space = if core.s_flag != 0 {SUPERVISOR_PROGRAM} else {USER_PROGRAM};
	core.mem.read_byte(address_space, ea)
}
pub fn imm_8(core: &mut Core) -> u32 {
	let extension = core.read_imm_u16();
	mask_out_above_8!(extension) as u32
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{ax_pd_8, ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn predecrement_ax() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn predecrement_ay() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, ay_pd_8(core));
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, ay_pd_8(core));
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<commit_msg>Use Core read/write data/program shorthand<commit_after>
use super::effective_address;
use super::Core;

pub fn ay_pd_8(core: &mut Core) -> u32 {
	let ea = effective_address::predecrement_ay(core);
	core.read_data_byte(ea)
}
pub fn ax_pd_8(core: &mut Core) -> (u32, u32) {
	let ea = effective_address::predecrement_ax(core);
	(core.read_data_byte(ea), ea)
}
pub fn ay_pi_8(core: &mut Core) -> u32 {
	let ea = effective_address::postincrement_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_ai_8(core: &mut Core) -> u32 {
	let ea = effective_address::address_indirect_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_di_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_ix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_ay(core);
	core.read_data_byte(ea)
}
pub fn aw_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_word(core);
	core.read_data_byte(ea)
}
pub fn al_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_long(core);
	core.read_data_byte(ea)
}
pub fn pcdi_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_pc(core);
	core.read_program_byte(ea)
}
pub fn pcix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_pc(core);
	core.read_program_byte(ea)
}
pub fn imm_8(core: &mut Core) -> u32 {
	let extension = core.read_imm_u16();
	mask_out_above_8!(extension) as u32
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{ax_pd_8, ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn predecrement_ax() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn predecrement_ay() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, ay_pd_8(core));
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, ay_pd_8(core));
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#[cfg(not(all(feature = "nasm", target_arch = "x86_64")))]
pub use native::*;
#[cfg(all(feature = "nasm", target_arch = "x86_64"))]
pub use x86::*;

#[cfg(all(feature = "nasm", target_arch = "x86_64"))]
mod x86 {
  use arg_enum_proc_macro::ArgEnum;
  use std::env;

  #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
  pub enum CpuFeatureLevel {
    NATIVE,
    SSE2,
    SSSE3,
    AVX2,
  }

  impl CpuFeatureLevel {
    pub const fn len() -> usize {
      CpuFeatureLevel::AVX2 as usize + 1
    }

    #[inline(always)]
    pub fn as_index(self) -> usize {
      const LEN: usize = CpuFeatureLevel::len();
      assert_eq!(LEN & (LEN - 1), 0);
      self as usize & (LEN - 1)
    }
  }

  impl Default for CpuFeatureLevel {
    fn default() -> CpuFeatureLevel {
      let detected: CpuFeatureLevel = if is_x86_feature_detected!("avx2") {
        CpuFeatureLevel::AVX2
      } else if is_x86_feature_detected!("ssse3") {
        CpuFeatureLevel::SSSE3
      } else if is_x86_feature_detected!("sse2") {
        CpuFeatureLevel::SSE2
      } else {
        CpuFeatureLevel::NATIVE
      };
      let manual: CpuFeatureLevel = match env::var("RAV1E_CPU_TARGET") {
        Ok(feature) => match feature.as_ref() {
          "rust" => CpuFeatureLevel::NATIVE,
          "avx2" => CpuFeatureLevel::AVX2,
          "ssse3" => CpuFeatureLevel::SSSE3,
          "sse2" => CpuFeatureLevel::SSE2,
          _ => detected,
        },
        Err(_e) => detected,
      };
      if manual > detected {
        detected
      } else {
        manual
      }
    }
  }
}

#[cfg(not(all(feature = "nasm", target_arch = "x86_64")))]
mod native {
  use arg_enum_proc_macro::ArgEnum;

  #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
  pub enum CpuFeatureLevel {
    NATIVE,
  }

  impl Default for CpuFeatureLevel {
    fn default() -> CpuFeatureLevel {
      CpuFeatureLevel::NATIVE
    }
  }
}
<commit_msg>Temporarily disable SSE2 optimizations (#1755)<commit_after>// Copyright (c) 2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

#[cfg(not(all(feature = "nasm", target_arch = "x86_64")))]
pub use native::*;
#[cfg(all(feature = "nasm", target_arch = "x86_64"))]
pub use x86::*;

#[cfg(all(feature = "nasm", target_arch = "x86_64"))]
mod x86 {
  use arg_enum_proc_macro::ArgEnum;
  use std::env;

  #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
  pub enum CpuFeatureLevel {
    NATIVE,
    SSE2,
    SSSE3,
    AVX2,
  }

  impl CpuFeatureLevel {
    pub const fn len() -> usize {
      CpuFeatureLevel::AVX2 as usize + 1
    }

    #[inline(always)]
    pub fn as_index(self) -> usize {
      const LEN: usize = CpuFeatureLevel::len();
      assert_eq!(LEN & (LEN - 1), 0);
      self as usize & (LEN - 1)
    }
  }

  impl Default for CpuFeatureLevel {
    fn default() -> CpuFeatureLevel {
      let detected: CpuFeatureLevel = if is_x86_feature_detected!("avx2") {
        CpuFeatureLevel::AVX2
      } else if is_x86_feature_detected!("ssse3") {
        CpuFeatureLevel::SSSE3
      // FIXME: SSE2 is currently broken, see https://github.com/xiph/rav1e/issues/1715
      // } else if is_x86_feature_detected!("sse2") {
      //   CpuFeatureLevel::SSE2
      } else {
        CpuFeatureLevel::NATIVE
      };
      let manual: CpuFeatureLevel = match env::var("RAV1E_CPU_TARGET") {
        Ok(feature) => match feature.as_ref() {
          "rust" => CpuFeatureLevel::NATIVE,
          "avx2" => CpuFeatureLevel::AVX2,
          "ssse3" => CpuFeatureLevel::SSSE3,
          // "sse2" => CpuFeatureLevel::SSE2,
          _ => detected,
        },
        Err(_e) => detected,
      };
      if manual > detected {
        detected
      } else {
        manual
      }
    }
  }
}

#[cfg(not(all(feature = "nasm", target_arch = "x86_64")))]
mod native {
  use arg_enum_proc_macro::ArgEnum;

  #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, ArgEnum)]
  pub enum CpuFeatureLevel {
    NATIVE,
  }

  impl Default for CpuFeatureLevel {
    fn default() -> CpuFeatureLevel {
      CpuFeatureLevel::NATIVE
    }
  }
}
<|endoftext|>


<commit_before>
pub struct Task {
        id: int,
        todo: ~str,
        priority: char,
        finished: bool,
        raw_todo: ~str,
        contexts: & 'static [~str],
        projects: & 'static [~str]
}

impl Task {
        pub fn to_str(&self) -> ~str {
                return format!("{:d} {:b} ({:c}) '{:s}' \"{:s}\"",
                                self.id, self.finished, self.priority,
                                self.todo, self.raw_todo)
        }

        pub fn create(todo: ~str, id: int) -> Task {
                let mut task = Task{id: id, raw_todo: todo.clone(), todo: todo.clone(),
                                        finished: false, priority: '^',
                                        contexts: &[], projects: &[]};

                if (todo.slice(0, 2) == "x ") {
                        task.finished = true;
                        task.todo = todo.slice(2, todo.len()).to_owned()
                }

                return task;
        }
}

#[test]
fn simple_todo_create_test() {
        let t = Task::create(~"some important task", 1);

        assert!(t.id == 1);
        assert!(t.priority == '^');
        assert!(t.finished == false);
        assert!(t.todo == ~"some important task");
        assert!(t.raw_todo == ~"some important task");
}

#[test]
fn todo_to_str_test() {
        let t = Task::create(~"some important task", 1);

        assert_eq!(t.to_str(), ~"1 false (^) 'some important task' \"some important task\"")

        let x = Task::create(~"x some important task", 1);
        assert_eq!(x.to_str(), ~"1 true (^) 'some important task' \"x some important task\"")
}
<commit_msg>some more tests again<commit_after>
pub struct Task {
        id: int,
        todo: ~str,
        priority: char,
        finished: bool,
        raw_todo: ~str,
        contexts: & 'static [~str],
        projects: & 'static [~str]
}

impl Task {
        pub fn to_str(&self) -> ~str {
                return format!("{:d} {:b} ({:c}) '{:s}' \"{:s}\"",
                                self.id, self.finished, self.priority,
                                self.todo, self.raw_todo)
        }

        pub fn create(todo: ~str, id: int) -> Task {
                let mut task = Task{id: id, raw_todo: todo.clone(), todo: todo.clone(),
                                        finished: false, priority: '^',
                                        contexts: &[], projects: &[]};

                let mut t = todo.clone();

                if (t.slice(0, 2) == "x ") {
                        task.finished = true;
                        t = t.slice(2, t.len()).to_owned();
                }

                //if (todo[0])
                task.todo = t;

                return task;
        }
}

#[test]
fn simple_todo_create_test() {
        let t = Task::create(~"some important task", 1);

        assert_eq!(t.id , 1);
        assert_eq!(t.priority , '^');
        assert_eq!(t.finished , false);
        assert_eq!(t.todo , ~"some important task");
        assert_eq!(t.raw_todo , ~"some important task");
}

#[test]
fn simple_todo_with_priority_test() {
        let t = Task::create(~"(A) some important task with priority", 1);

        assert_eq!(t.id , 1);
        assert_eq!(t.priority , '^');
        assert_eq!(t.finished , false);
        assert_eq!(t.todo , ~"some important task with priority");
        assert_eq!(t.raw_todo , ~"(A) some important task with priority");
}

#[test]
fn todo_to_str_test() {
        let t = Task::create(~"some important task", 1);

        assert_eq!(t.to_str(), ~"1 false (^) 'some important task' \"some important task\"")

        let x = Task::create(~"x some important task", 1);
        assert_eq!(x.to_str(), ~"1 true (^) 'some important task' \"x some important task\"")
}
<|endoftext|>


<commit_before>
extern crate ndarray;
#[macro_use]
extern crate ndarray_linalg;

use ndarray::*;
use ndarray_linalg::*;
use std::cmp::min;

fn test(a: Array2<f64>, n: usize, m: usize) {
    let ans = a.clone();
    println!("a = \n{:?}", &a);
    let (q, r): (Array2<_>, Array2<_>) = a.qr().unwrap();
    println!("q = \n{:?}", &q);
    println!("r = \n{:?}", &r);
    assert_close_l2!(&q.t().dot(&q), &Array::eye(min(n, m)), 1e-7);
    assert_close_l2!(&q.dot(&r), &ans, 1e-7);
    assert_close_l2!(&r.clone().into_triangular(UPLO::Upper), &r, 1e-7);
}

#[test]
fn qr_square() {
    let a = random((3, 3));
    test(a, 3, 3);
}

#[test]
fn qr_square_t() {
    let a = random((3, 3).f());
    test(a, 3, 3);
}

#[test]
fn qr_3x4() {
    let a = random((3, 4));
    test(a, 3, 4);
}

#[test]
fn qr_3x4_t() {
    let a = random((3, 4).f());
    test(a, 3, 4);
}

#[test]
fn qr_4x3() {
    let a = random((4, 3));
    test(a, 4, 3);
}

#[test]
fn qr_4x3_t() {
    let a = random((4, 3).f());
    test(a, 4, 3);
}
<commit_msg>Add test for qr_square<commit_after>
extern crate ndarray;
#[macro_use]
extern crate ndarray_linalg;

use ndarray::*;
use ndarray_linalg::*;
use std::cmp::min;

fn test(a: Array2<f64>, n: usize, m: usize) {
    let ans = a.clone();
    println!("a = \n{:?}", &a);
    let (q, r): (Array2<_>, Array2<_>) = a.qr().unwrap();
    println!("q = \n{:?}", &q);
    println!("r = \n{:?}", &r);
    assert_close_l2!(&q.t().dot(&q), &Array::eye(min(n, m)), 1e-7);
    assert_close_l2!(&q.dot(&r), &ans, 1e-7);
    assert_close_l2!(&r.clone().into_triangular(UPLO::Upper), &r, 1e-7);
}

fn test_square(a: Array2<f64>, n: usize, m: usize) {
    let ans = a.clone();
    println!("a = \n{:?}", &a);
    let (q, r): (Array2<_>, Array2<_>) = a.qr_square().unwrap();
    println!("q = \n{:?}", &q);
    println!("r = \n{:?}", &r);
    assert_close_l2!(&q.t().dot(&q), &Array::eye(min(n, m)), 1e-7);
    assert_close_l2!(&q.dot(&r), &ans, 1e-7);
    assert_close_l2!(&r.clone().into_triangular(UPLO::Upper), &r, 1e-7);
}

#[test]
fn qr_sq() {
    let a = random((3, 3));
    test_square(a, 3, 3);
}

#[test]
fn qr_sq_t() {
    let a = random((3, 3).f());
    test_square(a, 3, 3);
}

#[test]
fn qr_3x3() {
    let a = random((3, 3));
    test(a, 3, 3);
}

#[test]
fn qr_3x3_t() {
    let a = random((3, 3).f());
    test(a, 3, 3);
}

#[test]
fn qr_3x4() {
    let a = random((3, 4));
    test(a, 3, 4);
}

#[test]
fn qr_3x4_t() {
    let a = random((3, 4).f());
    test(a, 3, 4);
}

#[test]
fn qr_4x3() {
    let a = random((4, 3));
    test(a, 4, 3);
}

#[test]
fn qr_4x3_t() {
    let a = random((4, 3).f());
    test(a, 4, 3);
}
<|endoftext|>