<commit_before>
pub struct Task {
        id: int,
        todo: ~str,
        priority: char,
        finished: bool,
        raw_todo: ~str,
        create_date: ~str,
        finish_date: ~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(text: ~str, id: int) -> Task {
                let mut task = Task{id: id, raw_todo: text.clone(), todo: text.clone(),
                                        finished: false, priority: '^',
                                        create_date: ~"", finish_date: ~"",
                                        contexts: &[], projects: &[]};

                let mut todo = text.clone();

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

                let mut chars = todo.chars().to_owned_vec();
                if (chars[0] == '(' && chars[2] == ')' &&
                    chars[1].is_uppercase() && chars[3] == ' ') {

                        task.priority = chars[1];
                        todo = todo.slice(4, todo.len()).to_owned();
                }

                chars = todo.chars().to_owned_vec();

                if (chars[10] == ' ' && chars[4] == '-' && chars[7] == '-') {
                        task.create_date = todo.slice(0, 10).to_owned();
                        todo = todo.slice(11, todo.len()).to_owned();
                }

                task.todo = todo;

                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 , 'A');
        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");

        let ts = Task::create(~"(a) some important task with priority", 1);

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

}

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

        assert_eq!(t.id , 1);
        assert_eq!(t.priority , 'A');
        assert_eq!(t.finished , false);
        assert_eq!(t.todo , ~"some important task with priority");
        assert_eq!(t.raw_todo , ~"(A) 2014-03-02 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\"")
}
<commit_msg>to_str and stuff<commit_after>
pub struct Task {
        id: int,
        todo: ~str,
        priority: char,
        finished: bool,
        raw_todo: ~str,
        create_date: ~str,
        finish_date: ~str,
        contexts: & 'static [~str],
        projects: & 'static [~str]
}

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

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

                let mut todo = text.clone();

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

                let mut chars = todo.chars().to_owned_vec();
                if (chars[0] == '(' && chars[2] == ')' &&
                    chars[1].is_uppercase() && chars[3] == ' ') {

                        task.priority = chars[1];
                        todo = todo.slice(4, todo.len()).to_owned();
                }

                chars = todo.chars().to_owned_vec();

                if (chars[10] == ' ' && chars[4] == '-' && chars[7] == '-') {
                        task.create_date = todo.slice(0, 10).to_owned();
                        todo = todo.slice(11, todo.len()).to_owned();
                }

                task.todo = todo;

                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 , 'A');
        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");

        let ts = Task::create(~"(a) some important task with priority", 1);

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

}

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

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

#[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 env_logger;
extern crate log;

use self::env_logger::LogBuilder;
use self::log::{LogRecord, LogLevelFilter};
use std::env;
use std::sync::{Once, ONCE_INIT};

pub struct LoggerUtils {}

static LOGGER_INIT: Once = ONCE_INIT;

impl LoggerUtils {
    pub fn init() {
        LOGGER_INIT.call_once(|| {
            let format = |record: &LogRecord| {
                format!("{:>5}|{:<30}|{:>35}:{:<4}| {}", record.level(), record.target(), record.location().file(), record.location().line(), record.args())
            };
            let mut builder = LogBuilder::new();
            builder.format(format).filter(None, LogLevelFilter::Info);

            if env::var("RUST_LOG").is_ok() {
                builder.parse(&env::var("RUST_LOG").unwrap());
            }

            builder.init().unwrap();
        });
    }
}

#[macro_export]
macro_rules! try_log {
    ($expr:expr) => (match $expr {
        Ok(val) => val,
        Err(err) => {
            error!("try_log! | {}", err);
            return Err(From::from(err))
        }
    })
}

macro_rules! _map_err {
    ($lvl:expr, $expr:expr) => (
        |err| {
            log!($lvl, "{} - {}", $expr, err);
            err
        }
    );
    ($lvl:expr) => (
        |err| {
            log!($lvl, "{}", err);
            err
        }
    )
}

#[macro_export]
macro_rules! map_err_err {
    () => ( _map_err!(::log::LogLevel::Error) );
    ($($arg:tt)*) => ( _map_err!(::log::LogLevel::Error, $($arg)*) )
}

#[macro_export]
macro_rules! map_err_trace {
    () => ( _map_err!(::log::LogLevel::Trace) );
    ($($arg:tt)*) => ( _map_err!(::log::LogLevel::Trace, $($arg)*) )
}
<commit_msg>Off logging by default in libindy library.<commit_after>extern crate env_logger;
extern crate log;

use self::env_logger::LogBuilder;
use self::log::{LogRecord, LogLevelFilter};
use std::env;
use std::sync::{Once, ONCE_INIT};

pub struct LoggerUtils {}

static LOGGER_INIT: Once = ONCE_INIT;

impl LoggerUtils {
    pub fn init() {
        LOGGER_INIT.call_once(|| {
            let format = |record: &LogRecord| {
                format!("{:>5}|{:<30}|{:>35}:{:<4}| {}", record.level(), record.target(), record.location().file(), record.location().line(), record.args())
            };
            let mut builder = LogBuilder::new();
            builder.format(format).filter(None, LogLevelFilter::Off);

            if env::var("RUST_LOG").is_ok() {
                builder.parse(&env::var("RUST_LOG").unwrap());
            }

            builder.init().unwrap();
        });
    }
}

#[macro_export]
macro_rules! try_log {
    ($expr:expr) => (match $expr {
        Ok(val) => val,
        Err(err) => {
            error!("try_log! | {}", err);
            return Err(From::from(err))
        }
    })
}

macro_rules! _map_err {
    ($lvl:expr, $expr:expr) => (
        |err| {
            log!($lvl, "{} - {}", $expr, err);
            err
        }
    );
    ($lvl:expr) => (
        |err| {
            log!($lvl, "{}", err);
            err
        }
    )
}

#[macro_export]
macro_rules! map_err_err {
    () => ( _map_err!(::log::LogLevel::Error) );
    ($($arg:tt)*) => ( _map_err!(::log::LogLevel::Error, $($arg)*) )
}

#[macro_export]
macro_rules! map_err_trace {
    () => ( _map_err!(::log::LogLevel::Trace) );
    ($($arg:tt)*) => ( _map_err!(::log::LogLevel::Trace, $($arg)*) )
}
<|endoftext|>


<commit_before>pub fn hello(name: Option<&str>) -> String {
    match name {
        Some(ref n) => format!("Hello, {}!", n),
        None => "Hello, World!".to_string(),
    }
}
<commit_msg>hello-world: No need to use `ref` on a `&str`<commit_after>pub fn hello(name: Option<&str>) -> String {
    match name {
        Some(n) => format!("Hello, {}!", n),
        None => "Hello, World!".to_string(),
    }
}
<|endoftext|>


<commit_before>use serde_json::Value;
use router::Router;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{View, Error as StorageError};
use messages::{Message, RawTransaction, Error as MessageError};
use node::{Node, State, NodeChannel, TxSender};
use node::state::ValidatorState;
use events::Milliseconds;
use blockchain::{StoredConfiguration, ConsensusConfig, Blockchain};

pub trait Transaction: Message + 'static {
    fn verify(&self) -> bool;
    fn execute(&self, view: &View) -> Result<(), StorageError>;
    fn info(&self) -> Value {
        Value::Null
    }
}

pub trait Service: Send + Sync + 'static {
    fn service_id(&self) -> u16;

    fn state_hash(&self, _: &View) -> Result<Vec<Hash>, StorageError> {
        Ok(Vec::new())
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    fn handle_genesis_block(&self, _: &View) -> Result<Value, StorageError> {
        Ok(Value::Null)
    }

    fn handle_commit(&self, _: &mut NodeState) -> Result<(), StorageError> {
        Ok(())
    }

    fn wire_public_api(&self, _: &ApiContext, _: &mut Router) {}

    fn wire_private_api(&self, _: &ApiContext, _: &mut Router) {}
}

pub struct NodeState<'a, 'b> {
    state: &'a mut State,
    view: &'b View,
    txs: Vec<Box<Transaction>>,
}

impl<'a, 'b> NodeState<'a, 'b> {
    pub fn new(state: &'a mut State, view: &'b View) -> NodeState<'a, 'b> {
        NodeState {
            state: state,
            view: view,
            txs: Vec::new(),
        }
    }

    pub fn validator_state(&self) -> &Option<ValidatorState> {
        self.state.validator_state()
    }

    pub fn view(&self) -> &View {
        self.view
    }

    pub fn height(&self) -> u64 {
        self.state.height()
    }

    pub fn round(&self) -> u32 {
        self.state.round()
    }

    pub fn validators(&self) -> &[PublicKey] {
        self.state.validators()
    }

    pub fn public_key(&self) -> &PublicKey {
        self.state.public_key()
    }

    pub fn secret_key(&self) -> &SecretKey {
        self.state.secret_key()
    }

    pub fn actual_config(&self) -> &StoredConfiguration {
        self.state.config()
    }

    pub fn consensus_config(&self) -> &ConsensusConfig {
        self.state.consensus_config()
    }

    pub fn service_config(&self, service: &Service) -> &Value {
        let id = service.service_id();
        self.state
            .services_config()
            .get(&format!("{}", id))
            .unwrap()
    }

    pub fn update_config(&mut self, new_config: StoredConfiguration) {
        self.state.update_config(new_config)
    }

    pub fn propose_timeout(&self) -> Milliseconds {
        self.state.propose_timeout()
    }

    pub fn set_propose_timeout(&mut self, timeout: Milliseconds) {
        self.state.set_propose_timeout(timeout)
    }

