<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.

//! This module contains the code to instantiate a "query result", and
//! in particular to extract out the resulting region obligations and
//! encode them therein.
//!
//! For an overview of what canonicaliation is and how it fits into
//! rustc, check out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html

use infer::canonical::substitute::substitute_value;
use infer::canonical::{
    Canonical, CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraint, QueryResult,
};
use infer::region_constraints::{Constraint, RegionConstraintData};
use infer::{InferCtxt, InferOk, InferResult};
use rustc_data_structures::indexed_vec::Idx;
use std::fmt::Debug;
use traits::query::NoSolution;
use traits::{FulfillmentContext, TraitEngine};
use traits::{Obligation, ObligationCause, PredicateObligation};
use ty::fold::TypeFoldable;
use ty::subst::{Kind, UnpackedKind};
use ty::{self, CanonicalVar};

use rustc_data_structures::indexed_vec::IndexVec;

type CanonicalizedQueryResult<'gcx, 'tcx, T> =
    <QueryResult<'tcx, T> as Canonicalize<'gcx, 'tcx>>::Canonicalized;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    /// This method is meant to be invoked as the final step of a canonical query
    /// implementation. It is given:
    ///
    /// - the instantiated variables `inference_vars` created from the query key
    /// - the result `answer` of the query
    /// - a fulfillment context `fulfill_cx` that may contain various obligations which
    ///   have yet to be proven.
    ///
    /// Given this, the function will process the obligations pending
    /// in `fulfill_cx`:
    ///
    /// - If all the obligations can be proven successfully, it will
    ///   package up any resulting region obligations (extracted from
    ///   `infcx`) along with the fully resolved value `answer` into a
    ///   query result (which is then itself canonicalized).
    /// - If some obligations can be neither proven nor disproven, then
    ///   the same thing happens, but the resulting query is marked as ambiguous.
    /// - Finally, if any of the obligations result in a hard error,
    ///   then `Err(NoSolution)` is returned.
    pub fn make_canonicalized_query_result<T>(
        &self,
        inference_vars: CanonicalVarValues<'tcx>,
        answer: T,
        fulfill_cx: &mut FulfillmentContext<'tcx>,
    ) -> Result<CanonicalizedQueryResult<'gcx, 'tcx, T>, NoSolution>
    where
        T: Debug,
        QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>,
    {
        let query_result = self.make_query_result(inference_vars, answer, fulfill_cx)?;
        let (canonical_result, _) = self.canonicalize_response(&query_result);

        debug!(
            "make_canonicalized_query_result: canonical_result = {:#?}",
            canonical_result
        );

        Ok(canonical_result)
    }

    /// Helper for `make_canonicalized_query_result` that does
    /// everything up until the final canonicalization.
    fn make_query_result<T>(
        &self,
        inference_vars: CanonicalVarValues<'tcx>,
        answer: T,
        fulfill_cx: &mut FulfillmentContext<'tcx>,
    ) -> Result<QueryResult<'tcx, T>, NoSolution>
    where
        T: Debug,
        QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>,
    {
        let tcx = self.tcx;

        debug!(
            "make_query_result(\
             inference_vars={:?}, \
             answer={:?})",
            inference_vars, answer,
        );

        // Select everything, returning errors.
        let true_errors = match fulfill_cx.select_where_possible(self) {
            Ok(()) => vec![],
            Err(errors) => errors,
        };
        debug!("true_errors = {:#?}", true_errors);

        if !true_errors.is_empty() {
            // FIXME -- we don't indicate *why* we failed to solve
            debug!("make_query_result: true_errors={:#?}", true_errors);
            return Err(NoSolution);
        }

        // Anything left unselected *now* must be an ambiguity.
        let ambig_errors = match fulfill_cx.select_all_or_error(self) {
            Ok(()) => vec![],
            Err(errors) => errors,
        };
        debug!("ambig_errors = {:#?}", ambig_errors);

        let region_obligations = self.take_registered_region_obligations();

        let region_constraints = self.with_region_constraints(|region_constraints| {
            let RegionConstraintData {
                constraints,
                verifys,
                givens,
            } = region_constraints;

            assert!(verifys.is_empty());
            assert!(givens.is_empty());

            let mut outlives: Vec<_> = constraints
            .into_iter()
            .map(|(k, _)| match *k {
                // Swap regions because we are going from sub (<=) to outlives
                // (>=).
                Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
                    tcx.mk_region(ty::ReVar(v2)).into(),
                    tcx.mk_region(ty::ReVar(v1)),
                ),
                Constraint::VarSubReg(v1, r2) => {
                    ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
                }
                Constraint::RegSubVar(r1, v2) => {
                    ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
                }
                Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
            })
            .map(ty::Binder::dummy) // no bound regions in the code above
            .collect();

            outlives.extend(
                region_obligations
                    .into_iter()
                    .map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
                    .map(ty::Binder::dummy), // no bound regions in the code above
            );

            outlives
        });

        let certainty = if ambig_errors.is_empty() {
            Certainty::Proven
        } else {
            Certainty::Ambiguous
        };

        Ok(QueryResult {
            var_values: inference_vars,
            region_constraints,
            certainty,
            value: answer,
        })
    }

    /// Given the (canonicalized) result to a canonical query,
    /// instantiates the result so it can be used, plugging in the
    /// values from the canonical query. (Note that the result may
    /// have been ambiguous; you should check the certainty level of
    /// the query before applying this function.)
    ///
    /// To get a good understanding of what is happening here, check
    /// out the [chapter in the rustc guide][c].
    ///
    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
    pub fn instantiate_query_result<R>(
        &self,
        cause: &ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        original_values: &CanonicalVarValues<'tcx>,
        query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
    ) -> InferResult<'tcx, R>
    where
        R: Debug + TypeFoldable<'tcx>,
    {
        debug!(
            "instantiate_query_result(original_values={:#?}, query_result={:#?})",
            original_values, query_result,
        );

        // Every canonical query result includes values for each of
        // the inputs to the query. Therefore, we begin by unifying
        // these values with the original inputs that were
        // canonicalized.
        let result_values = &query_result.value.var_values;
        assert_eq!(original_values.len(), result_values.len());

        // Quickly try to find initial values for the canonical
        // variables in the result in terms of the query. We do this
        // by iterating down the values that the query gave to each of
        // the canonical inputs. If we find that one of those values
        // is directly equal to one of the canonical variables in the
        // result, then we can type the corresponding value from the
        // input. See the example above.
        let mut opt_values: IndexVec<CanonicalVar, Option<Kind<'tcx>>> =
            IndexVec::from_elem_n(None, query_result.variables.len());

        // In terms of our example above, we are iterating over pairs like:
        // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
        for (original_value, result_value) in original_values.iter().zip(result_values) {
            match result_value.unpack() {
                UnpackedKind::Type(result_value) => {
                    // e.g., here `result_value` might be `?0` in the example above...
                    if let ty::TyInfer(ty::InferTy::CanonicalTy(index)) = result_value.sty {
                        // in which case we would set `canonical_vars[0]` to `Some(?U)`.
                        opt_values[index] = Some(original_value);
                    }
                }
                UnpackedKind::Lifetime(result_value) => {
                    // e.g., here `result_value` might be `'?1` in the example above...
                    if let &ty::RegionKind::ReCanonical(index) = result_value {
                        // in which case we would set `canonical_vars[0]` to `Some('static)`.
                        opt_values[index] = Some(original_value);
                    }
                }
            }
        }

        // Create a result substitution: if we found a value for a
        // given variable in the loop above, use that. Otherwise, use
        // a fresh inference variable.
        let result_subst = &CanonicalVarValues {
            var_values: query_result
                .variables
                .iter()
                .enumerate()
                .map(|(index, info)| match opt_values[CanonicalVar::new(index)] {
                    Some(k) => k,
                    None => self.fresh_inference_var_for_canonical_var(cause.span, *info),
                })
                .collect(),
        };

        // Unify the original values for the canonical variables in
        // the input with the value found in the query
        // post-substitution. Often, but not always, this is a no-op,
        // because we already found the mapping in the first step.
        let substituted_values = |index: CanonicalVar| -> Kind<'tcx> {
            query_result.substitute_projected(self.tcx, result_subst, |v| &v.var_values[index])
        };
        let mut obligations = self
            .unify_canonical_vars(cause, param_env, original_values, substituted_values)?
            .into_obligations();

        obligations.extend(self.query_region_constraints_into_obligations(
            cause,
            param_env,
            &query_result.value.region_constraints,
            result_subst,
        ));

        let user_result: R =
            query_result.substitute_projected(self.tcx, result_subst, |q_r| &q_r.value);

        Ok(InferOk {
            value: user_result,
            obligations,
        })
    }

    /// Converts the region constraints resulting from a query into an
    /// iterator of obligations.
    fn query_region_constraints_into_obligations<'a>(
        &'a self,
        cause: &'a ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
        result_subst: &'a CanonicalVarValues<'tcx>,
    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a {
        Box::new(
            unsubstituted_region_constraints
                .iter()
                .map(move |constraint| {
                    let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
                    let k1 = substitute_value(self.tcx, result_subst, k1);
                    let r2 = substitute_value(self.tcx, result_subst, r2);
                    match k1.unpack() {
                        UnpackedKind::Lifetime(r1) => Obligation::new(
                            cause.clone(),
                            param_env,
                            ty::Predicate::RegionOutlives(ty::Binder::dummy(
                                ty::OutlivesPredicate(r1, r2),
                            )),
                        ),

                        UnpackedKind::Type(t1) => Obligation::new(
                            cause.clone(),
                            param_env,
                            ty::Predicate::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
                                t1, r2,
                            ))),
                        ),
                    }
                }),
        ) as Box<dyn Iterator<Item = _>>
    }

    /// Given two sets of values for the same set of canonical variables, unify them.
    /// The second set is produced lazilly by supplying indices from the first set.
    fn unify_canonical_vars(
        &self,
        cause: &ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        variables1: &CanonicalVarValues<'tcx>,
        variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
    ) -> InferResult<'tcx, ()> {
        self.commit_if_ok(|_| {
            let mut obligations = vec![];
            for (index, value1) in variables1.var_values.iter_enumerated() {
                let value2 = variables2(index);

                match (value1.unpack(), value2.unpack()) {
                    (UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => {
                        obligations
                            .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                    }
                    (
                        UnpackedKind::Lifetime(ty::ReErased),
                        UnpackedKind::Lifetime(ty::ReErased),
                    ) => {
                        // no action needed
                    }
                    (UnpackedKind::Lifetime(v1), UnpackedKind::Lifetime(v2)) => {
                        obligations
                            .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                    }
                    _ => {
                        bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
                    }
                }
            }
            Ok(InferOk {
                value: (),
                obligations,
            })
        })
    }
}
<commit_msg>extract the handling of region constraints from queries<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.

