<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 "canonicalizer" itself.
//!
//! 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::{
    Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
    SmallCanonicalVarValues,
};
use infer::InferCtxt;
use std::sync::atomic::Ordering;
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::Kind;
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt, TypeFlags};

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use smallvec::SmallVec;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    /// Canonicalizes a query value `V`. When we canonicalize a query,
    /// we not only canonicalize unbound inference variables, but we
    /// *also* replace all free regions whatsoever. So for example a
    /// query like `T: Trait<'static>` would be canonicalized to
    ///
    /// ```text
    /// T: Trait<'?0>
    /// ```
    ///
    /// with a mapping M that maps `'?0` to `'static`.
    ///
    /// 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#canonicalizing-the-query
    pub fn canonicalize_query<V>(
        &self,
        value: &V,
        var_values: &mut SmallCanonicalVarValues<'tcx>
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        self.tcx
            .sess
            .perf_stats
            .queries_canonicalized
            .fetch_add(1, Ordering::Relaxed);

        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: true,
                other_free_regions: true,
            },
            var_values,
        )
    }

    /// Canonicalizes a query *response* `V`. When we canonicalize a
    /// query response, we only canonicalize unbound inference
    /// variables, and we leave other free regions alone. So,
    /// continuing with the example from `canonicalize_query`, if
    /// there was an input query `T: Trait<'static>`, it would have
    /// been canonicalized to
    ///
    /// ```text
    /// T: Trait<'?0>
    /// ```
    ///
    /// with a mapping M that maps `'?0` to `'static`. But if we found that there
    /// exists only one possible impl of `Trait`, and it looks like
    ///
    ///     impl<T> Trait<'static> for T { .. }
    ///
    /// then we would prepare a query result R that (among other
    /// things) includes a mapping to `'?0 := 'static`. When
    /// canonicalizing this query result R, we would leave this
    /// reference to `'static` alone.
    ///
    /// 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#canonicalizing-the-query-result
    pub fn canonicalize_response<V>(
        &self,
        value: &V,
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        let mut var_values = SmallVec::new();
        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: false,
                other_free_regions: false,
            },
            &mut var_values
        )
    }

    /// A hacky variant of `canonicalize_query` that does not
    /// canonicalize `'static`.  Unfortunately, the existing leak
    /// check treaks `'static` differently in some cases (see also
    /// #33684), so if we are performing an operation that may need to
    /// prove "leak-check" related things, we leave `'static`
    /// alone.
    ///
    /// FIXME(#48536) -- once we have universes, we can remove this and just use
    /// `canonicalize_query`.
    pub fn canonicalize_hr_query_hack<V>(
        &self,
        value: &V,
        var_values: &mut SmallCanonicalVarValues<'tcx>
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        self.tcx
            .sess
            .perf_stats
            .queries_canonicalized
            .fetch_add(1, Ordering::Relaxed);

        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: false,
                other_free_regions: true,
            },
            var_values
        )
    }
}

/// If this flag is true, then all free regions will be replaced with
/// a canonical var. This is used to make queries as generic as
/// possible. For example, the query `F: Foo<'static>` would be
/// canonicalized to `F: Foo<'0>`.
struct CanonicalizeRegionMode {
    static_region: bool,
    other_free_regions: bool,
}

impl CanonicalizeRegionMode {
    fn any(&self) -> bool {
        self.static_region || self.other_free_regions
    }
}

struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    variables: SmallVec<[CanonicalVarInfo; 8]>,
    var_values: &'cx mut SmallCanonicalVarValues<'tcx>,
    // Note that indices is only used once `var_values` is big enough to be
    // heap-allocated.
    indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
    canonicalize_region_mode: CanonicalizeRegionMode,
    needs_canonical_flags: TypeFlags,
}

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

    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
        match *r {
            ty::ReLateBound(..) => {
                // leave bound regions alone
                r
            }

            ty::ReVar(vid) => {
                let r = self
                    .infcx
                    .unwrap()
                    .borrow_region_constraints()
                    .opportunistic_resolve_var(self.tcx, vid);
                let info = CanonicalVarInfo {
                    kind: CanonicalVarKind::Region,
                };
                debug!(
                    "canonical: region var found with vid {:?}, \
                     opportunistically resolved to {:?}",
                    vid, r
                );
                let cvar = self.canonical_var(info, r.into());
                self.tcx().mk_region(ty::ReCanonical(cvar))
            }

            ty::ReStatic => {
                if self.canonicalize_region_mode.static_region {
                    let info = CanonicalVarInfo {
                        kind: CanonicalVarKind::Region,
                    };
                    let cvar = self.canonical_var(info, r.into());
                    self.tcx().mk_region(ty::ReCanonical(cvar))
                } else {
                    r
                }
            }

            ty::ReEarlyBound(..)
            | ty::ReFree(_)
            | ty::ReScope(_)
            | ty::RePlaceholder(..)
            | ty::ReEmpty
            | ty::ReErased => {
                if self.canonicalize_region_mode.other_free_regions {
                    let info = CanonicalVarInfo {
                        kind: CanonicalVarKind::Region,
                    };
                    let cvar = self.canonical_var(info, r.into());
                    self.tcx().mk_region(ty::ReCanonical(cvar))
                } else {
                    r
                }
            }

            ty::ReClosureBound(..) | ty::ReCanonical(_) => {
                bug!("canonical region encountered during canonicalization")
            }
        }
    }

    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
        match t.sty {
            ty::Infer(ty::TyVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::General, t),

            ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Int, t),

            ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Float, t),

            ty::Infer(ty::FreshTy(_))
            | ty::Infer(ty::FreshIntTy(_))
            | ty::Infer(ty::FreshFloatTy(_)) => {
                bug!("encountered a fresh type during canonicalization")
            }

            ty::Infer(ty::CanonicalTy(_)) => {
                bug!("encountered a canonical type during canonicalization")
            }

            ty::Closure(..)
            | ty::Generator(..)
            | ty::GeneratorWitness(..)
            | ty::Bool
            | ty::Char
            | ty::Int(..)
            | ty::Uint(..)
            | ty::Float(..)
            | ty::Adt(..)
            | ty::Str
            | ty::Error
            | ty::Array(..)
            | ty::Slice(..)
            | ty::RawPtr(..)
            | ty::Ref(..)
            | ty::FnDef(..)
            | ty::FnPtr(_)
            | ty::Dynamic(..)
            | ty::Never
            | ty::Tuple(..)
            | ty::Projection(..)
            | ty::UnnormalizedProjection(..)
            | ty::Foreign(..)
            | ty::Param(..)
            | ty::Opaque(..) => {
                if t.flags.intersects(self.needs_canonical_flags) {
                    t.super_fold_with(self)
                } else {
                    t
                }
            }
        }
    }
}

impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
    /// The main `canonicalize` method, shared impl of
    /// `canonicalize_query` and `canonicalize_response`.
    fn canonicalize<V>(
        value: &V,
        infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        canonicalize_region_mode: CanonicalizeRegionMode,
        var_values: &'cx mut SmallCanonicalVarValues<'tcx>
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        debug_assert!(
            !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS),
            "canonicalizing a canonical value: {:?}",
            value,
        );

        let needs_canonical_flags = if canonicalize_region_mode.any() {
            TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
        } else {
            TypeFlags::KEEP_IN_LOCAL_TCX
        };

        let gcx = tcx.global_tcx();

        // Fast path: nothing that needs to be canonicalized.
        if !value.has_type_flags(needs_canonical_flags) {
            let out_value = gcx.lift(value).unwrap();
            let canon_value = Canonical {
                variables: List::empty(),
                value: out_value,
            };
            return canon_value;
        }

        let mut canonicalizer = Canonicalizer {
            infcx,
            tcx,
            canonicalize_region_mode,
            needs_canonical_flags,
            variables: SmallVec::new(),
            var_values,
            indices: FxHashMap::default(),
        };
        let out_value = value.fold_with(&mut canonicalizer);

        // Once we have canonicalized `out_value`, it should not
        // contain anything that ties it to this inference context
        // anymore, so it should live in the global arena.
        let out_value = gcx.lift(&out_value).unwrap_or_else(|| {
            bug!(
                "failed to lift `{:?}`, canonicalized from `{:?}`",
                out_value,
                value
            )
        });

        let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables);

        Canonical {
            variables: canonical_variables,
            value: out_value,
        }
    }

    /// Creates a canonical variable replacing `kind` from the input,
    /// or returns an existing variable if `kind` has already been
    /// seen. `kind` is expected to be an unbound variable (or
    /// potentially a free region).
    fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
        let Canonicalizer {
            variables,
            var_values,
            indices,
            ..
        } = self;

        // This code is hot. `variables` and `var_values` are usually small
        // (fewer than 8 elements ~95% of the time). They are SmallVec's to
        // avoid allocations in those cases. We also don't use `indices` to
        // determine if a kind has been seen before until the limit of 8 has
        // been exceeded, to also avoid allocations for `indices`.
        if !var_values.spilled() {
            // `var_values` is stack-allocated. `indices` isn't used yet. Do a
            // direct linear search of `var_values`.
            if let Some(idx) = var_values.iter().position(|&k| k == kind) {
                // `kind` is already present in `var_values`.
                CanonicalVar::new(idx)
            } else {
                // `kind` isn't present in `var_values`. Append it. Likewise
                // for `info` and `variables`.
                variables.push(info);
                var_values.push(kind);
                assert_eq!(variables.len(), var_values.len());

                // If `var_values` has become big enough to be heap-allocated,
                // fill up `indices` to facilitate subsequent lookups.
                if var_values.spilled() {
                    assert!(indices.is_empty());
                    *indices =
                        var_values.iter()
                            .enumerate()
                            .map(|(i, &kind)| (kind, CanonicalVar::new(i)))
                            .collect();
                }
                // The cv is the index of the appended element.
                CanonicalVar::new(var_values.len() - 1)
            }
        } else {
            // `var_values` is large. Do a hashmap search via `indices`.
            *indices
                .entry(kind)
                .or_insert_with(|| {
                    variables.push(info);
                    var_values.push(kind);
                    assert_eq!(variables.len(), var_values.len());
                    CanonicalVar::new(variables.len() - 1)
                })
        }
    }

    /// Given a type variable `ty_var` of the given kind, first check
    /// if `ty_var` is bound to anything; if so, canonicalize
    /// *that*. Otherwise, create a new canonical variable for
    /// `ty_var`.
    fn canonicalize_ty_var(&mut self, ty_kind: CanonicalTyVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> {
        let infcx = self.infcx.expect("encountered ty-var without infcx");
        let bound_to = infcx.shallow_resolve(ty_var);
        if bound_to != ty_var {
            self.fold_ty(bound_to)
        } else {
            let info = CanonicalVarInfo {
                kind: CanonicalVarKind::Ty(ty_kind),
            };
            let cvar = self.canonical_var(info, ty_var.into());
            self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
        }
    }
}
<commit_msg>canonicalizer.rs: rustfmt<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 "canonicalizer" itself.
//!
//! 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::{
    Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
    SmallCanonicalVarValues,
};
use infer::InferCtxt;
use std::sync::atomic::Ordering;
use ty::fold::{TypeFoldable, TypeFolder};
use ty::subst::Kind;
use ty::{self, CanonicalVar, Lift, List, Ty, TyCtxt, TypeFlags};

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
use smallvec::SmallVec;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    /// Canonicalizes a query value `V`. When we canonicalize a query,
    /// we not only canonicalize unbound inference variables, but we
    /// *also* replace all free regions whatsoever. So for example a
    /// query like `T: Trait<'static>` would be canonicalized to
    ///
    /// ```text
    /// T: Trait<'?0>
    /// ```
    ///
    /// with a mapping M that maps `'?0` to `'static`.
    ///
    /// 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#canonicalizing-the-query
    pub fn canonicalize_query<V>(
        &self,
        value: &V,
        var_values: &mut SmallCanonicalVarValues<'tcx>,
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        self.tcx
            .sess
            .perf_stats
            .queries_canonicalized
            .fetch_add(1, Ordering::Relaxed);

        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: true,
                other_free_regions: true,
            },
            var_values,
        )
    }

    /// Canonicalizes a query *response* `V`. When we canonicalize a
    /// query response, we only canonicalize unbound inference
    /// variables, and we leave other free regions alone. So,
    /// continuing with the example from `canonicalize_query`, if
    /// there was an input query `T: Trait<'static>`, it would have
    /// been canonicalized to
    ///
    /// ```text
    /// T: Trait<'?0>
    /// ```
    ///
    /// with a mapping M that maps `'?0` to `'static`. But if we found that there
    /// exists only one possible impl of `Trait`, and it looks like
    ///
    ///     impl<T> Trait<'static> for T { .. }
    ///
    /// then we would prepare a query result R that (among other
    /// things) includes a mapping to `'?0 := 'static`. When
    /// canonicalizing this query result R, we would leave this
    /// reference to `'static` alone.
    ///
    /// 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#canonicalizing-the-query-result
    pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        let mut var_values = SmallVec::new();
        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: false,
                other_free_regions: false,
            },
            &mut var_values,
        )
    }

    /// A hacky variant of `canonicalize_query` that does not
    /// canonicalize `'static`.  Unfortunately, the existing leak
    /// check treaks `'static` differently in some cases (see also
    /// #33684), so if we are performing an operation that may need to
    /// prove "leak-check" related things, we leave `'static`
    /// alone.
    ///
    /// FIXME(#48536) -- once we have universes, we can remove this and just use
    /// `canonicalize_query`.
    pub fn canonicalize_hr_query_hack<V>(
        &self,
        value: &V,
        var_values: &mut SmallCanonicalVarValues<'tcx>,
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        self.tcx
            .sess
            .perf_stats
            .queries_canonicalized
            .fetch_add(1, Ordering::Relaxed);

        Canonicalizer::canonicalize(
            value,
            Some(self),
            self.tcx,
            CanonicalizeRegionMode {
                static_region: false,
                other_free_regions: true,
            },
            var_values,
        )
    }
}

/// If this flag is true, then all free regions will be replaced with
/// a canonical var. This is used to make queries as generic as
/// possible. For example, the query `F: Foo<'static>` would be
/// canonicalized to `F: Foo<'0>`.
struct CanonicalizeRegionMode {
    static_region: bool,
    other_free_regions: bool,
}

impl CanonicalizeRegionMode {
    fn any(&self) -> bool {
        self.static_region || self.other_free_regions
    }
}

struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    variables: SmallVec<[CanonicalVarInfo; 8]>,
    var_values: &'cx mut SmallCanonicalVarValues<'tcx>,
    // Note that indices is only used once `var_values` is big enough to be
    // heap-allocated.
    indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
    canonicalize_region_mode: CanonicalizeRegionMode,
    needs_canonical_flags: TypeFlags,
}

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

    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
        match *r {
            ty::ReLateBound(..) => {
                // leave bound regions alone
                r
            }

            ty::ReVar(vid) => {
                let r = self.infcx
                    .unwrap()
                    .borrow_region_constraints()
                    .opportunistic_resolve_var(self.tcx, vid);
                let info = CanonicalVarInfo {
                    kind: CanonicalVarKind::Region,
                };
                debug!(
                    "canonical: region var found with vid {:?}, \
                     opportunistically resolved to {:?}",
                    vid, r
                );
                let cvar = self.canonical_var(info, r.into());
                self.tcx().mk_region(ty::ReCanonical(cvar))
            }

            ty::ReStatic => {
                if self.canonicalize_region_mode.static_region {
                    let info = CanonicalVarInfo {
                        kind: CanonicalVarKind::Region,
                    };
                    let cvar = self.canonical_var(info, r.into());
                    self.tcx().mk_region(ty::ReCanonical(cvar))
                } else {
                    r
                }
            }

            ty::ReEarlyBound(..)
            | ty::ReFree(_)
            | ty::ReScope(_)
            | ty::RePlaceholder(..)
            | ty::ReEmpty
            | ty::ReErased => {
                if self.canonicalize_region_mode.other_free_regions {
                    let info = CanonicalVarInfo {
                        kind: CanonicalVarKind::Region,
                    };
                    let cvar = self.canonical_var(info, r.into());
                    self.tcx().mk_region(ty::ReCanonical(cvar))
                } else {
                    r
                }
            }

            ty::ReClosureBound(..) | ty::ReCanonical(_) => {
                bug!("canonical region encountered during canonicalization")
            }
        }
    }

    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
        match t.sty {
            ty::Infer(ty::TyVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::General, t),

            ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Int, t),

            ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(CanonicalTyVarKind::Float, t),

            ty::Infer(ty::FreshTy(_))
            | ty::Infer(ty::FreshIntTy(_))
            | ty::Infer(ty::FreshFloatTy(_)) => {
                bug!("encountered a fresh type during canonicalization")
            }

            ty::Infer(ty::CanonicalTy(_)) => {
                bug!("encountered a canonical type during canonicalization")
            }

            ty::Closure(..)
            | ty::Generator(..)
            | ty::GeneratorWitness(..)
            | ty::Bool
            | ty::Char
            | ty::Int(..)
            | ty::Uint(..)
            | ty::Float(..)
            | ty::Adt(..)
            | ty::Str
            | ty::Error
            | ty::Array(..)
            | ty::Slice(..)
            | ty::RawPtr(..)
            | ty::Ref(..)
            | ty::FnDef(..)
            | ty::FnPtr(_)
            | ty::Dynamic(..)
            | ty::Never
            | ty::Tuple(..)
            | ty::Projection(..)
            | ty::UnnormalizedProjection(..)
            | ty::Foreign(..)
            | ty::Param(..)
            | ty::Opaque(..) => {
                if t.flags.intersects(self.needs_canonical_flags) {
                    t.super_fold_with(self)
                } else {
                    t
                }
            }
        }
    }
}

impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
    /// The main `canonicalize` method, shared impl of
    /// `canonicalize_query` and `canonicalize_response`.
    fn canonicalize<V>(
        value: &V,
        infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        canonicalize_region_mode: CanonicalizeRegionMode,
        var_values: &'cx mut SmallCanonicalVarValues<'tcx>,
    ) -> Canonicalized<'gcx, V>
    where
        V: TypeFoldable<'tcx> + Lift<'gcx>,
    {
        debug_assert!(
            !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS),
            "canonicalizing a canonical value: {:?}",
            value,
        );

        let needs_canonical_flags = if canonicalize_region_mode.any() {
            TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
        } else {
            TypeFlags::KEEP_IN_LOCAL_TCX
        };

        let gcx = tcx.global_tcx();

        // Fast path: nothing that needs to be canonicalized.
        if !value.has_type_flags(needs_canonical_flags) {
            let out_value = gcx.lift(value).unwrap();
            let canon_value = Canonical {
                variables: List::empty(),
                value: out_value,
            };
            return canon_value;
        }

        let mut canonicalizer = Canonicalizer {
            infcx,
            tcx,
            canonicalize_region_mode,
            needs_canonical_flags,
            variables: SmallVec::new(),
            var_values,
            indices: FxHashMap::default(),
        };
        let out_value = value.fold_with(&mut canonicalizer);

        // Once we have canonicalized `out_value`, it should not
        // contain anything that ties it to this inference context
        // anymore, so it should live in the global arena.
        let out_value = gcx.lift(&out_value).unwrap_or_else(|| {
            bug!(
                "failed to lift `{:?}`, canonicalized from `{:?}`",
                out_value,
                value
            )
        });

        let canonical_variables = tcx.intern_canonical_var_infos(&canonicalizer.variables);

        Canonical {
            variables: canonical_variables,
            value: out_value,
        }
    }

    /// Creates a canonical variable replacing `kind` from the input,
    /// or returns an existing variable if `kind` has already been
    /// seen. `kind` is expected to be an unbound variable (or
    /// potentially a free region).
    fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
        let Canonicalizer {
            variables,
            var_values,
            indices,
            ..
        } = self;

        // This code is hot. `variables` and `var_values` are usually small
        // (fewer than 8 elements ~95% of the time). They are SmallVec's to
        // avoid allocations in those cases. We also don't use `indices` to
        // determine if a kind has been seen before until the limit of 8 has
        // been exceeded, to also avoid allocations for `indices`.
        if !var_values.spilled() {
            // `var_values` is stack-allocated. `indices` isn't used yet. Do a
            // direct linear search of `var_values`.
            if let Some(idx) = var_values.iter().position(|&k| k == kind) {
                // `kind` is already present in `var_values`.
                CanonicalVar::new(idx)
            } else {
                // `kind` isn't present in `var_values`. Append it. Likewise
                // for `info` and `variables`.
                variables.push(info);
                var_values.push(kind);
                assert_eq!(variables.len(), var_values.len());

                // If `var_values` has become big enough to be heap-allocated,
                // fill up `indices` to facilitate subsequent lookups.
                if var_values.spilled() {
                    assert!(indices.is_empty());
                    *indices = var_values
                        .iter()
                        .enumerate()
                        .map(|(i, &kind)| (kind, CanonicalVar::new(i)))
                        .collect();
                }
                // The cv is the index of the appended element.
                CanonicalVar::new(var_values.len() - 1)
            }
        } else {
            // `var_values` is large. Do a hashmap search via `indices`.
            *indices.entry(kind).or_insert_with(|| {
                variables.push(info);
                var_values.push(kind);
                assert_eq!(variables.len(), var_values.len());
                CanonicalVar::new(variables.len() - 1)
            })
        }
    }

    /// Given a type variable `ty_var` of the given kind, first check
    /// if `ty_var` is bound to anything; if so, canonicalize
    /// *that*. Otherwise, create a new canonical variable for
    /// `ty_var`.
    fn canonicalize_ty_var(&mut self, ty_kind: CanonicalTyVarKind, ty_var: Ty<'tcx>) -> Ty<'tcx> {
        let infcx = self.infcx.expect("encountered ty-var without infcx");
        let bound_to = infcx.shallow_resolve(ty_var);
        if bound_to != ty_var {
            self.fold_ty(bound_to)
        } else {
            let info = CanonicalVarInfo {
                kind: CanonicalVarKind::Ty(ty_kind),
            };
            let cvar = self.canonical_var(info, ty_var.into());
            self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add problem #17<commit_after>fn to_word_under10(n: uint) -> ~str {
    return match n {
        0 => ~"zero",
        1 => ~"one",
        2 => ~"two",
        3 => ~"three",
        4 => ~"four",
        5 => ~"five",
        6 => ~"six",
        7 => ~"seven",
        8 => ~"eight",
        9 => ~"nine",
        _ => fail
    };
}

fn to_word_under20(n: uint) -> ~str {
    assert n < 20;
    if n < 10 { return to_word_under10(n); }
    return match n {
        10 => ~"ten",
        11 => ~"eleven",
        12 => ~"twelve",
        13 => ~"thirteen",
        14 => ~"fourteen",
        15 => ~"fifteen",
        16 => ~"sixteen",
        17 => ~"seventeen",
        18 => ~"eighteen",
        19 => ~"nineteen",
        _  => fail
    };
}

fn to_word_under100(n: uint) -> ~str {
    assert n < 100;
    if n < 20 { return to_word_under20(n); }

    let prefix = match n / 10 {
        0 | 1 => fail,
        2 => ~"twenty",
        3 => ~"thirty",
        4 => ~"forty",
        5 => ~"fifty",
        6 => ~"sixty",
        7 => ~"seventy",
        8 => ~"eighty",
        9 => ~"ninety",
        _ => fail
    };
    if n % 10 != 0 {
        return prefix + "-" + to_word_under10(n % 10);
    } else {
        return prefix;
    }
}

fn to_word_under1000(n: uint) -> ~str {
    assert n < 1000;
    if n < 100 { return to_word_under100(n); }

    let prefix = to_word_under10(n / 100) + " hundred";
    if n % 100 != 0 {
        return prefix + " and " + to_word_under100(n % 100);
    } else {
        return prefix;
    }
}

fn to_word(n: uint) -> ~str {
    assert n <= 1000;
    if n < 1000 { return to_word_under1000(n); }
    return ~"one thousand";
}

fn main() {
    let mut sum = 0;
    for 1000.timesi |i| {
        let n = i + 1;
        io::println(fmt!("%4u => %s", n, to_word(n)));
        for str::each(to_word(n)) |b| {
            if b != ('-' as u8) && b != (' ' as u8) {
                sum += 1;
            }
        }
    }
    io::println(fmt!("%u", sum));
}<|endoftext|>


<commit_before>extern crate hyper;
extern crate time;

use hyper::Client;
use hyper::header::Connection;
use time::*;
use std::thread;
use std::sync::{Arc, Mutex};

struct Request {
    elapsed_time: f64
}

impl Request{
    fn new(elapsed_time: f64) -> Request{
        Request {
            elapsed_time: elapsed_time,
        }
    }
}

fn main() {
    let requests = Arc::new(Mutex::new(Vec::new()));
    let threads = Arc::new(Mutex::new(Vec::new()));

    for _x in 0..100 {
        println!("Spawning thread: {}", _x);

        let mut client = Client::new();
        let thread_items = requests.clone();

        let handle = thread::spawn(move || {
            for _y in 0..100 {
                println!("Firing requests: {}", _y);

                let start = time::precise_time_s();

                let _res = client.get("http://jacob.uk.com")
                    .header(Connection::close())
                    .send().unwrap();

                let end = time::precise_time_s();

                thread_items.lock().unwrap().push((Request::new(end-start)));
            }
        });

        threads.lock().unwrap().push((handle));
    }

    for t in threads.iter(){
        println!("Hello World");
    }
}
<commit_msg>lock the thread before we unwrap and iterate over it<commit_after>extern crate hyper;
extern crate time;

use hyper::Client;
use hyper::header::Connection;
use time::*;
use std::thread;
use std::sync::{Arc, Mutex};

struct Request {
    elapsed_time: f64
}

impl Request{
    fn new(elapsed_time: f64) -> Request{
        Request {
            elapsed_time: elapsed_time,
        }
    }
}

fn main() {
    let requests = Arc::new(Mutex::new(Vec::new()));
    let threads = Arc::new(Mutex::new(Vec::new()));

    for _x in 0..100 {
        println!("Spawning thread: {}", _x);

        let mut client = Client::new();
        let thread_items = requests.clone();

        let handle = thread::spawn(move || {
            for _y in 0..100 {
                println!("Firing requests: {}", _y);

                let start = time::precise_time_s();

                let _res = client.get("http://jacob.uk.com")
                    .header(Connection::close())
                    .send().unwrap();

                let end = time::precise_time_s();

                thread_items.lock().unwrap().push((Request::new(end-start)));
            }
        });

        threads.lock().unwrap().push((handle));
    }

    for t in threads.lock().unwrap().iter() {
        //error: cannot move out of borrowed content
        //t.join();
    }
}
<|endoftext|>


<commit_before><commit_msg>Basic map generation without numbers<commit_after><|endoftext|>


<commit_before>trait Normalize {
  fn normalize(&self) -> Self;
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Const {
  Data,
  Codata,
}

impl Normalize for Const {
  fn normalize(&self) -> Const {
    *self
  }
}

impl ToString for Const {
  fn to_string(&self) -> String {
    match *self {
      Const::Data => "data".to_string(),
      Const::Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

impl Normalize for Var {
  fn normalize(&self) -> Var {
    self.clone()
  }
}

impl ToString for Var {
  fn to_string(&self) -> String {
    if self.idx == 0 {
      self.name.clone()
    } else {
      self.name.clone() + "@" + &self.idx.to_string()
    }
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    match *self {
      Expr::Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    match *self {
      Expr::Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    match *self {
      Expr::Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    match *self {
      Expr::Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    match *self {
      Expr::App(_, _) => true,
      _ => false,
    }
  }
}

fn constant(c: Const) -> Expr {
  Expr::constant(c)
}
fn var(v: &Var) -> Expr {
  Expr::var(v)
}
fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::lam(var, ty, body)
}
fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::pi(var, ty, body)
}
fn app(f: Expr, arg: Expr) -> Expr {
  Expr::app(f, arg)
}

fn replace(val: &Var, with: &Expr, body: &Expr) -> Expr {
  use Expr::*;
  match *body {
    Const(ref constant) => body.clone(),
    Var(ref var) => {
      if *var == *val {
        with.clone()
      } else {
        body.clone()
      }
    }
    Lam(ref var, ref ty, ref body) => {
      // TODO: Check var == val
      let ty = Box::new(replace(val, with, &ty));
      let body = Box::new(replace(val, with, &body));
      Lam(var.clone(), ty, body)
    }
    Pi(ref var, ref ty, ref body) => {
      // TODO: Check var == val
      let ty = Box::new(replace(val, with, &ty));
      let body = Box::new(replace(val, with, &body));
      Pi(var.clone(), ty, body)
    }
    App(ref f, ref arg) => {
      let f = Box::new(replace(val, with, &f));
      let arg = Box::new(replace(val, with, &arg));
      App(f, arg)
    }
  }
}

impl Normalize for Expr {
  fn normalize(&self) -> Expr {
    use Expr::*;
    // println!("normalize {}", self.to_string());
    match *self {
      Const(ref constant) => Const(constant.normalize()),
      Var(ref var) => Var(var.normalize()),
      Lam(ref var, ref ty, ref body) => {
        let l = &Lam(var.normalize(),
                     Box::new(ty.normalize()),
                     Box::new(body.normalize()));
        l.clone()
      }
      Pi(ref var, ref ty, ref body) => {
        let p = &Pi(var.normalize(),
                    Box::new(ty.normalize()),
                    Box::new(body.normalize()));
        p.clone()
      }
      App(ref f, ref arg) => {
        let f = f.normalize();
        let arg = arg.normalize();
        if let Lam(var, ty, body) = f {
          replace(&var, &arg, &body)
        } else if let Pi(var, ty, body) = f {
          replace(&var, &arg, &body)
        } else {
          panic!("f isn't a function {}", f.to_string())
        }
      }
    }
  }
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        "(".to_string() + &var.to_string() + " : " + &ty.to_string() + ") -> " +
        &body.to_string()
      }
      Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + " : " + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  println!("{}", id.normalize().to_string());
  let apply_int = app(id.clone(), var(&Var::new("int", 0)));
  println!("{}", apply_int.to_string());
  println!("{}", apply_int.normalize().to_string());
  let apply_id = app(app(id, var(&Var::new("int", 0))), var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
  println!("{}", apply_id.normalize().to_string());
}

#[test]
fn test_to_string() {
  let codata = Const::Codata;
  println!("{}", codata.to_string());
  assert_eq!("codata", codata.to_string());
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  assert_eq!("x", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  assert_eq!("forall (a : data) -> (x : a) -> x", id.to_string());
  let apply_id = app(app(id, var(&Var::new("int", 0))), var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
  assert_eq!("(forall (a : data) -> (x : a) -> x) int 1",
             apply_id.to_string());
}
<commit_msg>Begin testing applying id to itself.<commit_after>trait Normalize {
  fn normalize(&self) -> Self;
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Const {
  Data,
  Codata,
}

impl Normalize for Const {
  fn normalize(&self) -> Const {
    *self
  }
}

impl ToString for Const {
  fn to_string(&self) -> String {
    match *self {
      Const::Data => "data".to_string(),
      Const::Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }

  pub fn shift(&self) -> Var {
    Var {
      name: self.name.clone(),
      idx: self.idx + 1,
    }
  }
}

impl Normalize for Var {
  fn normalize(&self) -> Var {
    self.clone()
  }
}

impl ToString for Var {
  fn to_string(&self) -> String {
    if self.name.len() == 0 {
      "".to_string()
    } else if self.idx == 0 {
      self.name.clone()
    } else {
      self.name.clone() + "@" + &self.idx.to_string()
    }
  }
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    match *self {
      Expr::Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    match *self {
      Expr::Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    match *self {
      Expr::Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    match *self {
      Expr::Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    match *self {
      Expr::App(_, _) => true,
      _ => false,
    }
  }
}

fn constant(c: Const) -> Expr {
  Expr::constant(c)
}
fn var(v: &Var) -> Expr {
  Expr::var(v)
}
fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::lam(var, ty, body)
}
fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::pi(var, ty, body)
}
fn app(f: Expr, arg: Expr) -> Expr {
  Expr::app(f, arg)
}

fn replace(val: &Var, with: &Expr, body: &Expr) -> Expr {
  use Expr::*;
  match *body {
    Const(ref constant) => body.clone(),
    Var(ref var) => {
      if *var == *val {
        with.clone()
      } else {
        body.clone()
      }
    }
    Lam(ref var, ref ty, ref body) => {
      // TODO: Check var == val
      // let val = if *var == *val {
      //   &val
      // } else {
      //   &val
      // };
      let ty = Box::new(replace(val, with, &ty));
      let body = Box::new(replace(val, with, &body));
      Lam(var.clone(), ty, body)
    }
    Pi(ref var, ref ty, ref body) => {
      // TODO: Check var == val
      let ty = Box::new(replace(val, with, &ty));
      let body = Box::new(replace(val, with, &body));
      Pi(var.clone(), ty, body)
    }
    App(ref f, ref arg) => {
      let f = Box::new(replace(val, with, &f));
      let arg = Box::new(replace(val, with, &arg));
      App(f, arg)
    }
  }
}

impl Normalize for Expr {
  fn normalize(&self) -> Expr {
    use Expr::*;
    // println!("normalize {}", self.to_string());
    match *self {
      Const(ref constant) => Const(constant.normalize()),
      Var(ref var) => Var(var.normalize()),
      Lam(ref var, ref ty, ref body) => {
        let l = &Lam(var.normalize(),
                     Box::new(ty.normalize()),
                     Box::new(body.normalize()));
        l.clone()
      }
      Pi(ref var, ref ty, ref body) => {
        let p = &Pi(var.normalize(),
                    Box::new(ty.normalize()),
                    Box::new(body.normalize()));
        p.clone()
      }
      App(ref f, ref arg) => {
        let f = f.normalize();
        let arg = arg.normalize();
        if let Lam(var, ty, body) = f {
          replace(&var, &arg, &body)
        } else if let Pi(var, ty, body) = f {
          replace(&var, &arg, &body)
        } else {
          panic!("f isn't a function {}", f.to_string())
        }
      }
    }
  }
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        let vars = var.to_string();
        if vars.len() == 0 {
          ty.to_string() + " -> " + &body.to_string()
        } else {
          "(".to_string() + &var.to_string() + " : " + &ty.to_string() +
          ") -> " + &body.to_string()
        }
      }
      Pi(ref var, ref ty, ref body) => {
        let vars = var.to_string();
        if vars.len() == 0 {
          "forall (".to_string() + &ty.to_string() + ") -> " + &body.to_string()
        } else {
          "forall (".to_string() + &var.to_string() + " : " +
          &ty.to_string() + ") -> " + &body.to_string()
        }
      }
      App(ref f, ref arg) => {
        let mut s = String::new();
        if f.is_lam() || f.is_pi() {
          s.push('(');
          s.push_str(&f.to_string()[..]);
          s.push(')');
        } else {
          s.push_str(&f.to_string()[..]);
        }
        s.push(' ');
        if arg.is_lam() || arg.is_pi() {
          s.push('(');
          s.push_str(&arg.to_string()[..]);
          s.push(')');
        } else {
          s.push_str(&arg.to_string()[..]);
        }
        // + " ".to_string() + (if arg.is_lam() || arg.is_pi() {
        //   "(".to_string() + &arg.to_string() + ")"
        // } else {
        //   &arg.to_string()
        // })
        s
      }
    }
  }
}

fn main() {
  // println!("{}", Const::Data.to_string());
  // let a = Var::new("a", 0);
  // let x = Var::new("x", 0);
  // let expra = var(&a);
  // let exprx = var(&x);
  // println!("{}", x.to_string());
  // let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  // println!("{}", id.to_string());
  // println!("{}", id.normalize().to_string());
  // let apply_int = app(id.clone(), var(&Var::new("int", 0)));
  // println!("{}", apply_int.to_string());
  // println!("{}", apply_int.normalize().to_string());
  // let apply_id = app(app(id, var(&Var::new("int", 0))), var(&Var::new("1", 0)));
  // println!("{}", apply_id.to_string());
  // println!("{}", apply_id.normalize().to_string());

  // (   \(id : forall (a : *) -> a -> a)
  // ->  id (forall (a : *) -> a -> a) id  -- Apply the identity function to itself
  // )
  //
  // -- id
  // (\(a : *) -> \(x : a) -> x)

  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let id = Var::new("id", 0);
  let unused = Var::new("", 0);
  let ty = pi(a.clone(),
              constant(Const::Data),
              lam(unused, Expr::var(&a), Expr::var(&a)));
  println!("{}", ty.to_string());
  let id_impl = pi(a.clone(),
                   constant(Const::Data),
                   lam(x.clone(), Expr::var(&a), Expr::var(&x)));
  println!("{}", id_impl.to_string());
  let id2 = lam(id.clone(),
                ty.clone(),
                app(app(Expr::var(&id.clone()), ty.clone()),
                    Expr::var(&id.clone())));
  println!("{}", id2.to_string());
  let id2app = app(lam(id.clone(),
                       ty.clone(),
                       app(app(Expr::var(&id.clone()), ty.clone()),
                           Expr::var(&id.clone()))),
                   id_impl.clone());
  println!("{}", id2app.to_string());
  println!("{}", id2app.normalize().to_string());
}

#[test]
fn test_to_string() {
  let codata = Const::Codata;
  println!("{}", codata.to_string());
  assert_eq!("codata", codata.to_string());
  let a = Var::new("a", 0);
  let x = Var::new("x", 0);
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  assert_eq!("x", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  assert_eq!("forall (a : data) -> (x : a) -> x", id.to_string());
  let apply_id = app(app(id, var(&Var::new("int", 0))), var(&Var::new("1", 0)));
  println!("{}", apply_id.to_string());
  assert_eq!("(forall (a : data) -> (x : a) -> x) int 1",
             apply_id.to_string());
}
<|endoftext|>


<commit_before>// Copyright 2016 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![recursion_limit="300"]
#![feature(const_fn)]

extern crate sdl2;
extern crate image;
extern crate time;
extern crate byteorder;
extern crate serde_json;
extern crate openssl;
extern crate hyper;
extern crate flate2;
extern crate rand;
extern crate rustc_serialize;
extern crate cgmath;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate collision;
pub extern crate steven_blocks;
extern crate steven_shared as shared;

#[macro_use]
pub mod macros;

pub mod ecs;
pub mod protocol;
pub mod format;
pub mod nbt;
pub mod item;
pub mod gl;
pub mod types;
pub mod resources;
pub mod render;
pub mod ui;
pub mod screen;
pub mod settings;
#[macro_use]
pub mod console;
pub mod server;
pub mod world;
pub mod chunk_builder;
pub mod auth;
pub mod model;
pub mod entity;

use std::sync::{Arc, RwLock, Mutex};
use std::marker::PhantomData;
use std::thread;
use std::sync::mpsc;

const CL_BRAND: console::CVar<String> = console::CVar {
    ty: PhantomData,
    name: "cl_brand",
    description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \
                  \"Vanilla\"",
    mutable: false,
    serializable: false,
    default: &|| "Steven".to_owned(),
};

pub struct Game {
    renderer: render::Renderer,
    screen_sys: screen::ScreenSystem,
    resource_manager: Arc<RwLock<resources::Manager>>,
    console: Arc<Mutex<console::Console>>,
    should_close: bool,

    server: server::Server,
    focused: bool,
    chunk_builder: chunk_builder::ChunkBuilder,

    connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
}

impl Game {
    pub fn connect_to(&mut self, address: &str) {
        let (tx, rx) = mpsc::channel();
        self.connect_reply = Some(rx);
        let address = address.to_owned();
        let resources = self.resource_manager.clone();
        let console = self.console.clone();
        thread::spawn(move || {
            tx.send(server::Server::connect(resources, console, &address)).unwrap();
        });
    }

    pub fn tick(&mut self, delta: f64) {
        if !self.server.is_connected() {
            self.renderer.camera.yaw += 0.005 * delta;
            if self.renderer.camera.yaw > ::std::f64::consts::PI * 2.0 {
                self.renderer.camera.yaw = 0.0;
            }
        }

        if let Some(disconnect_reason) = self.server.disconnect_reason.take() {
            self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                Some(disconnect_reason)
            )));
        }
        if !self.server.is_connected() {
            self.focused = false;
        }

        let mut clear_reply = false;
        if let Some(ref recv) = self.connect_reply {
            if let Ok(server) = recv.try_recv() {
                clear_reply = true;
                match server {
                    Ok(val) => {
                        self.screen_sys.pop_screen();
                        self.focused = true;
                        self.server.remove(&mut self.renderer);
                        self.server = val;
                    },
                    Err(err) => {
                        let msg = match err {
                            protocol::Error::Disconnect(val) => val,
                            err => {
                                let mut msg = format::TextComponent::new(&format!("{}", err));
                                msg.modifier.color = Some(format::Color::Red);
                                format::Component::Text(msg)
                            },
                        };
                        self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                            Some(msg)
                        )));
                    }
                }
            }
        }
        if clear_reply {
            self.connect_reply = None;
        }
    }
}

fn main() {
    let con = Arc::new(Mutex::new(console::Console::new()));
    {
        let mut con = con.lock().unwrap();
        con.register(CL_BRAND);
        auth::register_vars(&mut con);
        settings::register_vars(&mut con);
        con.load_config();
        con.save_config();
    }

    let proxy = console::ConsoleProxy::new(con.clone());

    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::Trace);
        Box::new(proxy)
    }).unwrap();

    info!("test compile");

    let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
    {
        resource_manager.write().unwrap().tick();
    }

    let sdl = sdl2::init().unwrap();
    let sdl_video = sdl.video().unwrap();

    sdl_video.gl_set_swap_interval(1);

    let window = sdl2::video::WindowBuilder::new(&sdl_video, "Steven", 854, 480)
                            .opengl()
                            .resizable()
                            .build()
                            .expect("Could not create sdl window.");
    let gl_attr = sdl_video.gl_attr();
    gl_attr.set_stencil_size(0);
    gl_attr.set_depth_size(24);
    gl_attr.set_context_major_version(3);
    gl_attr.set_context_minor_version(2);
    gl_attr.set_context_profile(sdl2::video::GLProfile::Core);

    let gl_context = window.gl_create_context().unwrap();
    window.gl_make_current(&gl_context).expect("Could not set current context.");

    gl::init(&sdl_video);

    let renderer = render::Renderer::new(resource_manager.clone());
    let mut ui_container = ui::Container::new();

    let mut last_frame = time::now();
    let frame_time = (time::Duration::seconds(1).num_nanoseconds().unwrap() as f64) / 60.0;

    let mut screen_sys = screen::ScreenSystem::new();
    screen_sys.add_screen(Box::new(screen::Login::new(con.clone())));

    let textures = renderer.get_textures();
    let mut game = Game {
        server: server::Server::dummy_server(resource_manager.clone(), con.clone()),
        focused: false,
        renderer: renderer,
        screen_sys: screen_sys,
        resource_manager: resource_manager.clone(),
        console: con,
        should_close: false,
        chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
        connect_reply: None,
    };
    game.renderer.camera.pos = cgmath::Point3::new(0.5, 13.2, 0.5);

    let mut events = sdl.event_pump().unwrap();
    while !game.should_close {
        let version = {
            let mut res = game.resource_manager.write().unwrap();
            res.tick();
            res.version()
        };

        let now = time::now();
        let diff = now - last_frame;
        last_frame = now;
        let delta = (diff.num_nanoseconds().unwrap() as f64) / frame_time;
        let (width, height) = window.drawable_size();

        game.tick(delta);
        game.server.tick(&mut game.renderer, delta);

        game.renderer.update_camera(width, height);
        game.server.world.compute_render_list(&mut game.renderer);
        game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, version);

        game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
        game.console
            .lock()
            .unwrap()
            .tick(&mut ui_container, &mut game.renderer, delta, width as f64);
        ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
        game.renderer.tick(&mut game.server.world, delta, width, height);

        window.gl_swap_window();

        for event in events.poll_iter() {
            handle_window_event(&window, &mut game, &mut ui_container, event)
        }
    }
}

fn handle_window_event(window: &sdl2::video::Window,
                       game: &mut Game,
                       ui_container: &mut ui::Container,
                       event: sdl2::event::Event) {
    use sdl2::event::Event;
    use sdl2::keyboard::Keycode;
    use sdl2::mouse::Mouse;
    use std::f64::consts::PI;

    let mouse = window.subsystem().sdl().mouse();

    match event {
        Event::Quit{..} => game.should_close = true,

        Event::MouseMotion{x, y, xrel, yrel, ..} => {
            let (width, height) = window.size();
            if game.focused {
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                if let Some(player) = game.server.player {
                    let s = 2000.0 + 0.01;
                    let (rx, ry) = (xrel as f64 / s, yrel as f64 / s);
                    let rotation = game.server.entities.get_component_mut(player, game.server.rotation).unwrap();
                    rotation.yaw -= rx;
                    rotation.pitch -= ry;
                    if rotation.pitch < (PI/2.0) + 0.01 {
                        rotation.pitch = (PI/2.0) + 0.01;
                    }
                    if rotation.pitch > (PI/2.0)*3.0 - 0.01 {
                        rotation.pitch = (PI/2.0)*3.0 - 0.01;
                    }
                }
            } else {
                if mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(false);
                }
                ui_container.hover_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseButtonUp{mouse_btn: Mouse::Left, x, y, ..} => {
            let (width, height) = window.size();

            if game.server.is_connected() && !game.focused && !game.screen_sys.is_current_closable() {
                game.focused = true;
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                return;
            }
            if !game.focused {
                if mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(false);
                }
                ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseWheel{x, y, ..} => {
            game.screen_sys.on_scroll(x as f64, y as f64);
        }
        Event::KeyUp{keycode: Some(Keycode::Escape), ..} => {
            if game.focused {
                mouse.set_relative_mouse_mode(false);
                game.focused = false;
                game.screen_sys.replace_screen(Box::new(screen::SettingsMenu::new(game.console.clone(), true)));
            } else if game.screen_sys.is_current_closable() {
                mouse.set_relative_mouse_mode(true);
                game.focused = true;
                game.screen_sys.pop_screen();
            }
        }
        Event::KeyDown{keycode: Some(Keycode::Backquote), ..} => {
            game.console.lock().unwrap().toggle();
        }
        Event::KeyDown{keycode: Some(key), ..} => {
            if game.focused {
                let console = game.console.lock().unwrap();
                if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
                    game.server.key_press(true, steven_key);
                }
            } else {
                ui_container.key_press(game, key, true);
            }
        }
        Event::KeyUp{keycode: Some(key), ..} => {
            if game.focused {
                let console = game.console.lock().unwrap();
                if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
                    game.server.key_press(false, steven_key);
                }
            } else {
                ui_container.key_press(game, key, false);
            }
        }
        Event::TextInput{text, ..} => {
            if !game.focused {
                for c in text.chars() {
                    ui_container.key_type(game, c);
                }
            }
        }
        _ => (),
    }
}
<commit_msg>Updat1<commit_after>// Copyright 2016 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![recursion_limit="300"]
#![feature(const_fn)]

extern crate sdl2;
extern crate image;
extern crate time;
extern crate byteorder;
extern crate serde_json;
extern crate openssl;
extern crate hyper;
extern crate flate2;
extern crate rand;
extern crate rustc_serialize;
extern crate cgmath;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;
extern crate collision;
pub extern crate steven_blocks;
extern crate steven_shared as shared;

#[macro_use]
pub mod macros;

pub mod ecs;
pub mod protocol;
pub mod format;
pub mod nbt;
pub mod item;
pub mod gl;
pub mod types;
pub mod resources;
pub mod render;
pub mod ui;
pub mod screen;
pub mod settings;
#[macro_use]
pub mod console;
pub mod server;
pub mod world;
pub mod chunk_builder;
pub mod auth;
pub mod model;
pub mod entity;

use std::sync::{Arc, RwLock, Mutex};
use std::marker::PhantomData;
use std::thread;
use std::sync::mpsc;

const CL_BRAND: console::CVar<String> = console::CVar {
    ty: PhantomData,
    name: "cl_brand",
    description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \
                  \"Vanilla\"",
    mutable: false,
    serializable: false,
    default: &|| "Steven".to_owned(),
};

pub struct Game {
    renderer: render::Renderer,
    screen_sys: screen::ScreenSystem,
    resource_manager: Arc<RwLock<resources::Manager>>,
    console: Arc<Mutex<console::Console>>,
    should_close: bool,

    server: server::Server,
    focused: bool,
    chunk_builder: chunk_builder::ChunkBuilder,

    connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
}

impl Game {
    pub fn connect_to(&mut self, address: &str) {
        let (tx, rx) = mpsc::channel();
        self.connect_reply = Some(rx);
        let address = address.to_owned();
        let resources = self.resource_manager.clone();
        let console = self.console.clone();
        thread::spawn(move || {
            tx.send(server::Server::connect(resources, console, &address)).unwrap();
        });
    }

    pub fn tick(&mut self, delta: f64) {
        if !self.server.is_connected() {
            self.renderer.camera.yaw += 0.005 * delta;
            if self.renderer.camera.yaw > ::std::f64::consts::PI * 2.0 {
                self.renderer.camera.yaw = 0.0;
            }
        }

        if let Some(disconnect_reason) = self.server.disconnect_reason.take() {
            self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                Some(disconnect_reason)
            )));
        }
        if !self.server.is_connected() {
            self.focused = false;
        }

        let mut clear_reply = false;
        if let Some(ref recv) = self.connect_reply {
            if let Ok(server) = recv.try_recv() {
                clear_reply = true;
                match server {
                    Ok(val) => {
                        self.screen_sys.pop_screen();
                        self.focused = true;
                        self.server.remove(&mut self.renderer);
                        self.server = val;
                    },
                    Err(err) => {
                        let msg = match err {
                            protocol::Error::Disconnect(val) => val,
                            err => {
                                let mut msg = format::TextComponent::new(&format!("{}", err));
                                msg.modifier.color = Some(format::Color::Red);
                                format::Component::Text(msg)
                            },
                        };
                        self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
                            Some(msg)
                        )));
                    }
                }
            }
        }
        if clear_reply {
            self.connect_reply = None;
        }
    }
}