    pub fn add_transaction<T: Transaction>(&mut self, tx: T) {
        assert!(tx.verify());
        self.txs.push(Box::new(tx));
    }

    pub fn transactions(self) -> Vec<Box<Transaction>> {
        self.txs
    }
}

pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: TxSender<NodeChannel>,
    public_key: PublicKey,
    secret_key: SecretKey,
}

impl ApiContext {
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: node.state().public_key().clone(),
            secret_key: node.state().secret_key().clone(),
        }
    }

    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    pub fn node_channel(&self) -> &TxSender<NodeChannel> {
        &self.node_channel
    }

    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }
}<commit_msg>Fix clippy warning<commit_after>use serde_json::Value;
use router::Router;

use crypto::{Hash, PublicKey, SecretKey};
use storage::{View, Error as StorageError};
use messages::{Message, RawTransaction, Error as MessageError};
use node::{Node, State, NodeChannel, TxSender};
use node::state::ValidatorState;
use events::Milliseconds;
use blockchain::{StoredConfiguration, ConsensusConfig, Blockchain};

pub trait Transaction: Message + 'static {
    fn verify(&self) -> bool;
    fn execute(&self, view: &View) -> Result<(), StorageError>;
    fn info(&self) -> Value {
        Value::Null
    }
}

pub trait Service: Send + Sync + 'static {
    fn service_id(&self) -> u16;

    fn state_hash(&self, _: &View) -> Result<Vec<Hash>, StorageError> {
        Ok(Vec::new())
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, MessageError>;

    fn handle_genesis_block(&self, _: &View) -> Result<Value, StorageError> {
        Ok(Value::Null)
    }

    fn handle_commit(&self, _: &mut NodeState) -> Result<(), StorageError> {
        Ok(())
    }

    fn wire_public_api(&self, _: &ApiContext, _: &mut Router) {}

    fn wire_private_api(&self, _: &ApiContext, _: &mut Router) {}
}

pub struct NodeState<'a, 'b> {
    state: &'a mut State,
    view: &'b View,
    txs: Vec<Box<Transaction>>,
}

impl<'a, 'b> NodeState<'a, 'b> {
    pub fn new(state: &'a mut State, view: &'b View) -> NodeState<'a, 'b> {
        NodeState {
            state: state,
            view: view,
            txs: Vec::new(),
        }
    }

    pub fn validator_state(&self) -> &Option<ValidatorState> {
        self.state.validator_state()
    }

    pub fn view(&self) -> &View {
        self.view
    }

    pub fn height(&self) -> u64 {
        self.state.height()
    }

    pub fn round(&self) -> u32 {
        self.state.round()
    }

    pub fn validators(&self) -> &[PublicKey] {
        self.state.validators()
    }

    pub fn public_key(&self) -> &PublicKey {
        self.state.public_key()
    }

    pub fn secret_key(&self) -> &SecretKey {
        self.state.secret_key()
    }

    pub fn actual_config(&self) -> &StoredConfiguration {
        self.state.config()
    }

    pub fn consensus_config(&self) -> &ConsensusConfig {
        self.state.consensus_config()
    }

    pub fn service_config(&self, service: &Service) -> &Value {
        let id = service.service_id();
        self.state
            .services_config()
            .get(&format!("{}", id))
            .unwrap()
    }

    pub fn update_config(&mut self, new_config: StoredConfiguration) {
        self.state.update_config(new_config)
    }

    pub fn propose_timeout(&self) -> Milliseconds {
        self.state.propose_timeout()
    }

    pub fn set_propose_timeout(&mut self, timeout: Milliseconds) {
        self.state.set_propose_timeout(timeout)
    }

    pub fn add_transaction<T: Transaction>(&mut self, tx: T) {
        assert!(tx.verify());
        self.txs.push(Box::new(tx));
    }

    pub fn transactions(self) -> Vec<Box<Transaction>> {
        self.txs
    }
}

pub struct ApiContext {
    blockchain: Blockchain,
    node_channel: TxSender<NodeChannel>,
    public_key: PublicKey,
    secret_key: SecretKey,
}

impl ApiContext {
    pub fn new(node: &Node) -> ApiContext {
        let handler = node.handler();
        ApiContext {
            blockchain: handler.blockchain.clone(),
            node_channel: node.channel(),
            public_key: *node.state().public_key(),
            secret_key: node.state().secret_key().clone(),
        }
    }

    pub fn blockchain(&self) -> &Blockchain {
        &self.blockchain
    }

    pub fn node_channel(&self) -> &TxSender<NodeChannel> {
        &self.node_channel
    }

    pub fn public_key(&self) -> &PublicKey {
        &self.public_key
    }

    pub fn secret_key(&self) -> &SecretKey {
        &self.secret_key
    }
}<|endoftext|>


<commit_before>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::{
    conversion::analysis::fun::{ArgumentAnalysis, ReceiverMutability},
    types::QualifiedName,
};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use std::{borrow::Cow, collections::HashSet};
use syn::{
    parse_quote, punctuated::Punctuated, token::Comma, FnArg, GenericArgument, PatType, Path,
    PathSegment, ReturnType, Type, TypePath, TypeReference,
};