//! This module contains the code to instantiate a "query result", and
//! in particular to extract out the resulting region obligations and
//! encode them therein.
//!
//! For an overview of what canonicaliation is and how it fits into
//! rustc, check out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html

use infer::canonical::substitute::substitute_value;
use infer::canonical::{
    Canonical, CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraint, QueryResult,
};
use infer::region_constraints::{Constraint, RegionConstraintData};
use infer::{InferCtxt, InferOk, InferResult, RegionObligation};
use rustc_data_structures::indexed_vec::Idx;
use std::fmt::Debug;
use syntax::ast;
use traits::query::NoSolution;
use traits::{FulfillmentContext, TraitEngine};
use traits::{Obligation, ObligationCause, PredicateObligation};
use ty::fold::TypeFoldable;
use ty::subst::{Kind, UnpackedKind};
use ty::{self, CanonicalVar, TyCtxt};

use rustc_data_structures::indexed_vec::IndexVec;

type CanonicalizedQueryResult<'gcx, 'tcx, T> =
    <QueryResult<'tcx, T> as Canonicalize<'gcx, 'tcx>>::Canonicalized;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    /// This method is meant to be invoked as the final step of a canonical query
    /// implementation. It is given:
    ///
    /// - the instantiated variables `inference_vars` created from the query key
    /// - the result `answer` of the query
    /// - a fulfillment context `fulfill_cx` that may contain various obligations which
    ///   have yet to be proven.
    ///
    /// Given this, the function will process the obligations pending
    /// in `fulfill_cx`:
    ///
    /// - If all the obligations can be proven successfully, it will
    ///   package up any resulting region obligations (extracted from
    ///   `infcx`) along with the fully resolved value `answer` into a
    ///   query result (which is then itself canonicalized).
    /// - If some obligations can be neither proven nor disproven, then
    ///   the same thing happens, but the resulting query is marked as ambiguous.
    /// - Finally, if any of the obligations result in a hard error,
    ///   then `Err(NoSolution)` is returned.
    pub fn make_canonicalized_query_result<T>(
        &self,
        inference_vars: CanonicalVarValues<'tcx>,
        answer: T,
        fulfill_cx: &mut FulfillmentContext<'tcx>,
    ) -> Result<CanonicalizedQueryResult<'gcx, 'tcx, T>, NoSolution>
    where
        T: Debug,
        QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>,
    {
        let query_result = self.make_query_result(inference_vars, answer, fulfill_cx)?;
        let (canonical_result, _) = self.canonicalize_response(&query_result);

        debug!(
            "make_canonicalized_query_result: canonical_result = {:#?}",
            canonical_result
        );

        Ok(canonical_result)
    }

    /// Helper for `make_canonicalized_query_result` that does
    /// everything up until the final canonicalization.
    fn make_query_result<T>(
        &self,
        inference_vars: CanonicalVarValues<'tcx>,
        answer: T,
        fulfill_cx: &mut FulfillmentContext<'tcx>,
    ) -> Result<QueryResult<'tcx, T>, NoSolution>
    where
        T: Debug,
        QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>,
    {
        let tcx = self.tcx;

        debug!(
            "make_query_result(\
             inference_vars={:?}, \
             answer={:?})",
            inference_vars, answer,
        );

        // Select everything, returning errors.
        let true_errors = match fulfill_cx.select_where_possible(self) {
            Ok(()) => vec![],
            Err(errors) => errors,
        };
        debug!("true_errors = {:#?}", true_errors);

        if !true_errors.is_empty() {
            // FIXME -- we don't indicate *why* we failed to solve
            debug!("make_query_result: true_errors={:#?}", true_errors);
            return Err(NoSolution);
        }

        // Anything left unselected *now* must be an ambiguity.
        let ambig_errors = match fulfill_cx.select_all_or_error(self) {
            Ok(()) => vec![],
            Err(errors) => errors,
        };
        debug!("ambig_errors = {:#?}", ambig_errors);

        let region_obligations = self.take_registered_region_obligations();
        let region_constraints = self.with_region_constraints(|region_constraints| {
            make_query_outlives(tcx, region_obligations, region_constraints)
        });

        let certainty = if ambig_errors.is_empty() {
            Certainty::Proven
        } else {
            Certainty::Ambiguous
        };

        Ok(QueryResult {
            var_values: inference_vars,
            region_constraints,
            certainty,
            value: answer,
        })
    }

    /// Given the (canonicalized) result to a canonical query,
    /// instantiates the result so it can be used, plugging in the
    /// values from the canonical query. (Note that the result may
    /// have been ambiguous; you should check the certainty level of
    /// the query before applying this function.)
    ///
    /// To get a good understanding of what is happening here, check
    /// out the [chapter in the rustc guide][c].
    ///
    /// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
    pub fn instantiate_query_result<R>(
        &self,
        cause: &ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        original_values: &CanonicalVarValues<'tcx>,
        query_result: &Canonical<'tcx, QueryResult<'tcx, R>>,
    ) -> InferResult<'tcx, R>
    where
        R: Debug + TypeFoldable<'tcx>,
    {
        debug!(
            "instantiate_query_result(original_values={:#?}, query_result={:#?})",
            original_values, query_result,
        );

        // Every canonical query result includes values for each of
        // the inputs to the query. Therefore, we begin by unifying
        // these values with the original inputs that were
        // canonicalized.
        let result_values = &query_result.value.var_values;
        assert_eq!(original_values.len(), result_values.len());

        // Quickly try to find initial values for the canonical
        // variables in the result in terms of the query. We do this
        // by iterating down the values that the query gave to each of
        // the canonical inputs. If we find that one of those values
        // is directly equal to one of the canonical variables in the
        // result, then we can type the corresponding value from the
        // input. See the example above.
        let mut opt_values: IndexVec<CanonicalVar, Option<Kind<'tcx>>> =
            IndexVec::from_elem_n(None, query_result.variables.len());

        // In terms of our example above, we are iterating over pairs like:
        // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
        for (original_value, result_value) in original_values.iter().zip(result_values) {
            match result_value.unpack() {
                UnpackedKind::Type(result_value) => {
                    // e.g., here `result_value` might be `?0` in the example above...
                    if let ty::TyInfer(ty::InferTy::CanonicalTy(index)) = result_value.sty {
                        // in which case we would set `canonical_vars[0]` to `Some(?U)`.
                        opt_values[index] = Some(original_value);
                    }
                }
                UnpackedKind::Lifetime(result_value) => {
                    // e.g., here `result_value` might be `'?1` in the example above...
                    if let &ty::RegionKind::ReCanonical(index) = result_value {
                        // in which case we would set `canonical_vars[0]` to `Some('static)`.
                        opt_values[index] = Some(original_value);
                    }
                }
            }
        }

        // Create a result substitution: if we found a value for a
        // given variable in the loop above, use that. Otherwise, use
        // a fresh inference variable.
        let result_subst = &CanonicalVarValues {
            var_values: query_result
                .variables
                .iter()
                .enumerate()
                .map(|(index, info)| match opt_values[CanonicalVar::new(index)] {
                    Some(k) => k,
                    None => self.fresh_inference_var_for_canonical_var(cause.span, *info),
                })
                .collect(),
        };

        // Unify the original values for the canonical variables in
        // the input with the value found in the query
        // post-substitution. Often, but not always, this is a no-op,
        // because we already found the mapping in the first step.
        let substituted_values = |index: CanonicalVar| -> Kind<'tcx> {
            query_result.substitute_projected(self.tcx, result_subst, |v| &v.var_values[index])
        };
        let mut obligations = self
            .unify_canonical_vars(cause, param_env, original_values, substituted_values)?
            .into_obligations();

        obligations.extend(self.query_region_constraints_into_obligations(
            cause,
            param_env,
            &query_result.value.region_constraints,
            result_subst,
        ));

        let user_result: R =
            query_result.substitute_projected(self.tcx, result_subst, |q_r| &q_r.value);

        Ok(InferOk {
            value: user_result,
            obligations,
        })
    }

    /// Converts the region constraints resulting from a query into an
    /// iterator of obligations.
    fn query_region_constraints_into_obligations<'a>(
        &'a self,
        cause: &'a ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
        result_subst: &'a CanonicalVarValues<'tcx>,
    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a {
        Box::new(
            unsubstituted_region_constraints
                .iter()
                .map(move |constraint| {
                    let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
                    let k1 = substitute_value(self.tcx, result_subst, k1);
                    let r2 = substitute_value(self.tcx, result_subst, r2);
                    match k1.unpack() {
                        UnpackedKind::Lifetime(r1) => Obligation::new(
                            cause.clone(),
                            param_env,
                            ty::Predicate::RegionOutlives(ty::Binder::dummy(
                                ty::OutlivesPredicate(r1, r2),
                            )),
                        ),

                        UnpackedKind::Type(t1) => Obligation::new(
                            cause.clone(),
                            param_env,
                            ty::Predicate::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
                                t1, r2,
                            ))),
                        ),
                    }
                }),
        ) as Box<dyn Iterator<Item = _>>
    }

    /// Given two sets of values for the same set of canonical variables, unify them.
    /// The second set is produced lazilly by supplying indices from the first set.
    fn unify_canonical_vars(
        &self,
        cause: &ObligationCause<'tcx>,
        param_env: ty::ParamEnv<'tcx>,
        variables1: &CanonicalVarValues<'tcx>,
        variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
    ) -> InferResult<'tcx, ()> {
        self.commit_if_ok(|_| {
            let mut obligations = vec![];
            for (index, value1) in variables1.var_values.iter_enumerated() {
                let value2 = variables2(index);

                match (value1.unpack(), value2.unpack()) {
                    (UnpackedKind::Type(v1), UnpackedKind::Type(v2)) => {
                        obligations
                            .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                    }
                    (
                        UnpackedKind::Lifetime(ty::ReErased),
                        UnpackedKind::Lifetime(ty::ReErased),
                    ) => {
                        // no action needed
                    }
                    (UnpackedKind::Lifetime(v1), UnpackedKind::Lifetime(v2)) => {
                        obligations
                            .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations());
                    }
                    _ => {
                        bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,);
                    }
                }
            }
            Ok(InferOk {
                value: (),
                obligations,
            })
        })
    }
}