fn main() {
    let con = Arc::new(Mutex::new(console::Console::new()));
    {
        let mut con = con.lock().unwrap();
        con.register(CL_BRAND);
        auth::register_vars(&mut con);
        settings::register_vars(&mut con);
        con.load_config();
        con.save_config();
    }

    let proxy = console::ConsoleProxy::new(con.clone());

    log::set_logger(|max_log_level| {
        max_log_level.set(log::LogLevelFilter::Trace);
        Box::new(proxy)
    }).unwrap();

    info!("test compi");

    let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
    {
        resource_manager.write().unwrap().tick();
    }

    let sdl = sdl2::init().unwrap();
    let sdl_video = sdl.video().unwrap();

    sdl_video.gl_set_swap_interval(1);

    let window = sdl2::video::WindowBuilder::new(&sdl_video, "Steven", 854, 480)
                            .opengl()
                            .resizable()
                            .build()
                            .expect("Could not create sdl window.");
    let gl_attr = sdl_video.gl_attr();
    gl_attr.set_stencil_size(0);
    gl_attr.set_depth_size(24);
    gl_attr.set_context_major_version(3);
    gl_attr.set_context_minor_version(2);
    gl_attr.set_context_profile(sdl2::video::GLProfile::Core);

    let gl_context = window.gl_create_context().unwrap();
    window.gl_make_current(&gl_context).expect("Could not set current context.");

    gl::init(&sdl_video);

    let renderer = render::Renderer::new(resource_manager.clone());
    let mut ui_container = ui::Container::new();

    let mut last_frame = time::now();
    let frame_time = (time::Duration::seconds(1).num_nanoseconds().unwrap() as f64) / 60.0;

    let mut screen_sys = screen::ScreenSystem::new();
    screen_sys.add_screen(Box::new(screen::Login::new(con.clone())));

    let textures = renderer.get_textures();
    let mut game = Game {
        server: server::Server::dummy_server(resource_manager.clone(), con.clone()),
        focused: false,
        renderer: renderer,
        screen_sys: screen_sys,
        resource_manager: resource_manager.clone(),
        console: con,
        should_close: false,
        chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
        connect_reply: None,
    };
    game.renderer.camera.pos = cgmath::Point3::new(0.5, 13.2, 0.5);

    let mut events = sdl.event_pump().unwrap();
    while !game.should_close {
        let version = {
            let mut res = game.resource_manager.write().unwrap();
            res.tick();
            res.version()
        };

        let now = time::now();
        let diff = now - last_frame;
        last_frame = now;
        let delta = (diff.num_nanoseconds().unwrap() as f64) / frame_time;
        let (width, height) = window.drawable_size();

        game.tick(delta);
        game.server.tick(&mut game.renderer, delta);

        game.renderer.update_camera(width, height);
        game.server.world.compute_render_list(&mut game.renderer);
        game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, version);

        game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
        game.console
            .lock()
            .unwrap()
            .tick(&mut ui_container, &mut game.renderer, delta, width as f64);
        ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
        game.renderer.tick(&mut game.server.world, delta, width, height);

        window.gl_swap_window();

        for event in events.poll_iter() {
            handle_window_event(&window, &mut game, &mut ui_container, event)
        }
    }
}