/// Function which can add explicit lifetime parameters to function signatures
/// where necessary, based on analysis of parameters and return types.
/// This is necessary in three cases:
/// 1) where the parameter is a Pin<&mut T>
///    and the return type is some kind of reference - because lifetime elision
///    is not smart enough to see inside a Pin.
/// 2) as a workaround for https://github.com/dtolnay/cxx/issues/1024, where the
///    input parameter is a non-POD type but the output reference is a POD or
///    built-in type
/// 3) Any parameter is any form of reference, and we're returning an `impl New`
pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
    param_details: &[ArgumentAnalysis],
    mut params: Punctuated<FnArg, Comma>,
    ret_type: &'r ReturnType,
    non_pod_types: &HashSet<QualifiedName>,
    assert_all_parameters_are_references: bool,
) -> (
    Option<TokenStream>,
    Punctuated<FnArg, Comma>,
    Cow<'r, ReturnType>,
) {
    let has_mutable_receiver = param_details
        .iter()
        .any(|pd| matches!(pd.self_type, Some((_, ReceiverMutability::Mutable))));

    let any_param_is_reference = param_details.iter().any(|pd| pd.was_reference);
    let return_type_is_impl = return_type_is_impl(ret_type);
    let non_pod_ref_param = reference_parameter_is_non_pod_reference(&params, non_pod_types);
    let ret_type_pod = return_type_is_pod_or_known_type_reference(ret_type, non_pod_types);
    let returning_impl_with_a_reference_param = return_type_is_impl && any_param_is_reference;
    let hits_1024_bug = non_pod_ref_param && ret_type_pod;
    if !(has_mutable_receiver || hits_1024_bug || returning_impl_with_a_reference_param) {
        return (None, params, Cow::Borrowed(ret_type));
    }
    let new_return_type = match ret_type {
        ReturnType::Type(rarrow, boxed_type) => match boxed_type.as_ref() {
            Type::Reference(rtr) => {
                let mut new_rtr = rtr.clone();
                new_rtr.lifetime = Some(parse_quote! { 'a });
                Some(ReturnType::Type(
                    *rarrow,
                    Box::new(Type::Reference(new_rtr)),
                ))
            }
            Type::Path(typ) => {
                let mut new_path = typ.clone();
                add_lifetime_to_pinned_reference(&mut new_path.path.segments)
                    .ok()
                    .map(|_| ReturnType::Type(*rarrow, Box::new(Type::Path(new_path))))
            }
            Type::ImplTrait(tyit) => {
                let old_tyit = tyit.to_token_stream();
                log::info!("It's {}", old_tyit.to_string());
                Some(parse_quote! {
                    #rarrow #old_tyit + 'a
                })
            }
            _ => None,
        },
        _ => None,
    };

    match new_return_type {
        None => (None, params, Cow::Borrowed(ret_type)),
        Some(new_return_type) => {
            for mut param in params.iter_mut() {
                match &mut param {
                    FnArg::Typed(PatType { ty, .. }) => match ty.as_mut() {
                        Type::Path(TypePath {
                            path: Path { segments, .. },
                            ..
                        }) => add_lifetime_to_pinned_reference(segments).unwrap_or_else(|e| {
                            if assert_all_parameters_are_references {
                                panic!("Expected a pinned reference: {:?}", e)
                            }
                        }),
                        Type::Reference(tyr) => add_lifetime_to_reference(tyr),
                        _ => panic!("Expected Pin<&mut T> or &T"),
                    },
                    _ => panic!("Unexpected fnarg"),
                }
            }

            (Some(quote! { <'a> }), params, Cow::Owned(new_return_type))
        }
    }
}

fn reference_parameter_is_non_pod_reference(
    params: &Punctuated<FnArg, Comma>,
    non_pod_types: &HashSet<QualifiedName>,
) -> bool {
    params.iter().any(|param| match param {
        FnArg::Typed(PatType { ty, .. }) => match ty.as_ref() {
            Type::Reference(TypeReference { elem, .. }) => match elem.as_ref() {
                Type::Path(typ) => {
                    let qn = QualifiedName::from_type_path(typ);
                    non_pod_types.contains(&qn)
                }
                _ => false,
            },
            _ => false,
        },
        _ => false,
    })
}

fn return_type_is_pod_or_known_type_reference(
    ret_type: &ReturnType,
    non_pod_types: &HashSet<QualifiedName>,
) -> bool {
    match ret_type {
        ReturnType::Type(_, boxed_type) => match boxed_type.as_ref() {
            Type::Reference(rtr) => match rtr.elem.as_ref() {
                Type::Path(typ) => {
                    let qn = QualifiedName::from_type_path(typ);
                    !non_pod_types.contains(&qn)
                }
                _ => false,
            },
            _ => false,
        },
        _ => false,
    }
}

fn return_type_is_impl(ret_type: &ReturnType) -> bool {
    matches!(ret_type, ReturnType::Type(_, boxed_type) if matches!(boxed_type.as_ref(), Type::ImplTrait(..)))
}

#[derive(Debug)]
enum AddLifetimeError {
    WasNotPin,
}

fn add_lifetime_to_pinned_reference(
    segments: &mut Punctuated<PathSegment, syn::token::Colon2>,
) -> Result<(), AddLifetimeError> {
    static EXPECTED_SEGMENTS: &[(&str, bool)] = &[
        ("std", false),
        ("pin", false),
        ("Pin", true), // true = act on the arguments of this segment
    ];

    for (seg, (expected_name, act)) in segments.iter_mut().zip(EXPECTED_SEGMENTS.iter()) {
        if seg.ident != expected_name {
            return Err(AddLifetimeError::WasNotPin);
        }
        if *act {
            match &mut seg.arguments {
                syn::PathArguments::AngleBracketed(aba) => match aba.args.iter_mut().next() {
                    Some(GenericArgument::Type(Type::Reference(tyr))) => {
                        add_lifetime_to_reference(tyr);
                    }
                    _ => panic!("Expected generic args with a reference"),
                },
                _ => panic!("Expected angle bracketed args"),
            }
        }
    }
    Ok(())
}

fn add_lifetime_to_reference(tyr: &mut syn::TypeReference) {
    tyr.lifetime = Some(parse_quote! { 'a })
}
<commit_msg>Fix faulty panic.<commit_after>// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use crate::{
    conversion::analysis::fun::{ArgumentAnalysis, ReceiverMutability},
    types::QualifiedName,
};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use std::{borrow::Cow, collections::HashSet};
use syn::{
    parse_quote, punctuated::Punctuated, token::Comma, FnArg, GenericArgument, PatType, Path,
    PathSegment, ReturnType, Type, TypePath, TypeReference,
};

/// Function which can add explicit lifetime parameters to function signatures
/// where necessary, based on analysis of parameters and return types.
/// This is necessary in three cases:
/// 1) where the parameter is a Pin<&mut T>
///    and the return type is some kind of reference - because lifetime elision
///    is not smart enough to see inside a Pin.
/// 2) as a workaround for https://github.com/dtolnay/cxx/issues/1024, where the
///    input parameter is a non-POD type but the output reference is a POD or
///    built-in type
/// 3) Any parameter is any form of reference, and we're returning an `impl New`
pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
    param_details: &[ArgumentAnalysis],
    mut params: Punctuated<FnArg, Comma>,
    ret_type: &'r ReturnType,
    non_pod_types: &HashSet<QualifiedName>,
    assert_all_parameters_are_references: bool,
) -> (
    Option<TokenStream>,
    Punctuated<FnArg, Comma>,
    Cow<'r, ReturnType>,
) {
    let has_mutable_receiver = param_details
        .iter()
        .any(|pd| matches!(pd.self_type, Some((_, ReceiverMutability::Mutable))));

    let any_param_is_reference = param_details.iter().any(|pd| pd.was_reference);
    let return_type_is_impl = return_type_is_impl(ret_type);
    let non_pod_ref_param = reference_parameter_is_non_pod_reference(&params, non_pod_types);
    let ret_type_pod = return_type_is_pod_or_known_type_reference(ret_type, non_pod_types);
    let returning_impl_with_a_reference_param = return_type_is_impl && any_param_is_reference;
    let hits_1024_bug = non_pod_ref_param && ret_type_pod;
    if !(has_mutable_receiver || hits_1024_bug || returning_impl_with_a_reference_param) {
        return (None, params, Cow::Borrowed(ret_type));
    }
    let new_return_type = match ret_type {
        ReturnType::Type(rarrow, boxed_type) => match boxed_type.as_ref() {
            Type::Reference(rtr) => {
                let mut new_rtr = rtr.clone();
                new_rtr.lifetime = Some(parse_quote! { 'a });
                Some(ReturnType::Type(
                    *rarrow,
                    Box::new(Type::Reference(new_rtr)),
                ))
            }
            Type::Path(typ) => {
                let mut new_path = typ.clone();
                add_lifetime_to_pinned_reference(&mut new_path.path.segments)
                    .ok()
                    .map(|_| ReturnType::Type(*rarrow, Box::new(Type::Path(new_path))))
            }
            Type::ImplTrait(tyit) => {
                let old_tyit = tyit.to_token_stream();
                Some(parse_quote! {
                    #rarrow #old_tyit + 'a
                })
            }
            _ => None,
        },
        _ => None,
    };

    match new_return_type {
        None => (None, params, Cow::Borrowed(ret_type)),
        Some(new_return_type) => {
            for mut param in params.iter_mut() {
                match &mut param {
                    FnArg::Typed(PatType { ty, .. }) => match ty.as_mut() {
                        Type::Path(TypePath {
                            path: Path { segments, .. },
                            ..
                        }) => add_lifetime_to_pinned_reference(segments).unwrap_or_else(|e| {
                            if assert_all_parameters_are_references {
                                panic!("Expected a pinned reference: {:?}", e)
                            }
                        }),
                        Type::Reference(tyr) => add_lifetime_to_reference(tyr),
                        _ if assert_all_parameters_are_references => {
                            panic!("Expected Pin<&mut T> or &T")
                        }
                        _ => {}
                    },
                    _ if assert_all_parameters_are_references => panic!("Unexpected fnarg"),
                    _ => {}
                }
            }

            (Some(quote! { <'a> }), params, Cow::Owned(new_return_type))
        }
    }
}

fn reference_parameter_is_non_pod_reference(
    params: &Punctuated<FnArg, Comma>,
    non_pod_types: &HashSet<QualifiedName>,
) -> bool {
    params.iter().any(|param| match param {
        FnArg::Typed(PatType { ty, .. }) => match ty.as_ref() {
            Type::Reference(TypeReference { elem, .. }) => match elem.as_ref() {
                Type::Path(typ) => {
                    let qn = QualifiedName::from_type_path(typ);
                    non_pod_types.contains(&qn)
                }
                _ => false,
            },
            _ => false,
        },
        _ => false,
    })
}

fn return_type_is_pod_or_known_type_reference(
    ret_type: &ReturnType,
    non_pod_types: &HashSet<QualifiedName>,
) -> bool {
    match ret_type {
        ReturnType::Type(_, boxed_type) => match boxed_type.as_ref() {
            Type::Reference(rtr) => match rtr.elem.as_ref() {
                Type::Path(typ) => {
                    let qn = QualifiedName::from_type_path(typ);
                    !non_pod_types.contains(&qn)
                }
                _ => false,
            },
            _ => false,
        },
        _ => false,
    }
}

fn return_type_is_impl(ret_type: &ReturnType) -> bool {
    matches!(ret_type, ReturnType::Type(_, boxed_type) if matches!(boxed_type.as_ref(), Type::ImplTrait(..)))
}

#[derive(Debug)]
enum AddLifetimeError {
    WasNotPin,
}

fn add_lifetime_to_pinned_reference(
    segments: &mut Punctuated<PathSegment, syn::token::Colon2>,
) -> Result<(), AddLifetimeError> {
    static EXPECTED_SEGMENTS: &[(&str, bool)] = &[
        ("std", false),
        ("pin", false),
        ("Pin", true), // true = act on the arguments of this segment
    ];

    for (seg, (expected_name, act)) in segments.iter_mut().zip(EXPECTED_SEGMENTS.iter()) {
        if seg.ident != expected_name {
            return Err(AddLifetimeError::WasNotPin);
        }
        if *act {
            match &mut seg.arguments {
                syn::PathArguments::AngleBracketed(aba) => match aba.args.iter_mut().next() {
                    Some(GenericArgument::Type(Type::Reference(tyr))) => {
                        add_lifetime_to_reference(tyr);
                    }
                    _ => panic!("Expected generic args with a reference"),
                },
                _ => panic!("Expected angle bracketed args"),
            }
        }
    }
    Ok(())
}

fn add_lifetime_to_reference(tyr: &mut syn::TypeReference) {
    tyr.lifetime = Some(parse_quote! { 'a })
}
<|endoftext|>


<commit_before>//! The PostgreSQL backend

use byteorder::NetworkEndian;

use super::query_builder::PgQueryBuilder;
use super::{PgMetadataLookup, PgValue};
use crate::backend::*;
use crate::deserialize::Queryable;
use crate::pg::metadata_lookup::PgMetadataCacheKey;
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::sql_types::TypeMetadata;

/// The PostgreSQL backend
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Pg;

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Queryable)]
pub(in crate::pg) struct InnerPgTypeMetadata {
    pub oid: u32,
    pub array_oid: u32,
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(in crate::pg) struct FailedToLookupTypeError(Box<PgMetadataCacheKey<'static>>);

impl FailedToLookupTypeError {
    pub(crate) fn new(cache_key: PgMetadataCacheKey<'static>) -> Self {
        Self(Box::new(cache_key))
    }
}

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

impl std::fmt::Display for FailedToLookupTypeError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if let Some(schema) = self.0.schema.as_ref() {
            write!(
                f,
                "Failed to find a type oid for `{}`.`{}`",
                schema, self.0.type_name
            )
        } else {
            write!(f, "Failed to find a type oid for {}`", self.0.type_name)
        }
    }
}

/// The [OIDs] for a SQL type
///
/// [OIDs]: https://www.postgresql.org/docs/current/static/datatype-oid.html
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[must_use]
pub struct PgTypeMetadata(pub(in crate::pg) Result<InnerPgTypeMetadata, FailedToLookupTypeError>);

impl PgTypeMetadata {
    /// Create a new instance of this type based on known constant [OIDs].
    ///
    /// Please refer to [PgMetadataLookup] for a way to query [OIDs]
    /// of custom types at run time
    ///
    /// [OIDs]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    /// [PgMetadataLookup]: struct.PgMetadataLookup.html
    pub fn new(type_oid: u32, array_oid: u32) -> Self {
        Self(Ok(InnerPgTypeMetadata {
            oid: type_oid,
            array_oid,
        }))
    }

    /// The [OID] of `T`
    ///
    /// [OID]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    pub fn oid(&self) -> Result<u32, impl std::error::Error + Send + Sync> {
        self.0.as_ref().map(|i| i.oid).map_err(Clone::clone)
    }

    /// The [OID] of `T[]`
    ///
    /// [OID]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    pub fn array_oid(self) -> Result<u32, impl std::error::Error + Send + Sync> {
        self.0.as_ref().map(|i| i.array_oid).map_err(Clone::clone)
    }
}

impl Backend for Pg {
    type QueryBuilder = PgQueryBuilder;
    type BindCollector = RawBytesBindCollector<Pg>;
    type ByteOrder = NetworkEndian;
}

impl<'a> HasRawValue<'a> for Pg {
    type RawValue = PgValue<'a>;
}

impl TypeMetadata for Pg {
    type TypeMetadata = PgTypeMetadata;
    type MetadataLookup = PgMetadataLookup;
}

impl SupportsReturningClause for Pg {}
impl SupportsOnConflictClause for Pg {}
impl SupportsOnConflictTargetDecorations for Pg {}
impl SupportsDefaultKeyword for Pg {}
impl UsesAnsiSavepointSyntax for Pg {}
<commit_msg>Update diesel/src/pg/backend.rs<commit_after>//! The PostgreSQL backend

use byteorder::NetworkEndian;

use super::query_builder::PgQueryBuilder;
use super::{PgMetadataLookup, PgValue};
use crate::backend::*;
use crate::deserialize::Queryable;
use crate::pg::metadata_lookup::PgMetadataCacheKey;
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::sql_types::TypeMetadata;

/// The PostgreSQL backend
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Pg;

#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Queryable)]
pub(in crate::pg) struct InnerPgTypeMetadata {
    pub oid: u32,
    pub array_oid: u32,
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(in crate::pg) struct FailedToLookupTypeError(Box<PgMetadataCacheKey<'static>>);

impl FailedToLookupTypeError {
    pub(crate) fn new(cache_key: PgMetadataCacheKey<'static>) -> Self {
        Self(Box::new(cache_key))
    }
}

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

impl std::fmt::Display for FailedToLookupTypeError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if let Some(schema) = self.0.schema.as_ref() {
            write!(
                f,
                "Failed to find a type oid for `{}`.`{}`",
                schema, self.0.type_name
            )
        } else {
            write!(f, "Failed to find a type oid for `{}`", self.0.type_name)
        }
    }
}

/// The [OIDs] for a SQL type
///
/// [OIDs]: https://www.postgresql.org/docs/current/static/datatype-oid.html
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[must_use]
pub struct PgTypeMetadata(pub(in crate::pg) Result<InnerPgTypeMetadata, FailedToLookupTypeError>);

impl PgTypeMetadata {
    /// Create a new instance of this type based on known constant [OIDs].
    ///
    /// Please refer to [PgMetadataLookup] for a way to query [OIDs]
    /// of custom types at run time
    ///
    /// [OIDs]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    /// [PgMetadataLookup]: struct.PgMetadataLookup.html
    pub fn new(type_oid: u32, array_oid: u32) -> Self {
        Self(Ok(InnerPgTypeMetadata {
            oid: type_oid,
            array_oid,
        }))
    }

    /// The [OID] of `T`
    ///
    /// [OID]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    pub fn oid(&self) -> Result<u32, impl std::error::Error + Send + Sync> {
        self.0.as_ref().map(|i| i.oid).map_err(Clone::clone)
    }

    /// The [OID] of `T[]`
    ///
    /// [OID]: https://www.postgresql.org/docs/current/static/datatype-oid.html
    pub fn array_oid(self) -> Result<u32, impl std::error::Error + Send + Sync> {
        self.0.as_ref().map(|i| i.array_oid).map_err(Clone::clone)
    }
}

impl Backend for Pg {
    type QueryBuilder = PgQueryBuilder;
    type BindCollector = RawBytesBindCollector<Pg>;
    type ByteOrder = NetworkEndian;
}

impl<'a> HasRawValue<'a> for Pg {
    type RawValue = PgValue<'a>;
}

impl TypeMetadata for Pg {
    type TypeMetadata = PgTypeMetadata;
    type MetadataLookup = PgMetadataLookup;
}

impl SupportsReturningClause for Pg {}
impl SupportsOnConflictClause for Pg {}
impl SupportsOnConflictTargetDecorations for Pg {}
impl SupportsDefaultKeyword for Pg {}
impl UsesAnsiSavepointSyntax for Pg {}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern crate clap;
extern crate clippy_dev;
extern crate regex;

use clap::{App, Arg, SubCommand};
use clippy_dev::*;

#[derive(PartialEq)]
enum UpdateMode {
    Check,
    Change
}

fn main() {
    let matches = App::new("Clippy developer tooling")
        .subcommand(
            SubCommand::with_name("update_lints")
                .about("Makes sure that:\n \
                       * the lint count in README.md is correct\n \
                       * the changelog contains markdown link references at the bottom\n \
                       * all lint groups include the correct lints\n \
                       * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
                       * all lints are registered in the lint store")
                .arg(
                    Arg::with_name("print-only")
                        .long("print-only")
                        .help("Print a table of lints to STDOUT. This does not include deprecated and internal lints. (Does not modify any files)")
                )
                .arg(
                    Arg::with_name("check")
                        .long("check")
                        .help("Checks that util/dev update_lints has been run. Used on CI."),
                )
            )
            .get_matches();

    if let Some(matches) = matches.subcommand_matches("update_lints") {
        if matches.is_present("print-only") {
            print_lints();
        } else if matches.is_present("check") {
            update_lints(UpdateMode::Check);
        } else {
            update_lints(UpdateMode::Change);
        }
    }
}

fn print_lints() {
    let lint_list = gather_all();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
    let lint_count = usable_lints.len();
    let grouped_by_lint_group = Lint::by_lint_group(&usable_lints);

    for (lint_group, mut lints) in grouped_by_lint_group {
        if lint_group == "Deprecated" { continue; }
        println!("\n## {}", lint_group);

        lints.sort_by_key(|l| l.name.clone());

        for lint in lints {
            println!("* [{}]({}#{}) ({})", lint.name, clippy_dev::DOCS_LINK.clone(), lint.name, lint.desc);
        }
    }

    println!("there are {} lints", lint_count);
}

fn update_lints(update_mode: UpdateMode) {
    let lint_list: Vec<Lint> = gather_all().collect();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
    let lint_count = usable_lints.len();

    let mut file_change = replace_region_in_file(
        "../README.md",
        r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang-nursery.github.io/rust-clippy/master/index.html\)"#,
        "",
        true,
        update_mode == UpdateMode::Change,
        || {
            vec![
                format!("[There are {} lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)", lint_count)
            ]
        }
    ).changed;

    file_change |= replace_region_in_file(
        "../CHANGELOG.md",
        "<!-- begin autogenerated links to lint list -->",
        "<!-- end autogenerated links to lint list -->",
        false,
        update_mode == UpdateMode::Change,
        || { gen_changelog_lint_list(lint_list.clone()) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin deprecated lints",
        "end deprecated lints",
        false,
        update_mode == UpdateMode::Change,
        || { gen_deprecated(&lint_list) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin lints modules",
        "end lints modules",
        false,
        update_mode == UpdateMode::Change,
        || { gen_modules_list(lint_list.clone()) }
    ).changed;

    // Generate lists of lints in the clippy::all lint group
    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        r#"reg.register_lint_group\("clippy::all""#,
        r#"\]\);"#,
        false,
        update_mode == UpdateMode::Change,
        || {
            // clippy::all should only include the following lint groups:
            let all_group_lints = usable_lints.clone().into_iter().filter(|l| {
                l.group == "correctness" ||
                  l.group == "style" ||
                  l.group == "complexity" ||
                  l.group == "perf"
            }).collect();

            gen_lint_group_list(all_group_lints)
        }
    ).changed;

    // Generate the list of lints for all other lint groups
    for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
        file_change |= replace_region_in_file(
            "../clippy_lints/src/lib.rs",
            &format!("reg.register_lint_group\\(\"clippy::{}\"", lint_group),
            r#"\]\);"#,
            false,
            update_mode == UpdateMode::Change,
            || { gen_lint_group_list(lints.clone()) }
        ).changed;
    }

    if update_mode == UpdateMode::Check && file_change {
      println!("Not all lints defined properly. Please run util/dev update_lints to make sure all lints are defined properly.");
      std::process::exit(1);
    }
}
<commit_msg>Update println! formatting<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern crate clap;
extern crate clippy_dev;
extern crate regex;

use clap::{App, Arg, SubCommand};
use clippy_dev::*;

#[derive(PartialEq)]
enum UpdateMode {
    Check,
    Change
}

fn main() {
    let matches = App::new("Clippy developer tooling")
        .subcommand(
            SubCommand::with_name("update_lints")
                .about("Makes sure that:\n \
                       * the lint count in README.md is correct\n \
                       * the changelog contains markdown link references at the bottom\n \
                       * all lint groups include the correct lints\n \
                       * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
                       * all lints are registered in the lint store")
                .arg(
                    Arg::with_name("print-only")
                        .long("print-only")
                        .help("Print a table of lints to STDOUT. This does not include deprecated and internal lints. (Does not modify any files)")
                )
                .arg(
                    Arg::with_name("check")
                        .long("check")
                        .help("Checks that util/dev update_lints has been run. Used on CI."),
                )
            )
            .get_matches();

    if let Some(matches) = matches.subcommand_matches("update_lints") {
        if matches.is_present("print-only") {
            print_lints();
        } else if matches.is_present("check") {
            update_lints(UpdateMode::Check);
        } else {
            update_lints(UpdateMode::Change);
        }
    }
}

fn print_lints() {
    let lint_list = gather_all();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list).collect();
    let lint_count = usable_lints.len();
    let grouped_by_lint_group = Lint::by_lint_group(&usable_lints);

    for (lint_group, mut lints) in grouped_by_lint_group {
        if lint_group == "Deprecated" { continue; }
        println!("\n## {}", lint_group);

        lints.sort_by_key(|l| l.name.clone());

        for lint in lints {
            println!("* [{}]({}#{}) ({})", lint.name, clippy_dev::DOCS_LINK.clone(), lint.name, lint.desc);
        }
    }

    println!("there are {} lints", lint_count);
}

fn update_lints(update_mode: UpdateMode) {
    let lint_list: Vec<Lint> = gather_all().collect();
    let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
    let lint_count = usable_lints.len();

    let mut file_change = replace_region_in_file(
        "../README.md",
        r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang-nursery.github.io/rust-clippy/master/index.html\)"#,
        "",
        true,
        update_mode == UpdateMode::Change,
        || {
            vec![
                format!("[There are {} lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)", lint_count)
            ]
        }
    ).changed;

    file_change |= replace_region_in_file(
        "../CHANGELOG.md",
        "<!-- begin autogenerated links to lint list -->",
        "<!-- end autogenerated links to lint list -->",
        false,
        update_mode == UpdateMode::Change,
        || { gen_changelog_lint_list(lint_list.clone()) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin deprecated lints",
        "end deprecated lints",
        false,
        update_mode == UpdateMode::Change,
        || { gen_deprecated(&lint_list) }
    ).changed;

    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        "begin lints modules",
        "end lints modules",
        false,
        update_mode == UpdateMode::Change,
        || { gen_modules_list(lint_list.clone()) }
    ).changed;

    // Generate lists of lints in the clippy::all lint group
    file_change |= replace_region_in_file(
        "../clippy_lints/src/lib.rs",
        r#"reg.register_lint_group\("clippy::all""#,
        r#"\]\);"#,
        false,
        update_mode == UpdateMode::Change,
        || {
            // clippy::all should only include the following lint groups:
            let all_group_lints = usable_lints.clone().into_iter().filter(|l| {
                l.group == "correctness" ||
                  l.group == "style" ||
                  l.group == "complexity" ||
                  l.group == "perf"
            }).collect();

            gen_lint_group_list(all_group_lints)
        }
    ).changed;

    // Generate the list of lints for all other lint groups
    for (lint_group, lints) in Lint::by_lint_group(&usable_lints) {
        file_change |= replace_region_in_file(
            "../clippy_lints/src/lib.rs",
            &format!("reg.register_lint_group\\(\"clippy::{}\"", lint_group),
            r#"\]\);"#,
            false,
            update_mode == UpdateMode::Change,
            || { gen_lint_group_list(lints.clone()) }
        ).changed;
    }

    if update_mode == UpdateMode::Check && file_change {
      println!("Not all lints defined properly. Please run `util/dev update_lints` to make sure all lints are defined properly.");
      std::process::exit(1);
    }
}
<|endoftext|>


<commit_before>use id3::Tag;
use chill;
use uuid::Uuid;
use super::super::Error;

#[derive(Serialize, Deserialize, Debug)]
pub struct Track {
    pub id: String,
    pub title: String,
    pub number: u32,
    pub artist: String,
    pub album: String,
}

impl Track {
    pub fn from_id(id: &str, db: &chill::Client) -> Result<Track, Error> {
        let document = try!(db.read_document(("/tracks", id)).run());
        Ok(try!(document.get_content()))
    }

    pub fn from_tag(tag: Tag) -> Track {
        Track {
            id: Uuid::new_v4().to_simple_string(),
            artist: tag.artist().unwrap_or("Unkown Artist").to_string(),
            album: tag.album().unwrap_or("Unknown Album").to_string(),
            title: tag.title().unwrap_or("Unknown Title").to_string(),
            number: tag.track().unwrap_or(0),
        }
    }

    pub fn create(mut self, db: &chill::Client) -> Result<(chill::DocumentId, chill::Revision), Error> {
        db.create_document("/tracks", &self).run().map_err(Error::from)
    }

}
<commit_msg>server: remove duplicate id field<commit_after>use id3::Tag;
use chill;
use uuid::Uuid;
use super::super::Error;

#[derive(Serialize, Deserialize, Debug)]
pub struct Track {
    pub title: String,
    pub number: u32,
    pub artist: String,
    pub album: String,
}

impl Track {
    pub fn from_id(id: &str, db: &chill::Client) -> Result<Track, Error> {
        let document = try!(db.read_document(("/tracks", id)).run());
        Ok(try!(document.get_content()))
    }

    pub fn from_tag(tag: Tag) -> Track {
        Track {
            artist: tag.artist().unwrap_or("Unkown Artist").to_string(),
            album: tag.album().unwrap_or("Unknown Album").to_string(),
            title: tag.title().unwrap_or("Unknown Title").to_string(),
            number: tag.track().unwrap_or(0),
        }
    }

    pub fn create(mut self, db: &chill::Client) -> Result<(chill::DocumentId, chill::Revision), Error> {
        db.create_document("/tracks", &self).run().map_err(Error::from)
    }

}
<|endoftext|>


<commit_before>use crate::utils;
use crate::utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, subst::GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
use rustc_span::symbol::Ident;

declare_clippy_lint! {
    /// **What it does:**
    /// Detects uses of `Vec::sort_by` passing in a closure
    /// which compares the two arguments, either directly or indirectly.
    ///
    /// **Why is this bad?**
    /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
    /// possible) than to use `Vec::sort_by` and a more complicated
    /// closure.
    ///
    /// **Known problems:**
    /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
    /// imported by a use statement, then it will need to be added manually.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// # struct A;
    /// # impl A { fn foo(&self) {} }
    /// # let mut vec: Vec<A> = Vec::new();
    /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
    /// ```
    /// Use instead:
    /// ```rust
    /// # struct A;
    /// # impl A { fn foo(&self) {} }
    /// # let mut vec: Vec<A> = Vec::new();
    /// vec.sort_by_key(|a| a.foo());
    /// ```
    pub UNNECESSARY_SORT_BY,
    complexity,
    "Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
}

declare_lint_pass!(UnnecessarySortBy => [UNNECESSARY_SORT_BY]);

enum LintTrigger {
    Sort(SortDetection),
    SortByKey(SortByKeyDetection),
}

struct SortDetection {
    vec_name: String,
    unstable: bool,
}

struct SortByKeyDetection {
    vec_name: String,
    closure_arg: String,
    closure_body: String,
    reverse: bool,
    unstable: bool,
}

/// Detect if the two expressions are mirrored (identical, except one
/// contains a and the other replaces it with b)
fn mirrored_exprs(
    cx: &LateContext<'_>,
    a_expr: &Expr<'_>,
    a_ident: &Ident,
    b_expr: &Expr<'_>,
    b_ident: &Ident,
) -> bool {
    match (&a_expr.kind, &b_expr.kind) {
        // Two boxes with mirrored contents
        (ExprKind::Box(left_expr), ExprKind::Box(right_expr)) => {
            mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
        },
        // Two arrays with mirrored contents
        (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => left_exprs
            .iter()
            .zip(right_exprs.iter())
            .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)),
        // The two exprs are function calls.
        // Check to see that the function itself and its arguments are mirrored
        (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => {
            mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
                && left_args
                    .iter()
                    .zip(right_args.iter())
                    .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident))
        },
        // The two exprs are method calls.
        // Check to see that the function is the same and the arguments are mirrored
        // This is enough because the receiver of the method is listed in the arguments
        (
            ExprKind::MethodCall(left_segment, _, left_args, _),
            ExprKind::MethodCall(right_segment, _, right_args, _),
        ) => {
            left_segment.ident == right_segment.ident
                && left_args
                    .iter()
                    .zip(right_args.iter())
                    .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident))
        },
        // Two tuples with mirrored contents
        (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => left_exprs
            .iter()
            .zip(right_exprs.iter())
            .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)),
        // Two binary ops, which are the same operation and which have mirrored arguments
        (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => {
            left_op.node == right_op.node
                && mirrored_exprs(cx, left_left, a_ident, right_left, b_ident)
                && mirrored_exprs(cx, left_right, a_ident, right_right, b_ident)
        },
        // Two unary ops, which are the same operation and which have the same argument
        (ExprKind::Unary(left_op, left_expr), ExprKind::Unary(right_op, right_expr)) => {
            left_op == right_op && mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
        },
        // The two exprs are literals of some kind
        (ExprKind::Lit(left_lit), ExprKind::Lit(right_lit)) => left_lit.node == right_lit.node,
        (ExprKind::Cast(left, _), ExprKind::Cast(right, _)) => mirrored_exprs(cx, left, a_ident, right, b_ident),
        (ExprKind::DropTemps(left_block), ExprKind::DropTemps(right_block)) => {
            mirrored_exprs(cx, left_block, a_ident, right_block, b_ident)
        },
        (ExprKind::Field(left_expr, left_ident), ExprKind::Field(right_expr, right_ident)) => {
            left_ident.name == right_ident.name && mirrored_exprs(cx, left_expr, a_ident, right_expr, right_ident)
        },
        // Two paths: either one is a and the other is b, or they're identical to each other
        (
            ExprKind::Path(QPath::Resolved(
                _,
                Path {
                    segments: left_segments,
                    ..
                },
            )),
            ExprKind::Path(QPath::Resolved(
                _,
                Path {
                    segments: right_segments,
                    ..
                },
            )),
        ) => {
            (left_segments
                .iter()
                .zip(right_segments.iter())
                .all(|(left, right)| left.ident == right.ident)
                && left_segments
                    .iter()
                    .all(|seg| &seg.ident != a_ident && &seg.ident != b_ident))
                || (left_segments.len() == 1
                    && &left_segments[0].ident == a_ident
                    && right_segments.len() == 1
                    && &right_segments[0].ident == b_ident)
        },
        // Matching expressions, but one or both is borrowed
        (
            ExprKind::AddrOf(left_kind, Mutability::Not, left_expr),
            ExprKind::AddrOf(right_kind, Mutability::Not, right_expr),
        ) => left_kind == right_kind && mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident),
        (_, ExprKind::AddrOf(_, Mutability::Not, right_expr)) => {
            mirrored_exprs(cx, a_expr, a_ident, right_expr, b_ident)
        },
        (ExprKind::AddrOf(_, Mutability::Not, left_expr), _) => mirrored_exprs(cx, left_expr, a_ident, b_expr, b_ident),
        _ => false,
    }
}

fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
    if_chain! {
        if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind;
        if let name = name_ident.ident.name.to_ident_string();
        if name == "sort_by" || name == "sort_unstable_by";
        if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args;
        if utils::is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::vec_type);
        if let closure_body = cx.tcx.hir().body(*closure_body_id);
        if let &[
            Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..},
            Param { pat: Pat { kind: PatKind::Binding(_, _, right_ident, _), .. }, .. }
        ] = &closure_body.params;
        if let ExprKind::MethodCall(method_path, _, [ref left_expr, ref right_expr], _) = &closure_body.value.kind;
        if method_path.ident.name == sym::cmp;
        then {
            let (closure_body, closure_arg, reverse) = if mirrored_exprs(
                &cx,
                &left_expr,
                &left_ident,
                &right_expr,
                &right_ident
            ) {
                (Sugg::hir(cx, &left_expr, "..").to_string(), left_ident.name.to_string(), false)
            } else if mirrored_exprs(&cx, &left_expr, &right_ident, &right_expr, &left_ident) {
                (Sugg::hir(cx, &left_expr, "..").to_string(), right_ident.name.to_string(), true)
            } else {
                return None;
            };
            let vec_name = Sugg::hir(cx, &args[0], "..").to_string();
            let unstable = name == "sort_unstable_by";

            if let ExprKind::Path(QPath::Resolved(_, Path {
                segments: [PathSegment { ident: left_name, .. }], ..
            })) = &left_expr.kind {
                if left_name == left_ident {
                    return Some(LintTrigger::Sort(SortDetection { vec_name, unstable }));
                }
            }

            if !expr_borrows(cx, left_expr) {
                return Some(LintTrigger::SortByKey(SortByKeyDetection {
                    vec_name,
                    unstable,
                    closure_arg,
                    closure_body,
                    reverse
                }));
            }
        }
    }

    None
}

fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
    let ty = cx.typeck_results().expr_ty(expr);
    matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_)))
}

impl LateLintPass<'_> for UnnecessarySortBy {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        match detect_lint(cx, expr) {
            Some(LintTrigger::SortByKey(trigger)) => utils::span_lint_and_sugg(
                cx,
                UNNECESSARY_SORT_BY,
                expr.span,
                "use Vec::sort_by_key here instead",
                "try",
                format!(
                    "{}.sort{}_by_key(|{}| {})",
                    trigger.vec_name,
                    if trigger.unstable { "_unstable" } else { "" },
                    trigger.closure_arg,
                    if trigger.reverse {
                        format!("Reverse({})", trigger.closure_body)
                    } else {
                        trigger.closure_body.to_string()
                    },
                ),
                if trigger.reverse {
                    Applicability::MaybeIncorrect
                } else {
                    Applicability::MachineApplicable
                },
            ),
            Some(LintTrigger::Sort(trigger)) => utils::span_lint_and_sugg(
                cx,
                UNNECESSARY_SORT_BY,
                expr.span,
                "use Vec::sort here instead",
                "try",
                format!(
                    "{}.sort{}()",
                    trigger.vec_name,
                    if trigger.unstable { "_unstable" } else { "" },
                ),
                Applicability::MachineApplicable,
            ),
            None => {},
        }
    }
}
<commit_msg>Fix unnecessary_sort_by.rs that fails the dogfood test<commit_after>use crate::utils;
use crate::utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, subst::GenericArgKind};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
use rustc_span::symbol::Ident;