/// Given the region obligations and constraints scraped from the infcx,
/// creates query region constraints.
fn make_query_outlives<'tcx>(
    tcx: TyCtxt<'_, '_, 'tcx>,
    region_obligations: Vec<(ast::NodeId, RegionObligation<'tcx>)>,
    region_constraints: &RegionConstraintData<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>> {
    let RegionConstraintData {
        constraints,
        verifys,
        givens,
    } = region_constraints;

    assert!(verifys.is_empty());
    assert!(givens.is_empty());

    let mut outlives: Vec<_> = constraints
            .into_iter()
            .map(|(k, _)| match *k {
                // Swap regions because we are going from sub (<=) to outlives
                // (>=).
                Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
                    tcx.mk_region(ty::ReVar(v2)).into(),
                    tcx.mk_region(ty::ReVar(v1)),
                ),
                Constraint::VarSubReg(v1, r2) => {
                    ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
                }
                Constraint::RegSubVar(r1, v2) => {
                    ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
                }
                Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
            })
            .map(ty::Binder::dummy) // no bound regions in the code above
            .collect();

    outlives.extend(
        region_obligations
            .into_iter()
            .map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
            .map(ty::Binder::dummy), // no bound regions in the code above
    );

    outlives
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

//! Simple [DEFLATE][def]-based compression. This is a wrapper around the
//! [`miniz`][mz] library, which is a one-file pure-C implementation of zlib.
//!
//! [def]: https://en.wikipedia.org/wiki/DEFLATE
//! [mz]: https://code.google.com/p/miniz/

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "flate"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(libc)]
#![feature(staged_api)]
#![feature(unique)]
#![cfg_attr(test, feature(rustc_private, rand, vec_push_all))]

#[cfg(test)] #[macro_use] extern crate log;

extern crate libc;

use libc::{c_void, size_t, c_int};
use std::fmt;
use std::ops::Deref;
use std::ptr::Unique;
use std::slice;

#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Error {
    _unused: (),
}

impl Error {
    fn new() -> Error {
        Error {
            _unused: (),
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "decompression error".fmt(f)
    }
}

pub struct Bytes {
    ptr: Unique<u8>,
    len: usize,
}

impl Deref for Bytes {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe { slice::from_raw_parts(*self.ptr, self.len) }
    }
}

impl Drop for Bytes {
    fn drop(&mut self) {
        unsafe { libc::free(*self.ptr as *mut _); }
    }
}

#[link(name = "miniz", kind = "static")]
extern {
    /// Raw miniz compression function.
    fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                  src_buf_len: size_t,
                                  pout_len: *mut size_t,
                                  flags: c_int)
                                  -> *mut c_void;

    /// Raw miniz decompression function.
    fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                    src_buf_len: size_t,
                                    pout_len: *mut size_t,
                                    flags: c_int)
                                    -> *mut c_void;
}

const LZ_NORM: c_int = 0x80;  // LZ with 128 probes, "normal"
const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Bytes {
    unsafe {
        let mut outsz: size_t = 0;
        let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
                                             bytes.len() as size_t,
                                             &mut outsz,
                                             flags);
        assert!(!res.is_null());
        Bytes {
            ptr: Unique::new(res as *mut u8),
            len: outsz as usize,
        }
    }
}

/// Compress a buffer, without writing any sort of header on the output.
pub fn deflate_bytes(bytes: &[u8]) -> Bytes {
    deflate_bytes_internal(bytes, LZ_NORM)
}

/// Compress a buffer, using a header that zlib can understand.
pub fn deflate_bytes_zlib(bytes: &[u8]) -> Bytes {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
    unsafe {
        let mut outsz: size_t = 0;
        let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
                                               bytes.len() as size_t,
                                               &mut outsz,
                                               flags);
        if !res.is_null() {
            Ok(Bytes {
                ptr: Unique::new(res as *mut u8),
                len: outsz as usize,
            })
        } else {
            Err(Error::new())
        }
    }
}

/// Decompress a buffer, without parsing any sort of header on the input.
pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes,Error> {
    inflate_bytes_internal(bytes, 0)
}

/// Decompress a buffer that starts with a zlib header.
pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

#[cfg(test)]
mod tests {
    #![allow(deprecated)]
    use super::{inflate_bytes, deflate_bytes};
    use std::__rand::{thread_rng, Rng};

    #[test]
    fn test_flate_round_trip() {
        let mut r = thread_rng();
        let mut words = vec![];
        for _ in 0..20 {
            let range = r.gen_range(1, 10);
            let v = r.gen_iter::<u8>().take(range).collect::<Vec<u8>>();
            words.push(v);
        }
        for _ in 0..20 {
            let mut input = vec![];
            for _ in 0..2000 {
                input.push_all(r.choose(&words).unwrap());
            }
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(&input);
            let out = inflate_bytes(&cmp).unwrap();
            debug!("{} bytes deflated to {} ({:.1}% size)",
                   input.len(), cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(&*input, &*out);
        }
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = vec![1, 2, 3, 4, 5];
        let deflated = deflate_bytes(&bytes);
        let inflated = inflate_bytes(&deflated).unwrap();
        assert_eq!(&*inflated, &*bytes);
    }
}
<commit_msg>Auto merge of #28949 - iwillspeak:rustfmt-libflate, r=nrc<commit_after>// Copyright 2012 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.

//! Simple [DEFLATE][def]-based compression. This is a wrapper around the
//! [`miniz`][mz] library, which is a one-file pure-C implementation of zlib.
//!
//! [def]: https://en.wikipedia.org/wiki/DEFLATE
//! [mz]: https://code.google.com/p/miniz/

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "flate"]
#![unstable(feature = "rustc_private", issue = "27812")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(libc)]
#![feature(staged_api)]
#![feature(unique)]
#![cfg_attr(test, feature(rustc_private, rand, vec_push_all))]

#[cfg(test)]
#[macro_use]
extern crate log;

extern crate libc;

use libc::{c_void, size_t, c_int};
use std::fmt;
use std::ops::Deref;
use std::ptr::Unique;
use std::slice;

#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Error {
    _unused: (),
}

impl Error {
    fn new() -> Error {
        Error { _unused: () }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "decompression error".fmt(f)
    }
}

pub struct Bytes {
    ptr: Unique<u8>,
    len: usize,
}

impl Deref for Bytes {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe { slice::from_raw_parts(*self.ptr, self.len) }
    }
}

impl Drop for Bytes {
    fn drop(&mut self) {
        unsafe {
            libc::free(*self.ptr as *mut _);
        }
    }
}

#[link(name = "miniz", kind = "static")]
extern {
    /// Raw miniz compression function.
    fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
                                  src_buf_len: size_t,
                                  pout_len: *mut size_t,
                                  flags: c_int)
                                  -> *mut c_void;

    /// Raw miniz decompression function.
    fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
                                    src_buf_len: size_t,
                                    pout_len: *mut size_t,
                                    flags: c_int)
                                    -> *mut c_void;
}

const LZ_NORM: c_int = 0x80;  // LZ with 128 probes, "normal"
const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum

fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Bytes {
    unsafe {
        let mut outsz: size_t = 0;
        let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
                                             bytes.len() as size_t,
                                             &mut outsz,
                                             flags);
        assert!(!res.is_null());
        Bytes {
            ptr: Unique::new(res as *mut u8),
            len: outsz as usize,
        }
    }
}

/// Compress a buffer, without writing any sort of header on the output.
pub fn deflate_bytes(bytes: &[u8]) -> Bytes {
    deflate_bytes_internal(bytes, LZ_NORM)
}

/// Compress a buffer, using a header that zlib can understand.
pub fn deflate_bytes_zlib(bytes: &[u8]) -> Bytes {
    deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
}

fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes, Error> {
    unsafe {
        let mut outsz: size_t = 0;
        let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
                                               bytes.len() as size_t,
                                               &mut outsz,
                                               flags);
        if !res.is_null() {
            Ok(Bytes {
                ptr: Unique::new(res as *mut u8),
                len: outsz as usize,
            })
        } else {
            Err(Error::new())
        }
    }
}

/// Decompress a buffer, without parsing any sort of header on the input.
pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes, Error> {
    inflate_bytes_internal(bytes, 0)
}

/// Decompress a buffer that starts with a zlib header.
pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes, Error> {
    inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
}

#[cfg(test)]
mod tests {
    #![allow(deprecated)]
    use super::{inflate_bytes, deflate_bytes};
    use std::__rand::{thread_rng, Rng};