fn handle_window_event(window: &sdl2::video::Window,
                       game: &mut Game,
                       ui_container: &mut ui::Container,
                       event: sdl2::event::Event) {
    use sdl2::event::Event;
    use sdl2::keyboard::Keycode;
    use sdl2::mouse::Mouse;
    use std::f64::consts::PI;

    let mouse = window.subsystem().sdl().mouse();

    match event {
        Event::Quit{..} => game.should_close = true,

        Event::MouseMotion{x, y, xrel, yrel, ..} => {
            let (width, height) = window.size();
            if game.focused {
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                if let Some(player) = game.server.player {
                    let s = 2000.0 + 0.01;
                    let (rx, ry) = (xrel as f64 / s, yrel as f64 / s);
                    let rotation = game.server.entities.get_component_mut(player, game.server.rotation).unwrap();
                    rotation.yaw -= rx;
                    rotation.pitch -= ry;
                    if rotation.pitch < (PI/2.0) + 0.01 {
                        rotation.pitch = (PI/2.0) + 0.01;
                    }
                    if rotation.pitch > (PI/2.0)*3.0 - 0.01 {
                        rotation.pitch = (PI/2.0)*3.0 - 0.01;
                    }
                }
            } else {
                if mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(false);
                }
                ui_container.hover_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseButtonUp{mouse_btn: Mouse::Left, x, y, ..} => {
            let (width, height) = window.size();

            if game.server.is_connected() && !game.focused && !game.screen_sys.is_current_closable() {
                game.focused = true;
                if !mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(true);
                }
                return;
            }
            if !game.focused {
                if mouse.relative_mouse_mode() {
                    mouse.set_relative_mouse_mode(false);
                }
                ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64);
            }
        }
        Event::MouseWheel{x, y, ..} => {
            game.screen_sys.on_scroll(x as f64, y as f64);
        }
        Event::KeyUp{keycode: Some(Keycode::Escape), ..} => {
            if game.focused {
                mouse.set_relative_mouse_mode(false);
                game.focused = false;
                game.screen_sys.replace_screen(Box::new(screen::SettingsMenu::new(game.console.clone(), true)));
            } else if game.screen_sys.is_current_closable() {
                mouse.set_relative_mouse_mode(true);
                game.focused = true;
                game.screen_sys.pop_screen();
            }
        }
        Event::KeyDown{keycode: Some(Keycode::Backquote), ..} => {
            game.console.lock().unwrap().toggle();
        }
        Event::KeyDown{keycode: Some(key), ..} => {
            if game.focused {
                let console = game.console.lock().unwrap();
                if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
                    game.server.key_press(true, steven_key);
                }
            } else {
                ui_container.key_press(game, key, true);
            }
        }
        Event::KeyUp{keycode: Some(key), ..} => {
            if game.focused {
                let console = game.console.lock().unwrap();
                if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
                    game.server.key_press(false, steven_key);
                }
            } else {
                ui_container.key_press(game, key, false);
            }
        }
        Event::TextInput{text, ..} => {
            if !game.focused {
                for c in text.chars() {
                    ui_container.key_type(game, c);
                }
            }
        }
        _ => (),
    }
}
<|endoftext|>