declare_clippy_lint! {
    /// **What it does:**
    /// Detects uses of `Vec::sort_by` passing in a closure
    /// which compares the two arguments, either directly or indirectly.
    ///
    /// **Why is this bad?**
    /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if
    /// possible) than to use `Vec::sort_by` and a more complicated
    /// closure.
    ///
    /// **Known problems:**
    /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already
    /// imported by a use statement, then it will need to be added manually.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// # struct A;
    /// # impl A { fn foo(&self) {} }
    /// # let mut vec: Vec<A> = Vec::new();
    /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));
    /// ```
    /// Use instead:
    /// ```rust
    /// # struct A;
    /// # impl A { fn foo(&self) {} }
    /// # let mut vec: Vec<A> = Vec::new();
    /// vec.sort_by_key(|a| a.foo());
    /// ```
    pub UNNECESSARY_SORT_BY,
    complexity,
    "Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer"
}

declare_lint_pass!(UnnecessarySortBy => [UNNECESSARY_SORT_BY]);

enum LintTrigger {
    Sort(SortDetection),
    SortByKey(SortByKeyDetection),
}

struct SortDetection {
    vec_name: String,
    unstable: bool,
}

struct SortByKeyDetection {
    vec_name: String,
    closure_arg: String,
    closure_body: String,
    reverse: bool,
    unstable: bool,
}