    #[test]
    fn test_flate_round_trip() {
        let mut r = thread_rng();
        let mut words = vec![];
        for _ in 0..20 {
            let range = r.gen_range(1, 10);
            let v = r.gen_iter::<u8>().take(range).collect::<Vec<u8>>();
            words.push(v);
        }
        for _ in 0..20 {
            let mut input = vec![];
            for _ in 0..2000 {
                input.push_all(r.choose(&words).unwrap());
            }
            debug!("de/inflate of {} bytes of random word-sequences",
                   input.len());
            let cmp = deflate_bytes(&input);
            let out = inflate_bytes(&cmp).unwrap();
            debug!("{} bytes deflated to {} ({:.1}% size)",
                   input.len(),
                   cmp.len(),
                   100.0 * ((cmp.len() as f64) / (input.len() as f64)));
            assert_eq!(&*input, &*out);
        }
    }

    #[test]
    fn test_zlib_flate() {
        let bytes = vec![1, 2, 3, 4, 5];
        let deflated = deflate_bytes(&bytes);
        let inflated = inflate_bytes(&deflated).unwrap();
        assert_eq!(&*inflated, &*bytes);
    }
}
<|endoftext|>


<commit_before><commit_msg>Detect and reload new versions of the dynamic lib<commit_after><|endoftext|>


<commit_before>// Copyright 2015 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.

//! See docs in build/expr/mod.rs

use rustc_data_structures::fnv::FnvHashMap;

use build::{BlockAnd, BlockAndExtension, Builder};
use build::expr::category::{Category, RvalueFunc};
use hair::*;
use rustc::mir::repr::*;

impl<'a,'tcx> Builder<'a,'tcx> {
    /// Compile `expr`, yielding an rvalue.
    pub fn as_rvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Rvalue<'tcx>>
        where M: Mirror<'tcx, Output = Expr<'tcx>>
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_rvalue(block, expr)
    }

    fn expr_as_rvalue(&mut self,
                      mut block: BasicBlock,
                      expr: Expr<'tcx>)
                      -> BlockAnd<Rvalue<'tcx>> {
        debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);

        let this = self;
        let expr_span = expr.span;

        match expr.kind {
            ExprKind::Scope { extent, value } => {
                this.in_scope(extent, block, |this| this.as_rvalue(block, value))
            }
            ExprKind::InlineAsm { asm } => {
                block.and(Rvalue::InlineAsm(asm.clone()))
            }
            ExprKind::Repeat { value, count } => {
                let value_operand = unpack!(block = this.as_operand(block, value));
                block.and(Rvalue::Repeat(value_operand, count))
            }
            ExprKind::Borrow { region, borrow_kind, arg } => {
                let arg_lvalue = unpack!(block = this.as_lvalue(block, arg));
                block.and(Rvalue::Ref(region, borrow_kind, arg_lvalue))
            }
            ExprKind::Binary { op, lhs, rhs } => {
                let lhs = unpack!(block = this.as_operand(block, lhs));
                let rhs = unpack!(block = this.as_operand(block, rhs));
                block.and(Rvalue::BinaryOp(op, lhs, rhs))
            }
            ExprKind::Unary { op, arg } => {
                let arg = unpack!(block = this.as_operand(block, arg));
                block.and(Rvalue::UnaryOp(op, arg))
            }
            ExprKind::Box { value, value_extents } => {
                let value = this.hir.mirror(value);
                let result = this.temp(expr.ty);
                // to start, malloc some memory of suitable type (thus far, uninitialized):
                this.cfg.push_assign(block, expr_span, &result, Rvalue::Box(value.ty));
                this.in_scope(value_extents, block, |this| {
                    // schedule a shallow free of that memory, lest we unwind:
                    this.schedule_box_free(expr_span, value_extents, &result, value.ty);
                    // initialize the box contents:
                    unpack!(block = this.into(&result.clone().deref(), block, value));
                    block.and(Rvalue::Use(Operand::Consume(result)))
                })
            }
            ExprKind::Cast { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
            }
            ExprKind::ReifyFnPointer { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))
            }
            ExprKind::UnsafeFnPointer { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::UnsafeFnPointer, source, expr.ty))
            }
            ExprKind::Unsize { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::Unsize, source, expr.ty))
            }
            ExprKind::Vec { fields } => {
                // (*) We would (maybe) be closer to trans if we
                // handled this and other aggregate cases via
                // `into()`, not `as_rvalue` -- in that case, instead
                // of generating
                //
                //     let tmp1 = ...1;
                //     let tmp2 = ...2;
                //     dest = Rvalue::Aggregate(Foo, [tmp1, tmp2])
                //
                // we could just generate
                //
                //     dest.f = ...1;
                //     dest.g = ...2;
                //
                // The problem is that then we would need to:
                //
                // (a) have a more complex mechanism for handling
                //     partial cleanup;
                // (b) distinguish the case where the type `Foo` has a
                //     destructor, in which case creating an instance
                //     as a whole "arms" the destructor, and you can't
                //     write individual fields; and,
                // (c) handle the case where the type Foo has no
                //     fields. We don't want `let x: ();` to compile
                //     to the same MIR as `let x = ();`.

                // first process the set of fields
                let fields: Vec<_> =
                    fields.into_iter()
                          .map(|f| unpack!(block = this.as_operand(block, f)))
                          .collect();

                block.and(Rvalue::Aggregate(AggregateKind::Vec, fields))
            }
            ExprKind::Tuple { fields } => { // see (*) above
                // first process the set of fields
                let fields: Vec<_> =
                    fields.into_iter()
                          .map(|f| unpack!(block = this.as_operand(block, f)))
                          .collect();

                block.and(Rvalue::Aggregate(AggregateKind::Tuple, fields))
            }
            ExprKind::Closure { closure_id, substs, upvars } => { // see (*) above
                let upvars =
                    upvars.into_iter()
                          .map(|upvar| unpack!(block = this.as_operand(block, upvar)))
                          .collect();
                block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars))
            }
            ExprKind::Adt {
                adt_def, variant_index, substs, fields, base
            } => { // see (*) above
                // first process the set of fields that were provided
                // (evaluating them in order given by user)
                let fields_map: FnvHashMap<_, _> =
                    fields.into_iter()
                          .map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr))))
                          .collect();

                let field_names = this.hir.all_fields(adt_def, variant_index);

                let fields = if let Some(FruInfo { base, field_types }) = base {
                    let base = unpack!(block = this.as_lvalue(block, base));

                    // MIR does not natively support FRU, so for each
                    // base-supplied field, generate an operand that
                    // reads it from the base.
                    field_names.into_iter()
                        .zip(field_types.into_iter())
                        .map(|(n, ty)| match fields_map.get(&n) {
                            Some(v) => v.clone(),
                            None => Operand::Consume(base.clone().field(n, ty))
                        })
                        .collect()
                } else {
                    field_names.iter().map(|n| fields_map[n].clone()).collect()
                };

                block.and(Rvalue::Aggregate(AggregateKind::Adt(adt_def, variant_index, substs),
                                            fields))
            }
            ExprKind::Literal { .. } |
            ExprKind::Block { .. } |
            ExprKind::Match { .. } |
            ExprKind::If { .. } |
            ExprKind::Loop { .. } |
            ExprKind::LogicalOp { .. } |
            ExprKind::Call { .. } |
            ExprKind::Field { .. } |
            ExprKind::Deref { .. } |
            ExprKind::Index { .. } |
            ExprKind::VarRef { .. } |
            ExprKind::SelfRef |
            ExprKind::Assign { .. } |
            ExprKind::AssignOp { .. } |
            ExprKind::Break { .. } |
            ExprKind::Continue { .. } |
            ExprKind::Return { .. } |
            ExprKind::StaticRef { .. } => {
                // these do not have corresponding `Rvalue` variants,
                // so make an operand and then return that
                debug_assert!(match Category::of(&expr.kind) {
                    Some(Category::Rvalue(RvalueFunc::AsRvalue)) => false,
                    _ => true,
                });
                let operand = unpack!(block = this.as_operand(block, expr));
                block.and(Rvalue::Use(operand))
            }
        }
    }
}
<commit_msg>mir: Ignore noop casts (e.g. when `as` used for coercion).<commit_after>// Copyright 2015 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.

//! See docs in build/expr/mod.rs

use rustc_data_structures::fnv::FnvHashMap;

use build::{BlockAnd, BlockAndExtension, Builder};
use build::expr::category::{Category, RvalueFunc};
use hair::*;
use rustc::mir::repr::*;

impl<'a,'tcx> Builder<'a,'tcx> {
    /// Compile `expr`, yielding an rvalue.
    pub fn as_rvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Rvalue<'tcx>>
        where M: Mirror<'tcx, Output = Expr<'tcx>>
    {
        let expr = self.hir.mirror(expr);
        self.expr_as_rvalue(block, expr)
    }

    fn expr_as_rvalue(&mut self,
                      mut block: BasicBlock,
                      expr: Expr<'tcx>)
                      -> BlockAnd<Rvalue<'tcx>> {
        debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);

        let this = self;
        let expr_span = expr.span;