<commit_before><commit_msg>Add new example file_info<commit_after>extern crate zip;

use std::fs;

fn main() {
    std::process::exit(real_main());
}

fn real_main() -> i32 {
    let args: Vec<_> = std::env::args().collect();
    if args.len() < 2 {
        println!("Usage: {} <filename>", args[0]);
        return 1;
    }
    let fname = std::path::Path::new(&*args[1]);
    let file = fs::File::open(&fname).unwrap();

    let mut archive = zip::ZipArchive::new(file).unwrap();

    for i in 0..archive.len() {
        let file = archive.by_index(i).unwrap();
        let outpath = file.sanitized_name();

        {
            let comment = file.comment();
            if !comment.is_empty() {
                println!("Entry {} comment: {}", i, comment);
            }
        }

        if (&*file.name()).ends_with('/') {
            println!("Entry {} is a directory with name \"{}\"", i, outpath.as_path().display());
        } else {
            println!("Entry {} is a file with name \"{}\" ({} bytes)", i, outpath.as_path().display(), file.size());
        }
    }
    return 0;
}
<|endoftext|>


<commit_before><commit_msg>Adds Rust solution for #006<commit_after><|endoftext|>


<commit_before><commit_msg>Add code documentation to shell::completer<commit_after><|endoftext|>