/// Detect if the two expressions are mirrored (identical, except one
/// contains a and the other replaces it with b)
fn mirrored_exprs(
    cx: &LateContext<'_>,
    a_expr: &Expr<'_>,
    a_ident: &Ident,
    b_expr: &Expr<'_>,
    b_ident: &Ident,
) -> bool {
    match (&a_expr.kind, &b_expr.kind) {
        // Two boxes with mirrored contents
        (ExprKind::Box(left_expr), ExprKind::Box(right_expr)) => {
            mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
        },
        // Two arrays with mirrored contents
        (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => left_exprs
            .iter()
            .zip(right_exprs.iter())
            .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)),
        // The two exprs are function calls.
        // Check to see that the function itself and its arguments are mirrored
        (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => {
            mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
                && left_args
                    .iter()
                    .zip(right_args.iter())
                    .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident))
        },
        // The two exprs are method calls.
        // Check to see that the function is the same and the arguments are mirrored
        // This is enough because the receiver of the method is listed in the arguments
        (
            ExprKind::MethodCall(left_segment, _, left_args, _),
            ExprKind::MethodCall(right_segment, _, right_args, _),
        ) => {
            left_segment.ident == right_segment.ident
                && left_args
                    .iter()
                    .zip(right_args.iter())
                    .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident))
        },
        // Two tuples with mirrored contents
        (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => left_exprs
            .iter()
            .zip(right_exprs.iter())
            .all(|(left, right)| mirrored_exprs(cx, left, a_ident, right, b_ident)),
        // Two binary ops, which are the same operation and which have mirrored arguments
        (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => {
            left_op.node == right_op.node
                && mirrored_exprs(cx, left_left, a_ident, right_left, b_ident)
                && mirrored_exprs(cx, left_right, a_ident, right_right, b_ident)
        },
        // Two unary ops, which are the same operation and which have the same argument
        (ExprKind::Unary(left_op, left_expr), ExprKind::Unary(right_op, right_expr)) => {
            left_op == right_op && mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident)
        },
        // The two exprs are literals of some kind
        (ExprKind::Lit(left_lit), ExprKind::Lit(right_lit)) => left_lit.node == right_lit.node,
        (ExprKind::Cast(left, _), ExprKind::Cast(right, _)) => mirrored_exprs(cx, left, a_ident, right, b_ident),
        (ExprKind::DropTemps(left_block), ExprKind::DropTemps(right_block)) => {
            mirrored_exprs(cx, left_block, a_ident, right_block, b_ident)
        },
        (ExprKind::Field(left_expr, left_ident), ExprKind::Field(right_expr, right_ident)) => {
            left_ident.name == right_ident.name && mirrored_exprs(cx, left_expr, a_ident, right_expr, right_ident)
        },
        // Two paths: either one is a and the other is b, or they're identical to each other
        (
            ExprKind::Path(QPath::Resolved(
                _,
                Path {
                    segments: left_segments,
                    ..
                },
            )),
            ExprKind::Path(QPath::Resolved(
                _,
                Path {
                    segments: right_segments,
                    ..
                },
            )),
        ) => {
            (left_segments
                .iter()
                .zip(right_segments.iter())
                .all(|(left, right)| left.ident == right.ident)
                && left_segments
                    .iter()
                    .all(|seg| &seg.ident != a_ident && &seg.ident != b_ident))
                || (left_segments.len() == 1
                    && &left_segments[0].ident == a_ident
                    && right_segments.len() == 1
                    && &right_segments[0].ident == b_ident)
        },
        // Matching expressions, but one or both is borrowed
        (
            ExprKind::AddrOf(left_kind, Mutability::Not, left_expr),
            ExprKind::AddrOf(right_kind, Mutability::Not, right_expr),
        ) => left_kind == right_kind && mirrored_exprs(cx, left_expr, a_ident, right_expr, b_ident),
        (_, ExprKind::AddrOf(_, Mutability::Not, right_expr)) => {
            mirrored_exprs(cx, a_expr, a_ident, right_expr, b_ident)
        },
        (ExprKind::AddrOf(_, Mutability::Not, left_expr), _) => mirrored_exprs(cx, left_expr, a_ident, b_expr, b_ident),
        _ => false,
    }
}

fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<LintTrigger> {
    if_chain! {
        if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind;
        if let name = name_ident.ident.name.to_ident_string();
        if name == "sort_by" || name == "sort_unstable_by";
        if let [vec, Expr { kind: ExprKind::Closure(_, _, closure_body_id, _, _), .. }] = args;
        if utils::is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(vec), sym::vec_type);
        if let closure_body = cx.tcx.hir().body(*closure_body_id);
        if let &[
            Param { pat: Pat { kind: PatKind::Binding(_, _, left_ident, _), .. }, ..},
            Param { pat: Pat { kind: PatKind::Binding(_, _, right_ident, _), .. }, .. }
        ] = &closure_body.params;
        if let ExprKind::MethodCall(method_path, _, [ref left_expr, ref right_expr], _) = &closure_body.value.kind;
        if method_path.ident.name == sym::cmp;
        then {
            let (closure_body, closure_arg, reverse) = if mirrored_exprs(
                &cx,
                &left_expr,
                &left_ident,
                &right_expr,
                &right_ident
            ) {
                (Sugg::hir(cx, &left_expr, "..").to_string(), left_ident.name.to_string(), false)
            } else if mirrored_exprs(&cx, &left_expr, &right_ident, &right_expr, &left_ident) {
                (Sugg::hir(cx, &left_expr, "..").to_string(), right_ident.name.to_string(), true)
            } else {
                return None;
            };
            let vec_name = Sugg::hir(cx, &args[0], "..").to_string();
            let unstable = name == "sort_unstable_by";

            if let ExprKind::Path(QPath::Resolved(_, Path {
                segments: [PathSegment { ident: left_name, .. }], ..
            })) = &left_expr.kind {
                if left_name == left_ident {
                    return Some(LintTrigger::Sort(SortDetection { vec_name, unstable }));
                }
            }

            if !expr_borrows(cx, left_expr) {
                return Some(LintTrigger::SortByKey(SortByKeyDetection {
                    vec_name,
                    closure_arg,
                    closure_body,
                    reverse,
                    unstable,
                }));
            }
        }
    }

    None
}

fn expr_borrows(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
    let ty = cx.typeck_results().expr_ty(expr);
    matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(_)))
}