        match expr.kind {
            ExprKind::Scope { extent, value } => {
                this.in_scope(extent, block, |this| this.as_rvalue(block, value))
            }
            ExprKind::InlineAsm { asm } => {
                block.and(Rvalue::InlineAsm(asm.clone()))
            }
            ExprKind::Repeat { value, count } => {
                let value_operand = unpack!(block = this.as_operand(block, value));
                block.and(Rvalue::Repeat(value_operand, count))
            }
            ExprKind::Borrow { region, borrow_kind, arg } => {
                let arg_lvalue = unpack!(block = this.as_lvalue(block, arg));
                block.and(Rvalue::Ref(region, borrow_kind, arg_lvalue))
            }
            ExprKind::Binary { op, lhs, rhs } => {
                let lhs = unpack!(block = this.as_operand(block, lhs));
                let rhs = unpack!(block = this.as_operand(block, rhs));
                block.and(Rvalue::BinaryOp(op, lhs, rhs))
            }
            ExprKind::Unary { op, arg } => {
                let arg = unpack!(block = this.as_operand(block, arg));
                block.and(Rvalue::UnaryOp(op, arg))
            }
            ExprKind::Box { value, value_extents } => {
                let value = this.hir.mirror(value);
                let result = this.temp(expr.ty);
                // to start, malloc some memory of suitable type (thus far, uninitialized):
                this.cfg.push_assign(block, expr_span, &result, Rvalue::Box(value.ty));
                this.in_scope(value_extents, block, |this| {
                    // schedule a shallow free of that memory, lest we unwind:
                    this.schedule_box_free(expr_span, value_extents, &result, value.ty);
                    // initialize the box contents:
                    unpack!(block = this.into(&result.clone().deref(), block, value));
                    block.and(Rvalue::Use(Operand::Consume(result)))
                })
            }
            ExprKind::Cast { source } => {
                let source = this.hir.mirror(source);
                if source.ty == expr.ty {
                    this.expr_as_rvalue(block, source)
                } else {
                    let source = unpack!(block = this.as_operand(block, source));
                    block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
                }
            }
            ExprKind::ReifyFnPointer { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::ReifyFnPointer, source, expr.ty))
            }
            ExprKind::UnsafeFnPointer { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::UnsafeFnPointer, source, expr.ty))
            }
            ExprKind::Unsize { source } => {
                let source = unpack!(block = this.as_operand(block, source));
                block.and(Rvalue::Cast(CastKind::Unsize, source, expr.ty))
            }
            ExprKind::Vec { fields } => {
                // (*) We would (maybe) be closer to trans if we
                // handled this and other aggregate cases via
                // `into()`, not `as_rvalue` -- in that case, instead
                // of generating
                //
                //     let tmp1 = ...1;
                //     let tmp2 = ...2;
                //     dest = Rvalue::Aggregate(Foo, [tmp1, tmp2])
                //
                // we could just generate
                //
                //     dest.f = ...1;
                //     dest.g = ...2;
                //
                // The problem is that then we would need to:
                //
                // (a) have a more complex mechanism for handling
                //     partial cleanup;
                // (b) distinguish the case where the type `Foo` has a
                //     destructor, in which case creating an instance
                //     as a whole "arms" the destructor, and you can't
                //     write individual fields; and,
                // (c) handle the case where the type Foo has no
                //     fields. We don't want `let x: ();` to compile
                //     to the same MIR as `let x = ();`.

                // first process the set of fields
                let fields: Vec<_> =
                    fields.into_iter()
                          .map(|f| unpack!(block = this.as_operand(block, f)))
                          .collect();

                block.and(Rvalue::Aggregate(AggregateKind::Vec, fields))
            }
            ExprKind::Tuple { fields } => { // see (*) above
                // first process the set of fields
                let fields: Vec<_> =
                    fields.into_iter()
                          .map(|f| unpack!(block = this.as_operand(block, f)))
                          .collect();

                block.and(Rvalue::Aggregate(AggregateKind::Tuple, fields))
            }
            ExprKind::Closure { closure_id, substs, upvars } => { // see (*) above
                let upvars =
                    upvars.into_iter()
                          .map(|upvar| unpack!(block = this.as_operand(block, upvar)))
                          .collect();
                block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars))
            }
            ExprKind::Adt {
                adt_def, variant_index, substs, fields, base
            } => { // see (*) above
                // first process the set of fields that were provided
                // (evaluating them in order given by user)
                let fields_map: FnvHashMap<_, _> =
                    fields.into_iter()
                          .map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr))))
                          .collect();

                let field_names = this.hir.all_fields(adt_def, variant_index);

                let fields = if let Some(FruInfo { base, field_types }) = base {
                    let base = unpack!(block = this.as_lvalue(block, base));

                    // MIR does not natively support FRU, so for each
                    // base-supplied field, generate an operand that
                    // reads it from the base.
                    field_names.into_iter()
                        .zip(field_types.into_iter())
                        .map(|(n, ty)| match fields_map.get(&n) {
                            Some(v) => v.clone(),
                            None => Operand::Consume(base.clone().field(n, ty))
                        })
                        .collect()
                } else {
                    field_names.iter().map(|n| fields_map[n].clone()).collect()
                };

                block.and(Rvalue::Aggregate(AggregateKind::Adt(adt_def, variant_index, substs),
                                            fields))
            }
            ExprKind::Literal { .. } |
            ExprKind::Block { .. } |
            ExprKind::Match { .. } |
            ExprKind::If { .. } |
            ExprKind::Loop { .. } |
            ExprKind::LogicalOp { .. } |
            ExprKind::Call { .. } |
            ExprKind::Field { .. } |
            ExprKind::Deref { .. } |
            ExprKind::Index { .. } |
            ExprKind::VarRef { .. } |
            ExprKind::SelfRef |
            ExprKind::Assign { .. } |
            ExprKind::AssignOp { .. } |
            ExprKind::Break { .. } |
            ExprKind::Continue { .. } |
            ExprKind::Return { .. } |
            ExprKind::StaticRef { .. } => {
                // these do not have corresponding `Rvalue` variants,
                // so make an operand and then return that
                debug_assert!(match Category::of(&expr.kind) {
                    Some(Category::Rvalue(RvalueFunc::AsRvalue)) => false,
                    _ => true,
                });
                let operand = unpack!(block = this.as_operand(block, expr));
                block.and(Rvalue::Use(operand))
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

// ignore-tidy-linelength
// We specify -Z incremental here because we want to test the partitioning for
// incremental compilation
// compile-flags:-Zprint-trans-items=eager -Zincremental=tmp/partitioning-tests/extern-generic

#![allow(dead_code)]
#![crate_type="lib"]

// aux-build:cgu_generic_function.rs
extern crate cgu_generic_function;

//~ TRANS_ITEM fn extern_generic::user[0] @@ extern_generic[Internal]
fn user() {
    let _ = cgu_generic_function::foo("abc");
}

mod mod1 {
    use cgu_generic_function;

    //~ TRANS_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[Internal]
    fn user() {
        let _ = cgu_generic_function::foo("abc");
    }

    mod mod1 {
        use cgu_generic_function;

        //~ TRANS_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[Internal]
        fn user() {
            let _ = cgu_generic_function::foo("abc");
        }
    }
}

mod mod2 {
    use cgu_generic_function;

    //~ TRANS_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[Internal]
    fn user() {
        let _ = cgu_generic_function::foo("abc");
    }
}

mod mod3 {
    //~ TRANS_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[Internal]
    fn non_user() {}
}

// Make sure the two generic functions from the extern crate get instantiated
// once for the current crate
//~ TRANS_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function.volatile[External]
//~ TRANS_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function.volatile[Internal]
<commit_msg>Adapt codegen-unit test to shared-generics.<commit_after>// Copyright 2016 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.

// ignore-tidy-linelength
// We specify -Z incremental here because we want to test the partitioning for
// incremental compilation
// compile-flags:-Zprint-trans-items=eager -Zincremental=tmp/partitioning-tests/extern-generic -Zshare-generics=y

#![allow(dead_code)]
#![crate_type="lib"]

// aux-build:cgu_generic_function.rs
extern crate cgu_generic_function;

//~ TRANS_ITEM fn extern_generic::user[0] @@ extern_generic[Internal]
fn user() {
    let _ = cgu_generic_function::foo("abc");
}

mod mod1 {
    use cgu_generic_function;

    //~ TRANS_ITEM fn extern_generic::mod1[0]::user[0] @@ extern_generic-mod1[Internal]
    fn user() {
        let _ = cgu_generic_function::foo("abc");
    }

    mod mod1 {
        use cgu_generic_function;

        //~ TRANS_ITEM fn extern_generic::mod1[0]::mod1[0]::user[0] @@ extern_generic-mod1-mod1[Internal]
        fn user() {
            let _ = cgu_generic_function::foo("abc");
        }
    }
}

mod mod2 {
    use cgu_generic_function;

    //~ TRANS_ITEM fn extern_generic::mod2[0]::user[0] @@ extern_generic-mod2[Internal]
    fn user() {
        let _ = cgu_generic_function::foo("abc");
    }
}

mod mod3 {
    //~ TRANS_ITEM fn extern_generic::mod3[0]::non_user[0] @@ extern_generic-mod3[Internal]
    fn non_user() {}
}

// Make sure the two generic functions from the extern crate get instantiated
// once for the current crate
//~ TRANS_ITEM fn cgu_generic_function::foo[0]<&str> @@ cgu_generic_function.volatile[External]
//~ TRANS_ITEM fn cgu_generic_function::bar[0]<&str> @@ cgu_generic_function.volatile[External]
<|endoftext|>


<commit_before><commit_msg>made Point structure to have one string property<commit_after><|endoftext|>


<commit_before><commit_msg>add const-generics test<commit_after>// check-pass
#![allow(incomplete_features)]
#![feature(const_generics)]

struct Const<const N: usize>;
trait Foo<const N: usize> {}

impl<const N: usize> Foo<N> for Const<N> {}

fn foo_impl(_: impl Foo<3>) {}

fn foo_explicit<T: Foo<3>>(_: T) {}

fn foo_where<T>(_: T)
where
    T: Foo<3>,
{
}

fn main() {
    foo_impl(Const);
    foo_impl(Const::<3>);

    foo_explicit(Const);
    foo_explicit(Const::<3>);

    foo_where(Const);
    foo_where(Const::<3>);
}
<|endoftext|>


<commit_before><commit_msg>initial implementation of cql3 binary protocol<commit_after>extern mod std;

use core::result;
use core::str;
use core::vec;
use core::io;
use core::io::ReaderUtil;
use core::io::WriterUtil;

use std::net_ip;
use std::net_tcp;
use std::net_tcp::TcpSocketBuf;
use std::uv_global_loop;
use std::uv_iotask::IoTask;
use std::bigint;

trait CqlSerializable {
    fn len(&self) -> uint;
    fn serialize<T: io::Writer>(&self, buf: &T);
}

trait CqlReader {
    fn read_cql_str(&self) -> ~str;
    fn read_cql_long_str(&self) -> ~str;
    fn read_cql_rows(&self) -> cql_rows;
    fn read_cql_message(&self) -> cql_message;
}

impl<T: ReaderUtil> CqlReader for T {
    fn read_cql_str(&self) -> ~str {
        let len = self.read_be_u16() as uint;
        str::from_bytes(self.read_bytes(len))
    }

    fn read_cql_long_str(&self) -> ~str {
        let len = self.read_be_u32() as uint;
        str::from_bytes(self.read_bytes(len))
    }

    fn read_cql_rows(&self) -> cql_rows {
        let flags = self.read_be_u32();
        let column_count = self.read_be_u32();
        let (keyspace, table) =
            if flags == 0x0001 {
                let keyspace_str = self.read_cql_str();
                let table_str = self.read_cql_str();
                (keyspace_str, table_str)
            } else {
                (~"", ~"")
            };

        let mut row_metadata:~[cql_row_metadata] = ~[];
        for u32::range(0, column_count) |_| {
            let (keyspace, table) =
                if flags == 0x0001 {
                    (~"", ~"")
                } else {
                    let keyspace_str = self.read_cql_str();
                    let table_str = self.read_cql_str();
                    (keyspace_str, table_str)
                };
            let col_name = self.read_cql_str();
            let type_key = self.read_be_u16();
            let type_name =
                if type_key >= 0x20 {
                    self.read_cql_str()
                } else {
                    ~""
                };

            row_metadata.push(cql_row_metadata {
                keyspace: keyspace,
                table: table,
                col_name: col_name,
                col_type: cql_column_type(type_key),
                col_type_name: type_name
            });
        }

        let rows_count = self.read_be_u32();

        let mut rows:~[cql_row] = ~[];
        for u32::range(0, rows_count) |_| {
            let mut row: cql_row = cql_row{ cols: ~[] };
            for row_metadata.each |meta| {
                let col = match meta.col_type {
                    COLUMN_ASCII => cql_string(self.read_cql_long_str()),
                    COLUMN_VARCHAR => cql_string(self.read_cql_long_str()),
                    COLUMN_TEXT => cql_string(self.read_cql_long_str()),

                    COLUMN_INT => cql_i32(self.read_be_i32()),
                    COLUMN_BIGINT => cql_i64(self.read_be_i64()),
                    COLUMN_FLOAT => cql_f32(self.read_be_u32() as f32),
                    COLUMN_DOUBLE => cql_f64(self.read_be_u64() as f64),

    /*
                    COLUMN_CUSTOM => ,
                    COLUMN_BLOB => ,
                    COLUMN_BOOLEAN => ,
                    COLUMN_COUNTER => ,
                    COLUMN_DECIMAL => ,
                    COLUMN_TIMESTAMP => ,
                    COLUMN_UUID => ,
                    COLUMN_VARINT => ,
                    COLUMN_TIMEUUID => ,
                    COLUMN_INET => ,
                    COLUMN_LIST => ,
                    COLUMN_MAP => ,
                    COLUMN_SET => ,
                    */
                    _ => cql_i32(0),
                };

                row.cols.push(col);
            }
            rows.push(row);
        }

        cql_rows {
            flags: flags,
            column_count: column_count,
            keyspace: keyspace,
            table: table,
            row_metadata: row_metadata,
            rows_count: rows_count,
            rows: rows,
        }
    }

    fn read_cql_message(&self) -> cql_message {
        let version = self.read_u8();
        let flags = self.read_u8();
        let stream = self.read_i8();
        let opcode:cql_opcode = cql_opcode(self.read_u8());
        self.read_be_u32();

        let payload = match opcode {
            OPCODE_READY => empty,
            OPCODE_ERROR => {
                let code = self.read_be_u32();
                let msg = self.read_cql_str();
                error(code, msg)
            },
            OPCODE_RESULT => {
                let code = self.read_be_u32();
                match code {
                    0x0001 => {
                        result_void
                    },
                    0x0002 => {
                        result_rows(self.read_cql_rows())
                    },
                    0x0003 => {
                        let msg = self.read_cql_str();
                        result_keyspace(msg)
                    },
                    _ => empty
                }
            }
            _ => empty,
        };

        return cql_message {
            version: version,
            flags: flags,
            stream: stream,
            opcode: opcode,
            payload: payload,
        };
    }
}

struct pair {
    key: ~str,
    value: ~str,
}

impl CqlSerializable for pair {
    fn serialize<T: io::Writer>(&self, buf: &T) {
        buf.write_be_u16(self.key.len() as u16);
        buf.write(str::to_bytes(self.key));
        buf.write_be_u16(self.value.len() as u16);
        buf.write(str::to_bytes(self.value));
    }

    fn len(&self) -> uint {
        return 4 + self.key.len() + self.value.len();
    }
}

struct string_map {
    pairs: ~[pair],
}

impl CqlSerializable for string_map {
    fn serialize<T: io::Writer>(&self, buf: &T) {
        buf.write_be_u16(self.pairs.len() as u16);
        for self.pairs.each |pair| {
            pair.serialize(buf);
        }
    }

    fn len(&self) -> uint {
        let mut len = 2u;
        for self.pairs.each |pair| {
            len += pair.len();
        }
        len
    }
}

enum cql_consistency {
    CONSISTENCY_ANY = 0x0000,
    CONSISTENCY_ONE = 0x0001,
    CONSISTENCY_TWO = 0x0002,
    CONSISTENCY_THREE = 0x0003,
    CONSISTENCY_QUORUM = 0x0004,
    CONSISTENCY_ALL = 0x0005,
    CONSISTENCY_LOCAL_QUORUM = 0x0006,
    CONSISTENCY_EACH_QUORUM = 0x0007,
    CONSISTENCY_UNKNOWN,
}

fn cql_consistency(val: u16) -> cql_consistency {
    match val {
        0 => CONSISTENCY_ANY,
        1 => CONSISTENCY_ONE,
        2 => CONSISTENCY_TWO,
        3 => CONSISTENCY_THREE,
        4 => CONSISTENCY_QUORUM,
        5 => CONSISTENCY_ALL,
        6 => CONSISTENCY_LOCAL_QUORUM,
        7 => CONSISTENCY_EACH_QUORUM,
        _ => CONSISTENCY_UNKNOWN
    }
}

enum cql_column_type {
    COLUMN_CUSTOM = 0x0000,
    COLUMN_ASCII = 0x0001,
    COLUMN_BIGINT = 0x0002,
    COLUMN_BLOB = 0x0003,
    COLUMN_BOOLEAN = 0x0004,
    COLUMN_COUNTER = 0x0005,
    COLUMN_DECIMAL = 0x0006,
    COLUMN_DOUBLE = 0x0007,
    COLUMN_FLOAT = 0x0008,
    COLUMN_INT = 0x0009,
    COLUMN_TEXT = 0x000A,
    COLUMN_TIMESTAMP = 0x000B,
    COLUMN_UUID = 0x000C,
    COLUMN_VARCHAR = 0x000D,
    COLUMN_VARINT = 0x000E,
    COLUMN_TIMEUUID = 0x000F,
    COLUMN_INET = 0x0010,
    COLUMN_LIST = 0x0020,
    COLUMN_MAP = 0x0021,
    COLUMN_SET = 0x0022,
    COLUMN_UNKNOWN,
}

fn cql_column_type(val: u16) -> cql_column_type {
    match val {
        0x0000 => COLUMN_CUSTOM,
        0x0001 => COLUMN_ASCII,
        0x0002 => COLUMN_BIGINT,
        0x0003 => COLUMN_BLOB,
        0x0004 => COLUMN_BOOLEAN,
        0x0005 => COLUMN_COUNTER,
        0x0006 => COLUMN_DECIMAL,
        0x0007 => COLUMN_DOUBLE,
        0x0008 => COLUMN_FLOAT,
        0x0009 => COLUMN_INT,
        0x000A => COLUMN_TEXT,
        0x000B => COLUMN_TIMESTAMP,
        0x000C => COLUMN_UUID,
        0x000D => COLUMN_VARCHAR,
        0x000E => COLUMN_VARINT,
        0x000F => COLUMN_TIMEUUID,
        0x0010 => COLUMN_INET,
        0x0020 => COLUMN_LIST,
        0x0021 => COLUMN_MAP,
        0x0022 => COLUMN_SET,
        _ => COLUMN_UNKNOWN
    }
}

struct cql_row_metadata {
    keyspace: ~str,
    table: ~str,
    col_name: ~str,
    col_type: cql_column_type,
    col_type_name: ~str,
}

enum cql_col {
    cql_string(~str),

    cql_i32(i32),
    cql_i64(i64),

    cql_blob(~[u8]),
    cql_bool(bool),

    cql_counter(u64),

    cql_f32(f32),
    cql_f64(f64),

    cql_timestamp(u64),
    cql_bigint(bigint::BigInt),
}

struct cql_row {
    cols: ~[cql_col],
}

struct cql_rows {
    flags: u32,
    column_count: u32,
    keyspace: ~str,
    table: ~str,
    row_metadata: ~[cql_row_metadata],
    rows_count: u32,
    rows: ~[cql_row],
}

enum cql_payload {
    startup(string_map),
    query(~str, cql_consistency),
    error(u32, ~str),

    result_void(),
    result_rows(cql_rows),
    result_keyspace(~str),
    result_schema_change(),

    empty(),
}

const CQL_VERSION:u8 = 0x01;

enum cql_opcode {
    OPCODE_ERROR = 0x00,
    OPCODE_STARTUP = 0x01,
    OPCODE_READY = 0x02,
    OPCODE_AUTHENTICATE = 0x03,
    OPCODE_CREDENTIALS = 0x04,
    OPCODE_OPTIONS = 0x05,
    OPCODE_SUPPORTED = 0x06,
    OPCODE_QUERY = 0x07,
    OPCODE_RESULT = 0x08,
    OPCODE_PREPARE = 0x09,
    OPCODE_EXECUTE = 0x0A,
    OPCODE_REGISTER = 0x0B,
    OPCODE_EVENT = 0x0C,
    OPCODE_UNKNOWN
}

fn cql_opcode(val: u8) -> cql_opcode {
    match val {
        0x00 => OPCODE_ERROR,
        0x01 => OPCODE_STARTUP,
        0x02 => OPCODE_READY,
        0x03 => OPCODE_AUTHENTICATE,
        0x04 => OPCODE_CREDENTIALS,
        0x05 => OPCODE_OPTIONS,
        0x06 => OPCODE_SUPPORTED,
        0x07 => OPCODE_QUERY,
        0x08 => OPCODE_RESULT,
        0x09 => OPCODE_PREPARE,
        0x0A => OPCODE_EXECUTE,
        0x0B => OPCODE_REGISTER,
        0x0C => OPCODE_EVENT,
        _ => OPCODE_UNKNOWN
    }
}

struct cql_message {
    version: u8,
    flags: u8,
    stream: i8,
    opcode: cql_opcode,
    payload: cql_payload,
}

impl CqlSerializable for cql_message {
    fn serialize<T: io::Writer>(&self, buf: &T) {
        buf.write_u8(self.version);
        buf.write_u8(self.flags);
        buf.write_i8(self.stream);
        buf.write_u8(self.opcode as u8);
        buf.write_be_u32((self.len()-8) as u32);

        match copy self.payload {
            startup(map) => {
                map.serialize(buf)
            },
            query(query_str, consistency) => {
                buf.write_be_u32(query_str.len() as u32);
                buf.write(str::to_bytes(query_str));
                buf.write_be_u16(consistency as u16);
            },
            _ => (),
        }
    }
    fn len(&self) -> uint {
        8 + match copy self.payload {
            startup(map) => {
                map.len()
            },
            query(query_str, _) => {
                4 + query_str.len() + 2
            },
            _ => {
                0
            }
        }
    }
}

fn Options() -> cql_message {
    return cql_message {
        version: CQL_VERSION,
        flags: 0x00,
        stream: 0x01,
        opcode: OPCODE_OPTIONS,
        payload: empty,
    };
}

fn Startup() -> cql_message {
    let payload = string_map {
            pairs:~[pair{key: ~"CQL_VERSION", value: ~"3.0.0"}],
        };
    return cql_message {
        version: CQL_VERSION,
        flags: 0x00,
        stream: 0x01,
        opcode: OPCODE_STARTUP,
        payload: startup(payload),
    };
}

fn Query(query_str: ~str, con: cql_consistency) -> cql_message {
    return cql_message {
        version: CQL_VERSION,
        flags: 0x00,
        stream: 0x01,
        opcode: OPCODE_QUERY,
        payload: query(query_str, con),
    };
}

struct cql_client {
    socket: @net_tcp::TcpSocketBuf,
}

impl cql_client {
    fn query(&self, query_str: ~str) -> cql_message {
        Query(query_str, CONSISTENCY_ONE).serialize::<net_tcp::TcpSocketBuf>(self.socket);

        (*self.socket).read_cql_message()
    }
}

struct cql_err {
    err_name: ~str,
    err_msg: ~str,
}

fn cql_err(name: ~str, msg: ~str) -> cql_err {
    return cql_err{err_name: name, err_msg: msg};
}

fn get_sock(ip: ~str, port: uint) -> net_tcp::TcpSocket {
    let task = @uv_global_loop::get();
    let addr = net_ip::v4::parse_addr(ip);

    let res = net_tcp::connect(addr, port, task);
    if(res.is_err()) {
        io::println("Connection failed");
    }

    res.unwrap()
}

fn cql_client_create(ip: ~str, port: uint) -> result::Result<cql_client, cql_err> {
    let socket = get_sock(ip, port);
    let buf = @net_tcp::socket_buf(socket);

    let msg_startup = Startup();
    msg_startup.serialize::<net_tcp::TcpSocketBuf>(buf);

    let response = (*buf).read_cql_message();
    match response.opcode {
        OPCODE_READY => result::Ok(cql_client { socket: buf }),
        _ => result::Err(cql_err(fmt!("Invalid opcode: %?", response.opcode), ~""))
    }
}

fn main() {
    let res = ~cql_client_create(~"127.0.0.1", 9042);
    if res.is_err() {
        return;
    }

    let client = res.get_ref();
    //client.query(~"use test");
    let response = client.query(~"select id, email from test.test");
    io::println(fmt!("%?", response));
}
<|endoftext|>


<commit_before><commit_msg>Start writing disk device.<commit_after>use super::ConcurrentDevice;

use z80e_core_rust::{ Z80IODevice };

use std::sync::{ Arc, Condvar, Mutex };
use std::sync::atomic::{ AtomicBool, AtomicUsize, Ordering };
use std::io::{ self, Read, Write, Seek, SeekFrom, ErrorKind };
use std::fs::{ OpenOptions, File };
use std::path::Path;
use std::thread;
use std::str;

// Status port bitflags.
//     8-bit values, but "must" be usize to avoid overly-verbose casts for AtomicUsize calls.
const COMMAND_READY: usize = 1 << 4;
const DATA_READY: usize = 1 << 5;
const RESERVED: usize = 1 << 6;
const ERROR: usize = 1 << 7;
const DISK_MASK: usize = 0x0F;

// Commands.
const NOP: u8 = 0;
const SEL_DSK: u8 = 1;
const SEL_TRK: u8 = 2;
const SEL_SEC: u8 = 3;
const READ: u8 = 4;
const WRITE: u8 = 5;

pub struct Disk {
    file: File,
    spt: u16,
    tracks: u16,
}

impl Disk {
    pub fn open<T: AsRef<Path>>(path: &T) -> io::Result<Disk> {
        let mut file = try!(OpenOptions::new().read(true).write(true).open(path));
        {
            let mut magic: [u8; 10] = [0; 10];
            let mut read = 0;
            while read < magic.len() {
                read += try!(file.read(&mut magic[read..]));
            }
            if match str::from_utf8(&magic) {
                Ok(x) => x,
                Err(err) => return Err(io::Error::new(ErrorKind::InvalidData, "Not a valid disk image.")),
            } != "<CPM_Disk>" {
                return Err(io::Error::new(ErrorKind::InvalidData, "Not a valid disk image."));
            }
        }
        try!(file.seek(SeekFrom::Start(32)));
        let mut spt: [u8; 2] = [0; 2];
        let mut read = 0;
        while read < spt.len() {
            read += try!(file.read(&mut spt[read..]));
        }
        let spt: u16 = (spt[0] as u16) | ((spt[1] as u16) << 8);
        try!(file.seek(SeekFrom::Current(1)));
        let mut blm: [u8; 1] = [0; 1];
        while try!(file.read(&mut blm)) == 0 {};
        let blm = blm[0];
        let bls = blm + 1;
        try!(file.seek(SeekFrom::Current(1)));
        let mut dsm: [u8; 2] = [0; 2];
        let mut read = 0;
        while read < dsm.len() {
            read += try!(file.read(&mut dsm[read..]));
        }
        let dsm: u16 = (dsm[0] as u16) | ((dsm[1] as u16) << 8);
        Ok(Disk {
            file: file,
            spt: spt,
            tracks: ((bls as u16 * (dsm + 1)) / spt),
        })
    }
}

#[derive(Clone)]
pub struct DiskController {
    pub status: Arc<AtomicUsize>,
    do_command: Arc<Condvar>,
    buffer: Arc<Mutex<Buffer>>,
    parameters: Arc<Mutex<Parameters>>,
}

impl DiskController {
    fn new() -> DiskController {
        DiskController {
            status: Arc::new(AtomicUsize::new(0)),
            do_command: Arc::new(Condvar::new()),
            buffer: Arc::new(Mutex::new(Buffer::new())),
            parameters: Arc::new(Mutex::new(Parameters::new())),
        }
    }
}

impl ConcurrentDevice for DiskController {
    fn run(&mut self, die: Arc<AtomicBool>) {

    }
}

struct Buffer {
    bytes: [u8; 0x80],
    i: u8,
}

impl Buffer {
    fn new() -> Buffer {
        Buffer {
            bytes: [0; 0x80],
            i: 0,
        }
    }
}

struct Parameters {
    disk: u8,
    track: u16,
    sector: u8,
    command: u8,
}

impl Parameters {
    fn new() -> Parameters {
        Parameters {
            disk: 0,
            track: 0,
            sector: 0,
            command: NOP,
        }
    }
}

struct StatusPort {
    controller: DiskController,
}

impl StatusPort {
    fn new(controller: DiskController) -> StatusPort {
        StatusPort {
            controller: controller,
        }
    }
}

impl Z80IODevice for StatusPort {
    fn read_in(&self) -> u8 {
        (self.controller.status.load(Ordering::SeqCst) & 0xff) as u8
    }
    fn write_out(&mut self, value: u8) {
        self.controller.status.fetch_and(!(COMMAND_READY | DATA_READY), Ordering::SeqCst);
        let mut params = self.controller.parameters.lock().unwrap();
        params.command = value;
        self.controller.do_command.notify_one();
    }
}

struct DataPort {
    controller: DiskController,
}

impl DataPort {
    fn new(controller: DiskController) -> DataPort {
        DataPort {
            controller: controller,
        }
    }
}

impl Z80IODevice for DataPort {
    fn read_in (&self) -> u8 {
        if (self.controller.status.load(Ordering::SeqCst) & DATA_READY) != 0 {
            let mut buffer = self.controller.buffer.lock().unwrap();
            let i = (buffer.i & !0x80) as usize;
            buffer.i += 1;
            buffer.bytes[i]
        } else {
            let _ = writeln!(io::stderr(), "disk: Attempted to read data register when not ready.");
            0
        }
    }
    fn write_out(&mut self, value: u8) {
        if (self.controller.status.load(Ordering::SeqCst) & DATA_READY) != 0 {
            let mut buffer = self.controller.buffer.lock().unwrap();
            let i = (buffer.i & !0x80) as usize;
            buffer.i += 1;
            buffer.bytes[i] = value;
        } else {
            let _ = writeln!(io::stderr(), "disk: Attempted to write data register when not ready.");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add help file to deal with help related material.<commit_after>use getopts::{optflag,usage,OptGroup};
use std::io::{println,print};

pub fn opts() -> [OptGroup, .. 2]{
    return [
        optflag("v", "version", "display the version"),
        optflag("h", "help", "print this help menu")
    ]
}

pub fn print_usage(_program: &str, opts: &[OptGroup]) {
    let space = "    ";
    println("Usage: muxed [options]");
    println("");
    println("Commands:");
    println(format!("{}new                 create a new project file", space).as_slice());
    print(format!("{}open                open a new project file", space).as_slice());
    println(usage("", opts).as_slice());
}
<|endoftext|>


<commit_before><commit_msg>Had some sucess with clap<commit_after>extern crate clap;
extern crate rusqlite;
use clap::{App, Arg};

mod loader;

fn main() {

    // Once all App settings (including all arguments) have been set, you call get_matches() which
    // parses the string provided by the user, and returns all the valid matches to the ones you
    // specified.
    //
    // You can then query the matches struct to get information about how the user ran the program
    // at startup.
    //
    // For this example, let's assume you created an App which accepts three arguments (plus two
    // generated by clap), a flag to display debugging information triggered with "-d" or
    // "--debug" as well as an option argument which specifies a custom configuration file to use
    // triggered with "-c file" or "--config file" or "--config=file" and finally a positional
    // argument which is the input file we want to work with, this will be the only required
    // argument.
    let matches = App::new("whenenv")
                        .about("Parses an input file to do awesome things")
                        .version("1.0")
                        .author("Kevin K. <kbknapp@gmail.com>")
                        .arg(Arg::with_name("verbose")
                                    .help("Increase log output.")
                                    .short("v")
                                    .multiple(true)
                                    .long("verbose"))
                        .arg(Arg::with_name("quiet")
                                    .help("Decrease log output.")
                                    .short("q")
                                    .multiple(true)
                                    .long("quiet"))
                        .arg(Arg::with_name("env")
                                    .short("e")
                                    .long("env")
                                    .value_name("ENVIROMENT_VARIABLE")
                                    .help("Which enviroment variables to process")
                                    .multiple(true)
                                    .takes_value(true))
                        .arg(Arg::with_name("dir-jobs")
                                    .long("dir-jobs")
                                    .value_name("DIR_JOB")
                                    .help("directory storing json jobs.")
                                    .multiple(true)
                                    .takes_value(true))
                        .arg(Arg::with_name("dir-scripts")
                                    .long("dir-scripts")
                                    .value_name("DIR_SCRIPT")
                                    .help("directory storing jobs scripts.")
                                    .multiple(true)
                                    .takes_value(true))
                        .arg(Arg::with_name("config")
                                    .short("c")
                                    .long("config")
                                    .value_name("FILE")
                                    .help("Sets a custom config file")
                                    .takes_value(true))
                        .get_matches();

    // We can find out whether or not debugging was turned on
    if matches.is_present("debug") {
        println!("Debugging is turned on");
    }

    // If we wanted to some custom initialization based off some configuration file provided
    // by the user, we could get the file (A string of the file)
    if let Some(ref file) = matches.value_of("config") {
        println!("Using config file: {}", file);
    }
    if let Some(ref env) = matches.value_of("env") {
        println!("Using config file: {}", env);
    }

    if let Some(in_v) = matches.values_of("dir-scripts") {
        for in_file in in_v {
            println!("An input dir-scripts: {}", in_file);
           loader::listy(&in_file);
        }
    }
    // Continued program logic goes here...
    loader::deligate(matches)
}
<|endoftext|>


<commit_before><commit_msg>Added license support.<commit_after><|endoftext|>


<commit_before><commit_msg>Add display for metadata format<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for second half of issue #15689<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.

#[deriving(Clone)]
enum Test<'a> {
    Slice(&'a int)
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add basic file system tests<commit_after>#[macro_use]
extern crate lazy_static;

extern crate rex;

mod util;

use std::path::Path;

use rex::frontend::{Event, KeyPress};

use util::mock_filesystem::MockFileSystem;

// Little helper function till Iterator.eq stabalizes
fn iter_eq<I, J>(one: I, other: J) -> bool where
    I: IntoIterator,
    J: IntoIterator,
    I::Item: PartialEq<J::Item>,
{
    let mut one = one.into_iter();
    let mut other = other.into_iter();

    loop {
        match (one.next(), other.next()) {
            (None, None) => return true,
            (None, _) | (_, None) => return false,
            (Some(x), Some(y)) => if x != y { return false },
        }
    }
}

#[test]
fn test_basic_open() {
    // Create a vec with a marker in the end
    let mut v = vec![0; 1000];
    let len = v.len();
    v[len-1] = 0xAA;
    MockFileSystem::put("test_basic_open", v);

    let (mut edit, mut frontend) = util::simple_init_empty();
    let pedit = &mut edit;

    // Open file with the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('o')]);
    frontend.run_str(pedit, "test_basic_open");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Find the marker
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('f')]);
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('h')]);
    frontend.run_str(pedit, "AA");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // And make sure it is in the right place
    assert_eq!(pedit.get_position(), (len-1) as isize);

    // Make sure the opened file name is correct
    let name = Path::new("test_basic_open");
    assert_eq!(name, pedit.get_file_path().unwrap());
}

#[test]
fn test_basic_save() {
    // Create a view over a generic vector
    let v = util::generate_vec(1000);
    let (mut edit, mut frontend) = util::simple_init_with_vec(v.clone());
    let pedit = &mut edit;

    // Save it to a file
    frontend.run_keys(pedit, vec![KeyPress::Shortcut('s')]);
    frontend.run_str(pedit, "test_basic_save");
    frontend.run_keys(pedit, vec![KeyPress::Enter]);

    // Make sure they are equal
    assert!(iter_eq(v.iter(), MockFileSystem::get_inner("test_basic_save").iter()));
}
<|endoftext|>


<commit_before>// Copyright 2015 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.

use LinkerFlavor;
use super::{LinkArgs, Target, TargetOptions};
use super::emscripten_base::{cmd};

pub fn target() -> Result<Target, String> {
    let mut post_link_args = LinkArgs::new();
    post_link_args.insert(LinkerFlavor::Em,
                          vec!["-s".to_string(),
                               "WASM=1".to_string(),
                               "-s".to_string(),
                               "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]);

    let opts = TargetOptions {
        linker: cmd("emcc"),
        ar: cmd("emar"),

        dynamic_linking: false,
        executables: true,
        // Today emcc emits two files - a .js file to bootstrap and
        // possibly interpret the wasm, and a .wasm file
        exe_suffix: ".js".to_string(),
        linker_is_gnu: true,
        link_env: vec![("EMCC_WASM_BACKEND".to_string(), "1".to_string())],
        allow_asm: false,
        obj_is_bitcode: true,
        is_like_emscripten: true,
        max_atomic_width: Some(32),
        post_link_args: post_link_args,
        target_family: Some("unix".to_string()),
        .. Default::default()
    };
    Ok(Target {
        llvm_target: "wasm32-unknown-unknown".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_os: "emscripten".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
        arch: "wasm32".to_string(),
        linker_flavor: LinkerFlavor::Em,
        options: opts,
    })
}
<commit_msg>Pass debugging arguments to emcc<commit_after>// Copyright 2015 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.

use LinkerFlavor;
use super::{LinkArgs, Target, TargetOptions};
use super::emscripten_base::{cmd};

pub fn target() -> Result<Target, String> {
    let mut post_link_args = LinkArgs::new();
    post_link_args.insert(LinkerFlavor::Em,
                          vec!["-s".to_string(),
                               "WASM=1".to_string(),
                               "-s".to_string(),
                               "ASSERTIONS=1".to_string(),
                               "-s".to_string(),
                               "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
                               "-g3".to_string()]);

    let opts = TargetOptions {
        linker: cmd("emcc"),
        ar: cmd("emar"),

        dynamic_linking: false,
        executables: true,
        // Today emcc emits two files - a .js file to bootstrap and
        // possibly interpret the wasm, and a .wasm file
        exe_suffix: ".js".to_string(),
        linker_is_gnu: true,
        link_env: vec![("EMCC_WASM_BACKEND".to_string(), "1".to_string())],
        allow_asm: false,
        obj_is_bitcode: true,
        is_like_emscripten: true,
        max_atomic_width: Some(32),
        post_link_args: post_link_args,
        target_family: Some("unix".to_string()),
        .. Default::default()
    };
    Ok(Target {
        llvm_target: "wasm32-unknown-unknown".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_os: "emscripten".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
        arch: "wasm32".to_string(),
        linker_flavor: LinkerFlavor::Em,
        options: opts,
    })
}
<|endoftext|>


<commit_before><commit_msg>Wyvern: A final tranche of rustdoc comment updates for renderervk.rs<commit_after><|endoftext|>