<commit_before><commit_msg>Add remaining docs for Store.<commit_after><|endoftext|>


<commit_before><commit_msg>tests<commit_after>use super::*;

#[test]
fn queue() {
	let mut q = Queue::new();
	assert_eq!(q.queue("hello"), Ok(1));
}

#[test]
fn dequeue() {
	let mut q = Queue::new();
	q.queue("hello").unwrap();
	assert_eq!(q.dequeue(), Some("hello"));
}

#[test]
fn no_capacity() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.capacity(), None);
}

#[test]
fn some_capacity() {
	let q: Queue<u8> = Queue::with_capacity(12);
	assert_eq!(q.capacity(), Some(12));
}

#[test]
fn queue_full_capacity() {
	let mut q: Queue<u8> = Queue::with_capacity(0);
	assert_eq!(q.queue(3), Err(()));
}

#[test]
fn peek_at_empty() {
	let q: Queue<u8> = Queue::with_capacity(1);
	assert_eq!(q.peek(), None);
}

#[test]
fn peek_at_something() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	assert_eq!(q.peek(), Some(1));
}

#[test]
fn no_len() {
	let q: Queue<u8> = Queue::new();
	assert_eq!(q.len(), 0);
}

#[test]
fn some_len() {
	let mut q = Queue::new();
	q.queue(1).unwrap();
	q.queue(2).unwrap();
	assert_eq!(q.len(), 2);
}
<|endoftext|>


<commit_before><commit_msg>Added a function to QuadTree to get objects that have been inserted<commit_after><|endoftext|>


<commit_before><commit_msg>Add `alternative_names.rs` example<commit_after>#[macro_use(o,slog_log,slog_trace,slog_debug,slog_info,slog_warn,slog_error,slog_crit)]
extern crate slog;

extern crate slog_term;

use slog::drain::IntoLogger;

fn main() {
    let log = slog_term::stderr().into_logger(o!());

    slog_trace!(log, "logging a trace message");
    slog_debug!(log, "debug values", "x" => 1, "y" => -1);
    slog_info!(log, "some interesting info", "where" => "right here");
    slog_warn!(log, "be cautious!", "why" => "you never know...");
    slog_error!(log, "something's wrong", "type" => "unknown");
    slog_crit!(log, "abandoning test");
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for #21562<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.

#![feature(core)]

extern crate core;
use core::marker::Sync;

static SARRAY: [i32; 1] = [11];

struct MyStruct {
    pub arr: *const [i32],
}
unsafe impl Sync for MyStruct {}

static mystruct: MyStruct = MyStruct {
    arr: &SARRAY
};

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Rustify nvpairs.h for Tedsta<commit_after>enum DataType {
    Unknown = 0,
    Boolean,
    Byte,
    Int16,
    Uint16,
    Int32,
    Uint32,
    Int64,
    Uint64,
    String, // TODO: What to name this string type?
    ByteArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Int64Array,
    Uint64Array,
    StringArray,
    Hrtime,
    Nvlist, // TODO: What to name this ?
    NvlistArray,
    BooleanValue,
    Int8,
    Uint8,
    BooleanArray,
    Int8Array,
    Uint8Array
}

struct NvPair {
    nvp_size:       i32, // size of this nvpair
    nvp_name_sz:    i16, // length of name string
    nvp_reserve:    i16, // not used
    nvp_value_elem: i32, // number of elements for array types
    nvp_type:       DataType, // type of value
    // name string
    // aligned ptr array for string arrays
    // aligned array of data for value
}

// nvlist header
struct NvList {
    nvl_version: i32
    nvl_nvflag:  u32 // persistent flags
    nvl_priv:    u64 // ptr to private data if not packed
    nvl_flag:    u32
    nvl_pad:     i32 // currently not used, for alignment
}

// nvp implementation version
const NV_VERSION: i32 = 0;

// nvlist pack encoding
const NV_ENCODE_NATIVE: u8 = 0;
const NV_ENCODE_XDR:    u8 = 1;

// nvlist persistent unique name flags, stored in nvl_nvflags
const NV_UNIQUE_NAME:      u32 = 0x1;
const NV_UNIQUE_NAME_TYPE: u32 = 0x2;

// nvlist lookup pairs related flags
const NV_FLAG_NOENTOK: isize = 0x1;

/* What to do about these macros?
// convenience macros
#define NV_ALIGN(x)     (((ulong_t)(x) + 7ul) & ~7ul)
#define NV_ALIGN4(x)        (((x) + 3) & ~3)

#define NVP_SIZE(nvp)       ((nvp)->nvp_size)
#define NVP_NAME(nvp)       ((char *)(nvp) + sizeof (nvpair_t))
#define NVP_TYPE(nvp)       ((nvp)->nvp_type)
#define NVP_NELEM(nvp)      ((nvp)->nvp_value_elem)
#define NVP_VALUE(nvp)      ((char *)(nvp) + NV_ALIGN(sizeof (nvpair_t) \
                + (nvp)->nvp_name_sz))

#define NVL_VERSION(nvl)    ((nvl)->nvl_version)
#define NVL_SIZE(nvl)       ((nvl)->nvl_size)
#define NVL_FLAG(nvl)       ((nvl)->nvl_flag)
*/

// NV allocator framework
struct NvAllocOps;

struct NvAlloc<> {
    nva_ops: &'static NvAllocOps,
    nva_arg: Any, // This was a void pointer type.
                  // Not sure if Any is the correct type.
}

struct NvAllocOps {
    int (*nv_ao_init)(nv_alloc_t *, __va_list);
    void (*nv_ao_fini)(nv_alloc_t *);
    void *(*nv_ao_alloc)(nv_alloc_t *, size_t);
    void (*nv_ao_free)(nv_alloc_t *, void *, size_t);
    void (*nv_ao_reset)(nv_alloc_t *);
}
<|endoftext|>


<commit_before><commit_msg>docs(examples): add hello world<commit_after>use rocks::prelude::*;

fn main() {
    let opt = Options::default().map_db_options(|db_opt| db_opt.create_if_missing(true));

    let db = DB::open(opt, "./data").unwrap();

    assert!(db.put(WriteOptions::default_instance(), b"hello", b"world").is_ok());
    match db.get(ReadOptions::default_instance(), b"hello") {
        Ok(ref value) => println!("hello: {:?}", value),
        Err(e) => eprintln!("error: {}", e),
    }
    let _ = db.delete(&WriteOptions::default(), b"hello").unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Add an example that instantly removes the port it added.<commit_after>use std::net::SocketAddrV4;
use std::env;

extern crate igd;

fn main() {
    match igd::search_gateway() {
        Err(ref err) => match *err {
            igd::SearchError::IoError(ref ioe) => println!("IoError: {}", ioe),
            _ => println!("{:?}", err),
        },
        Ok(gateway) => {
            let args: Vec<_> = env::args().collect();
            if args.len() != 4 {
                println!("Usage: add_remove <local_ip> <local_port> <remote_port>");
                return;
            }
            let local_ip = args[1].parse().expect("Invalid IP address");
            let local_port = args[2].parse().expect("Invalid local port");
            let remote_port = args[3].parse().expect("Invalid remote port");

            let local_addr = SocketAddrV4::new(local_ip, local_port);

            match gateway.add_port(igd::PortMappingProtocol::TCP, remote_port,
                                local_addr, 60, "crust") {
                Err(ref err) => println!("{:?}", err),
                Ok(()) => {
                    println!("AddPortMapping successful.");
                    match gateway.remove_port(igd::PortMappingProtocol::TCP, remote_port) {
                        Err(ref err) => println!("Error removing: {:?}", err),
                        Ok(_) => println!("DeletePortMapping successful."),
                    }
                },
            }
        },
    }
}
<|endoftext|>


<commit_before>use std::str::FromStr;
use std::ascii::AsciiExt;

bitflags! {
    flags Flags: u8 {
        const REQUIRED   = 0b00000001,
        const MULTIPLE   = 0b00000010,
        const EMPTY_VALS = 0b00000100,
        const GLOBAL     = 0b00001000,
        const HIDDEN     = 0b00010000,
        const TAKES_VAL  = 0b00100000,
        const USE_DELIM  = 0b01000000,
        const NEXT_LINE_HELP = 0b10000000,
    }
}

#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct ArgFlags(Flags);

impl ArgFlags {
    pub fn new() -> Self {
        ArgFlags(EMPTY_VALS | USE_DELIM)
    }

    impl_settings!{ArgSettings,
        Required => REQUIRED,
        Multiple => MULTIPLE,
        EmptyValues => EMPTY_VALS,
        Global => GLOBAL,
        Hidden => HIDDEN,
        TakesValue => TAKES_VAL,
        UseValueDelimiter => USE_DELIM,
        NextLineHelp => NEXT_LINE_HELP
    }
}

impl Default for ArgFlags {
    fn default() -> Self {
        ArgFlags::new()
    }
}

/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
/// methods `Arg::set`, `Arg::unset`, and `Arg::is_set`
#[derive(Debug, PartialEq, Copy, Clone)]
#[doc(hidden)]
pub enum ArgSettings {
    /// The argument must be used
    Required,
    /// The argument may be used multiple times such as `--flag --flag`
    Multiple,
    /// The argument allows empty values such as `--option ""`
    EmptyValues,
    /// The argument should be propagated down through all child subcommands
    Global,
    /// The argument should **not** be shown in help text
    Hidden,
    /// The argument accepts a value, such as `--option <value>`
    TakesValue,
    /// Determines if the argument allows values to be grouped via a delimter
    UseValueDelimiter,
    /// Prints the help text on the line after the argument
    NextLineHelp,
}

impl FromStr for ArgSettings {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
        match &*s.to_ascii_lowercase() {
            "required" => Ok(ArgSettings::Required),
            "multiple" => Ok(ArgSettings::Multiple),
            "global" => Ok(ArgSettings::Global),
            "emptyvalues" => Ok(ArgSettings::EmptyValues),
            "hidden" => Ok(ArgSettings::Hidden),
            "takesvalue" => Ok(ArgSettings::TakesValue),
            "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
            "nextlinehelp" => Ok(ArgSettings::NextLineHelp),
            _ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
        }
    }
}
<commit_msg>sprinkle #[derive(Copy)]<commit_after>use std::str::FromStr;
use std::ascii::AsciiExt;

bitflags! {
    flags Flags: u8 {
        const REQUIRED   = 0b00000001,
        const MULTIPLE   = 0b00000010,
        const EMPTY_VALS = 0b00000100,
        const GLOBAL     = 0b00001000,
        const HIDDEN     = 0b00010000,
        const TAKES_VAL  = 0b00100000,
        const USE_DELIM  = 0b01000000,
        const NEXT_LINE_HELP = 0b10000000,
    }
}

#[doc(hidden)]
#[derive(Debug, Clone, Copy)]
pub struct ArgFlags(Flags);

impl ArgFlags {
    pub fn new() -> Self {
        ArgFlags(EMPTY_VALS | USE_DELIM)
    }

    impl_settings!{ArgSettings,
        Required => REQUIRED,
        Multiple => MULTIPLE,
        EmptyValues => EMPTY_VALS,
        Global => GLOBAL,
        Hidden => HIDDEN,
        TakesValue => TAKES_VAL,
        UseValueDelimiter => USE_DELIM,
        NextLineHelp => NEXT_LINE_HELP
    }
}

impl Default for ArgFlags {
    fn default() -> Self {
        ArgFlags::new()
    }
}

/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
/// methods `Arg::set`, `Arg::unset`, and `Arg::is_set`
#[derive(Debug, PartialEq, Copy, Clone)]
#[doc(hidden)]
pub enum ArgSettings {
    /// The argument must be used
    Required,
    /// The argument may be used multiple times such as `--flag --flag`
    Multiple,
    /// The argument allows empty values such as `--option ""`
    EmptyValues,
    /// The argument should be propagated down through all child subcommands
    Global,
    /// The argument should **not** be shown in help text
    Hidden,
    /// The argument accepts a value, such as `--option <value>`
    TakesValue,
    /// Determines if the argument allows values to be grouped via a delimter
    UseValueDelimiter,
    /// Prints the help text on the line after the argument
    NextLineHelp,
}

impl FromStr for ArgSettings {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
        match &*s.to_ascii_lowercase() {
            "required" => Ok(ArgSettings::Required),
            "multiple" => Ok(ArgSettings::Multiple),
            "global" => Ok(ArgSettings::Global),
            "emptyvalues" => Ok(ArgSettings::EmptyValues),
            "hidden" => Ok(ArgSettings::Hidden),
            "takesvalue" => Ok(ArgSettings::TakesValue),
            "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
            "nextlinehelp" => Ok(ArgSettings::NextLineHelp),
            _ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
        }
    }
}
<|endoftext|>