impl LateLintPass<'_> for UnnecessarySortBy {
    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
        match detect_lint(cx, expr) {
            Some(LintTrigger::SortByKey(trigger)) => utils::span_lint_and_sugg(
                cx,
                UNNECESSARY_SORT_BY,
                expr.span,
                "use Vec::sort_by_key here instead",
                "try",
                format!(
                    "{}.sort{}_by_key(|{}| {})",
                    trigger.vec_name,
                    if trigger.unstable { "_unstable" } else { "" },
                    trigger.closure_arg,
                    if trigger.reverse {
                        format!("Reverse({})", trigger.closure_body)
                    } else {
                        trigger.closure_body.to_string()
                    },
                ),
                if trigger.reverse {
                    Applicability::MaybeIncorrect
                } else {
                    Applicability::MachineApplicable
                },
            ),
            Some(LintTrigger::Sort(trigger)) => utils::span_lint_and_sugg(
                cx,
                UNNECESSARY_SORT_BY,
                expr.span,
                "use Vec::sort here instead",
                "try",
                format!(
                    "{}.sort{}()",
                    trigger.vec_name,
                    if trigger.unstable { "_unstable" } else { "" },
                ),
                Applicability::MachineApplicable,
            ),
            None => {},
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;

use num::Complex;
use common::{FFTnum, verify_length, verify_length_divisible};

use math_utils;
use array_utils;

use algorithm::FFTAlgorithm;

pub struct GoodThomasAlgorithm<T> {
    width: usize,
    // width_inverse: usize,
    width_size_fft: Rc<FFTAlgorithm<T>>,

    height: usize,
    // height_inverse: usize,
    height_size_fft: Rc<FFTAlgorithm<T>>,

    input_map: Vec<usize>,
    output_map: Vec<usize>,
}

impl<T: FFTnum> GoodThomasAlgorithm<T> {
    #[allow(dead_code)]
    pub fn new(n1_fft: Rc<FFTAlgorithm<T>>, n2_fft: Rc<FFTAlgorithm<T>>) -> Self {

        let n1 = n1_fft.len();
        let n2 = n2_fft.len();

        // compute the nultiplicative inverse of n1 mod n2 and vice versa
        let (gcd, mut n1_inverse, mut n2_inverse) =
            math_utils::extended_euclidean_algorithm(n1 as i64, n2 as i64);
        assert!(gcd == 1,
                "Invalid input n1 and n2 to Good-Thomas Algorithm: ({},{}): Inputs must be \
                 coprime",
                n1,
                n2);

        // n1_inverse or n2_inverse might be negative, make it positive
        if n1_inverse < 0 {
            n1_inverse += n2 as i64;
        }
        if n2_inverse < 0 {
            n2_inverse += n1 as i64;
        }

        GoodThomasAlgorithm {
            width: n1,
            // width_inverse: n1_inverse as usize,
            width_size_fft: n1_fft,

            height: n2,
            // height_inverse: n2_inverse as usize,
            height_size_fft: n2_fft,

            // NOTE: we are precomputing the input and output mappings because
            // benchmarking shows that it's 20-30% faster
            // If we wanted to optimize for memory use or setup time instead of multiple-FFT speed,
            // these can be computed at runtime
            input_map: (0..n1 * n2)
                .map(|i| (i % n1, i / n1))
                .map(|(x, y)| (x * n2 + y * n1) % (n1 * n2))
                .collect(),
            output_map: (0..n1 * n2)
                .map(|i| (i % n2, i / n2))
                .map(|(y, x)| {
                    (x * n2 * n2_inverse as usize + y * n1 * n1_inverse as usize) % (n1 * n2)
                })
                .collect(),
        }
    }

    fn copy_from_input(&self, input: &[Complex<T>], output: &mut [Complex<T>]) {
        for (output_element, input_index) in output.iter_mut().zip(self.input_map.iter()) {
            *output_element = unsafe { *input.get_unchecked(*input_index) };
        }
    }

    fn copy_to_output(&self, input: &[Complex<T>], output: &mut [Complex<T>]) {
        for (input_element, output_index) in input.iter().zip(self.output_map.iter()) {
            unsafe { *output.get_unchecked_mut(*output_index) = *input_element };
        }
    }

    fn perform_fft(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {

        // copy the input using our reordering algorithm
        self.copy_from_input(input, output);

        // run FFTs of size `width`
        self.width_size_fft.process_multi(output, input);

        // transpose
        array_utils::transpose(self.width, self.height, input, output);

        // run 'width' FFTs of size 'height' from the spectrum back into scratch
        self.height_size_fft.process_multi(output, input);

        // we're done, copy to the output
        self.copy_to_output(input, output);
    }
}

impl<T: FFTnum> FFTAlgorithm<T> for GoodThomasAlgorithm<T> {
    fn process(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length(input, output, self.len());

        self.perform_fft(input, output);
    }
    fn process_multi(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length_divisible(input, output, self.len());

        for (in_chunk, out_chunk) in input.chunks_mut(self.len()).zip(output.chunks_mut(self.len())) {
            self.perform_fft(in_chunk, out_chunk);
        }
    }
    fn len(&self) -> usize {
        self.input_map.len()
    }
}
<commit_msg>Removed unsafe blocks and added unit test for GoodThomasAlgorithm<commit_after>use std::rc::Rc;

use num::Complex;
use common::{FFTnum, verify_length, verify_length_divisible};

use math_utils;
use array_utils;

use algorithm::FFTAlgorithm;

pub struct GoodThomasAlgorithm<T> {
    width: usize,
    // width_inverse: usize,
    width_size_fft: Rc<FFTAlgorithm<T>>,

    height: usize,
    // height_inverse: usize,
    height_size_fft: Rc<FFTAlgorithm<T>>,

    input_map: Box<[usize]>,
    output_map: Box<[usize]>,
}

impl<T: FFTnum> GoodThomasAlgorithm<T> {
    #[allow(dead_code)]
    pub fn new(n1_fft: Rc<FFTAlgorithm<T>>, n2_fft: Rc<FFTAlgorithm<T>>) -> Self {

        let n1 = n1_fft.len();
        let n2 = n2_fft.len();

        // compute the nultiplicative inverse of n1 mod n2 and vice versa
        let (gcd, mut n1_inverse, mut n2_inverse) =
            math_utils::extended_euclidean_algorithm(n1 as i64, n2 as i64);
        assert!(gcd == 1,
                "Invalid input n1 and n2 to Good-Thomas Algorithm: ({},{}): Inputs must be \
                 coprime",
                n1,
                n2);

        // n1_inverse or n2_inverse might be negative, make it positive
        if n1_inverse < 0 {
            n1_inverse += n2 as i64;
        }
        if n2_inverse < 0 {
            n2_inverse += n1 as i64;
        }

        // NOTE: we are precomputing the input and output reordering indexes
        // benchmarking shows that it's 20-30% faster
        // If we wanted to optimize for memory use or setup time instead of multiple-FFT speed,
        // these can be computed at runtime
        let input_map: Vec<usize> =
            (0..n1 * n2)
                .map(|i| (i % n1, i / n1))
                .map(|(x, y)| (x * n2 + y * n1) % (n1 * n2))
                .collect();
        let output_map: Vec<usize> =
            (0..n1 * n2)
                .map(|i| (i % n2, i / n2))
                .map(|(y, x)| {
                    (x * n2 * n2_inverse as usize + y * n1 * n1_inverse as usize) % (n1 * n2)
                })
                .collect();

        GoodThomasAlgorithm {
            width: n1,
            width_size_fft: n1_fft,

            height: n2,
            height_size_fft: n2_fft,

            input_map: input_map.into_boxed_slice(),
            output_map: output_map.into_boxed_slice(),
        }
    }

    fn perform_fft(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {

        // copy the input using our reordering mapping
        for (output_element, &input_index) in output.iter_mut().zip(self.input_map.iter()) {
            *output_element = input[input_index];
        }

        // run FFTs of size `width`
        self.width_size_fft.process_multi(output, input);

        // transpose
        array_utils::transpose(self.width, self.height, input, output);

        // run FFTs of size 'height'
        self.height_size_fft.process_multi(output, input);

        // copy to the output, using our output redordeing mapping
        for (input_element, &output_index) in input.iter().zip(self.output_map.iter()) {
            output[output_index] = *input_element;
        }
    }
}

impl<T: FFTnum> FFTAlgorithm<T> for GoodThomasAlgorithm<T> {
    fn process(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length(input, output, self.len());

        self.perform_fft(input, output);
    }
    fn process_multi(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length_divisible(input, output, self.len());

        for (in_chunk, out_chunk) in input.chunks_mut(self.len()).zip(output.chunks_mut(self.len())) {
            self.perform_fft(in_chunk, out_chunk);
        }
    }
    fn len(&self) -> usize {
        self.input_map.len()
    }
}

#[cfg(test)]
mod unit_tests {
    use super::*;
    use std::rc::Rc;
    use test_utils::{random_signal, compare_vectors};
    use algorithm::DFT;
    use num::Zero;

    #[test]
    fn test_good_thomas() {

        //gcd(n, n+1) is guaranteed to be 1, so we can generate some test sizes by just passing in n, n + 1
        for width in 2..20 {
            test_good_thomas_with_lengths(width, width - 1);
            test_good_thomas_with_lengths(width, width + 1);
        }

        //verify that it works correctly when width and/or height are 1
        test_good_thomas_with_lengths(1, 10);
        test_good_thomas_with_lengths(10, 1);
        test_good_thomas_with_lengths(1, 1);
    }

    fn test_good_thomas_with_lengths(width: usize, height: usize) {
        let n = 4;
        let len = width * height;

        // set up algorithms
        let dft = DFT::new(len, false);

        let width_fft = Rc::new(DFT::new(width, false)) as Rc<FFTAlgorithm<f32>>;
        let height_fft = Rc::new(DFT::new(height, false)) as Rc<FFTAlgorithm<f32>>;

        let good_thomas_fft = GoodThomasAlgorithm::new(width_fft, height_fft);

        assert_eq!(good_thomas_fft.len(), len, "Good thomas algorithm reported incorrect length");

        // set up buffers
        let mut expected_input = random_signal(len * n);
        let mut actual_input = expected_input.clone();
        let mut multi_input = expected_input.clone();

        let mut expected_output = vec![Zero::zero(); len * n];
        let mut actual_output = expected_output.clone();
        let mut multi_output = expected_output.clone();

        // perform the test
        dft.process_multi(&mut expected_input, &mut expected_output);
        good_thomas_fft.process_multi(&mut multi_input, &mut multi_output);

        for (input_chunk, output_chunk) in actual_input.chunks_mut(len).zip(actual_output.chunks_mut(len)) {
            good_thomas_fft.process(input_chunk, output_chunk);
        }

        assert!(compare_vectors(&expected_output, &actual_output), "width = {}, height = {}", width, height);
        assert!(compare_vectors(&expected_output, &multi_output), "width = {}, height = {}", width, height);
    }
}
<|endoftext|>


<commit_before>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};
use std::io::buffered::BufferedReader;

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;
static mut visitor_count: int = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            //Get the first line of the request
            let fl_items: ~[&str] = request_str.split(' ').collect();
            let mut path = fl_items[1];

            path = path.slice_from(1);

            let ext;
            if path.len() > 4 {
	      ext = path.slice_from(path.len() - 4);
	    } else {
	      ext = "null"
	    }

            let p = Path::new(path);

            //Remove this
            //print(path);

            let mut response: ~str = ~"";

            if str::eq(&~"html", &ext.into_owned()) {
            if p.is_file() {
	      match File::open(&Path::new(path)) {
	      Some(file) => {
		let mut reader = BufferedReader::new(file);
		response = response + "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
		for line in reader.lines() {
		  response = response + line;
		}

	      }
	      None =>{
		response = foo();
	      }
	    }
            } else {
	      response = foo();
            }
            } else {
	      response = foo();
            }

            stream.write(response.as_bytes());
            println!("Connection terminates.");
        }
    }
}
fn foo() -> ~str {
	unsafe {visitor_count += 1;}
	"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty " + unsafe{visitor_count.to_str()} + "!

                 \r\n"
}
<commit_msg>Fix 403 message<commit_after>//
// zhttpto.rs
//
// Starting code for PS1
// Running on Rust 0.9
//
// Note that this code has serious security risks!  You should not run it
// on any system with access to sensitive files.
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu and David Evans
// Version 0.3

#[feature(globs)];
use std::io::*;
use std::io::net::ip::{SocketAddr};
use std::{str};
use std::io::buffered::BufferedReader;

static IP: &'static str = "127.0.0.1";
static PORT:        int = 4414;
static mut visitor_count: int = 0;

fn main() {
    let addr = from_str::<SocketAddr>(format!("{:s}:{:d}", IP, PORT)).unwrap();
    let mut acceptor = net::tcp::TcpListener::bind(addr).listen();

    println(format!("Listening on [{:s}] ...", addr.to_str()));

    for stream in acceptor.incoming() {
        // Spawn a task to handle the connection
        do spawn {
            let mut stream = stream;

            match stream {
                Some(ref mut s) => {
                             match s.peer_name() {
                                Some(pn) => {println(format!("Received connection from: [{:s}]", pn.to_str()));},
                                None => ()
                             }
                           },
                None => ()
            }

            let mut buf = [0, ..500];
            stream.read(buf);
            let request_str = str::from_utf8(buf);
            println(format!("Received request :\n{:s}", request_str));

            //Get the first line of the request
            let fl_items: ~[&str] = request_str.split(' ').collect();
            let mut path = fl_items[1];

            path = path.slice_from(1);

            let ext;
            if path.len() > 4 {
	      ext = path.slice_from(path.len() - 4);
	    } else {
	      ext = "null"
	    }

            let p = Path::new(path);

            //Remove this
            //print(path);

            let mut response: ~str = ~"";

            if path.len() != 0 {
            if p.is_file() {
            if str::eq(&~"html", &ext.into_owned()) {
	      match File::open(&Path::new(path)) {
	      Some(file) => {
		let mut reader = BufferedReader::new(file);
		response = response + "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
		for line in reader.lines() {
		  response = response + line;
		}

	      }
	      None =>{
		response = fourothree();
	      }
	    }
            } else {
	      response = fourothree();
            }
            } else {
	      response = fourothree();
            }
            } else {
	      response = foo();
            }

            stream.write(response.as_bytes());
            println!("Connection terminates.");
        }
    }
}
fn foo() -> ~str {
	unsafe {visitor_count += 1;}
	"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
                 <doctype !html><title>Hello, Rust!</title>

Greetings, Krusty " + unsafe{visitor_count.to_str()} + "!

                 \r\n"
}
fn fourothree() -> ~str {
  ~"HTTP/1.1 403 FORBIDDEN\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n
  <doctype !html><title>Hello, Rust!</title>

403 Forbidden!

                 \r\n"
}<|endoftext|>