<commit_before>use std::str::FromStr;
use std::ascii::AsciiExt;

bitflags! {
    flags Flags: u8 {
        const REQUIRED   = 0b00000001,
        const MULTIPLE   = 0b00000010,
        const EMPTY_VALS = 0b00000100,
        const GLOBAL     = 0b00001000,
        const HIDDEN     = 0b00010000,
        const TAKES_VAL  = 0b00100000,
        const USE_DELIM  = 0b01000000,
        const NEXT_LINE_HELP = 0b10000000,
    }
}

#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct ArgFlags(Flags);

impl ArgFlags {
    pub fn new() -> Self {
        ArgFlags(EMPTY_VALS | USE_DELIM)
    }

    impl_settings!{ArgSettings,
        Required => REQUIRED,
        Multiple => MULTIPLE,
        EmptyValues => EMPTY_VALS,
        Global => GLOBAL,
        Hidden => HIDDEN,
        TakesValue => TAKES_VAL,
        UseValueDelimiter => USE_DELIM,
        NextLineHelp => NEXT_LINE_HELP
    }
}

impl Default for ArgFlags {
    fn default() -> Self {
        ArgFlags::new()
    }
}

/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
/// methods `Arg::set`, `Arg::unset`, and `Arg::is_set`
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ArgSettings {
    /// The argument must be used
    Required,
    /// The argument may be used multiple times such as `--flag --flag`
    Multiple,
    /// The argument allows empty values such as `--option ""`
    EmptyValues,
    /// The argument should be propagated down through all child subcommands
    Global,
    /// The argument should **not** be shown in help text
    Hidden,
    /// The argument accepts a value, such as `--option <value>`
    TakesValue,
    /// Determines if the argument allows values to be grouped via a delimter
    UseValueDelimiter,
    /// Prints the help text on the line after the argument
    NextLineHelp,
}

impl FromStr for ArgSettings {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
        match &*s.to_ascii_lowercase() {
            "required" => Ok(ArgSettings::Required),
            "multiple" => Ok(ArgSettings::Multiple),
            "global" => Ok(ArgSettings::Global),
            "emptyvalues" => Ok(ArgSettings::EmptyValues),
            "hidden" => Ok(ArgSettings::Hidden),
            "takesvalue" => Ok(ArgSettings::TakesValue),
            "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
            "nextlinehelp" => Ok(ArgSettings::NextLineHelp),
            _ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
        }
    }
}
<commit_msg>chore: hides ArgSettings in docs<commit_after>use std::str::FromStr;
use std::ascii::AsciiExt;

bitflags! {
    flags Flags: u8 {
        const REQUIRED   = 0b00000001,
        const MULTIPLE   = 0b00000010,
        const EMPTY_VALS = 0b00000100,
        const GLOBAL     = 0b00001000,
        const HIDDEN     = 0b00010000,
        const TAKES_VAL  = 0b00100000,
        const USE_DELIM  = 0b01000000,
        const NEXT_LINE_HELP = 0b10000000,
    }
}

#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct ArgFlags(Flags);

impl ArgFlags {
    pub fn new() -> Self {
        ArgFlags(EMPTY_VALS | USE_DELIM)
    }

    impl_settings!{ArgSettings,
        Required => REQUIRED,
        Multiple => MULTIPLE,
        EmptyValues => EMPTY_VALS,
        Global => GLOBAL,
        Hidden => HIDDEN,
        TakesValue => TAKES_VAL,
        UseValueDelimiter => USE_DELIM,
        NextLineHelp => NEXT_LINE_HELP
    }
}

impl Default for ArgFlags {
    fn default() -> Self {
        ArgFlags::new()
    }
}

/// Various settings that apply to arguments and may be set, unset, and checked via getter/setter
/// methods `Arg::set`, `Arg::unset`, and `Arg::is_set`
#[derive(Debug, PartialEq, Copy, Clone)]
#[doc(hidden)]
pub enum ArgSettings {
    /// The argument must be used
    Required,
    /// The argument may be used multiple times such as `--flag --flag`
    Multiple,
    /// The argument allows empty values such as `--option ""`
    EmptyValues,
    /// The argument should be propagated down through all child subcommands
    Global,
    /// The argument should **not** be shown in help text
    Hidden,
    /// The argument accepts a value, such as `--option <value>`
    TakesValue,
    /// Determines if the argument allows values to be grouped via a delimter
    UseValueDelimiter,
    /// Prints the help text on the line after the argument
    NextLineHelp,
}

impl FromStr for ArgSettings {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
        match &*s.to_ascii_lowercase() {
            "required" => Ok(ArgSettings::Required),
            "multiple" => Ok(ArgSettings::Multiple),
            "global" => Ok(ArgSettings::Global),
            "emptyvalues" => Ok(ArgSettings::EmptyValues),
            "hidden" => Ok(ArgSettings::Hidden),
            "takesvalue" => Ok(ArgSettings::TakesValue),
            "usevaluedelimiter" => Ok(ArgSettings::UseValueDelimiter),
            "nextlinehelp" => Ok(ArgSettings::NextLineHelp),
            _ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>initial commit of graph example<commit_after>struct Graph<T> {
    nodes: Vec<Node<T>>,
}

fn main() {

}<|endoftext|>


<commit_before><commit_msg>add OpsWorks integration tests<commit_after>#![cfg(feature = "opsworks")]

extern crate rusoto;

use rusoto::opsworks::{OpsWorksClient, DescribeStacksRequest};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
fn should_describe_stacks() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = OpsWorksClient::new(credentials, Region::UsEast1);

    let request = DescribeStacksRequest::default();

    match client.describe_stacks(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}

#[test]
fn should_describe_my_user_profile() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = OpsWorksClient::new(credentials, Region::UsEast1);

    match client.describe_my_user_profile() {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}<|endoftext|>