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

use hir::def_id::DefId;
use ty::{self, Ty, TypeFoldable, Substs, TyCtxt};
use ty::subst::Kind;
use traits;
use syntax::abi::Abi;
use util::ppaux;

use std::fmt;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Instance<'tcx> {
    pub def: InstanceDef<'tcx>,
    pub substs: &'tcx Substs<'tcx>,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum InstanceDef<'tcx> {
    Item(DefId),
    Intrinsic(DefId),

    /// <fn() as FnTrait>::call_*
    /// def-id is FnTrait::call_*
    FnPtrShim(DefId, Ty<'tcx>),

    /// <Trait as Trait>::fn
    Virtual(DefId, usize),

    /// <[mut closure] as FnOnce>::call_once
    ClosureOnceShim { call_once: DefId },

    /// drop_in_place::<T>; None for empty drop glue.
    DropGlue(DefId, Option<Ty<'tcx>>),

    ///`<T as Clone>::clone` shim.
    CloneShim(DefId, Ty<'tcx>),
}

impl<'a, 'tcx> Instance<'tcx> {
    pub fn ty(&self,
              tcx: TyCtxt<'a, 'tcx, 'tcx>)
              -> Ty<'tcx>
    {
        self.def.def_ty(tcx).subst(tcx, self.substs)
    }
}

impl<'tcx> InstanceDef<'tcx> {
    #[inline]
    pub fn def_id(&self) -> DefId {
        match *self {
            InstanceDef::Item(def_id) |
            InstanceDef::FnPtrShim(def_id, _) |
            InstanceDef::Virtual(def_id, _) |
            InstanceDef::Intrinsic(def_id, ) |
            InstanceDef::ClosureOnceShim { call_once: def_id } |
            InstanceDef::DropGlue(def_id, _) |
            InstanceDef::CloneShim(def_id, _) => def_id
        }
    }

    #[inline]
    pub fn def_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
        tcx.type_of(self.def_id())
    }

    #[inline]
    pub fn attrs<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
        tcx.get_attrs(self.def_id())
    }

    pub fn is_inline<'a>(
        &self,
        tcx: TyCtxt<'a, 'tcx, 'tcx>
    ) -> bool {
        use hir::map::DefPathData;
        let def_id = match *self {
            ty::InstanceDef::Item(def_id) => def_id,
            ty::InstanceDef::DropGlue(_, Some(_)) => return false,
            _ => return true
        };
        match tcx.def_key(def_id).disambiguated_data.data {
            DefPathData::StructCtor |
            DefPathData::EnumVariant(..) |
            DefPathData::ClosureExpr => true,
            _ => false
        }
    }

    pub fn requires_local<'a>(
        &self,
        tcx: TyCtxt<'a, 'tcx, 'tcx>
    ) -> bool {
        use syntax::attr::requests_inline;
        if self.is_inline(tcx) {
            return true
        }
        if let ty::InstanceDef::DropGlue(..) = *self {
            // Drop glue wants to be instantiated at every translation
            // unit, but without an #[inline] hint. We should make this
            // available to normal end-users.
            return true
        }
        requests_inline(&self.attrs(tcx)[..]) ||
            tcx.is_const_fn(self.def_id())
    }
}

impl<'tcx> fmt::Display for Instance<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
        match self.def {
            InstanceDef::Item(_) => Ok(()),
            InstanceDef::Intrinsic(_) => {
                write!(f, " - intrinsic")
            }
            InstanceDef::Virtual(_, num) => {
                write!(f, " - shim(#{})", num)
            }
            InstanceDef::FnPtrShim(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
            InstanceDef::ClosureOnceShim { .. } => {
                write!(f, " - shim")
            }
            InstanceDef::DropGlue(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
            InstanceDef::CloneShim(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
        }
    }
}

impl<'a, 'b, 'tcx> Instance<'tcx> {
    pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
               -> Instance<'tcx> {
        assert!(!substs.has_escaping_regions(),
                "substs of instance {:?} not normalized for trans: {:?}",
                def_id, substs);
        Instance { def: InstanceDef::Item(def_id), substs: substs }
    }

    pub fn mono(tcx: TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
        Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
    }

    #[inline]
    pub fn def_id(&self) -> DefId {
        self.def.def_id()
    }

    /// Resolve a (def_id, substs) pair to an (optional) instance -- most commonly,
    /// this is used to find the precise code that will run for a trait method invocation,
    /// if known.
    ///
    /// Returns `None` if we cannot resolve `Instance` to a specific instance.
    /// For example, in a context like this,
    ///
    /// ```
    /// fn foo<T: Debug>(t: T) { ... }
    /// ```
    ///
    /// trying to resolve `Debug::fmt` applied to `T` will yield `None`, because we do not
    /// know what code ought to run. (Note that this setting is also affected by the
    /// `RevealMode` in the parameter environment.)
    ///
    /// Presuming that coherence and type-check have succeeded, if this method is invoked
    /// in a monomorphic context (i.e., like during trans), then it is guaranteed to return
    /// `Some`.
    pub fn resolve(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                   param_env: ty::ParamEnv<'tcx>,
                   def_id: DefId,
                   substs: &'tcx Substs<'tcx>) -> Option<Instance<'tcx>> {
        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
        let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
            debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
            let item = tcx.associated_item(def_id);
            resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
        } else {
            let ty = tcx.type_of(def_id);
            let item_type = tcx.trans_apply_param_substs_env(substs, param_env, &ty);

            let def = match item_type.sty {
                ty::TyFnDef(..) if {
                    let f = item_type.fn_sig(tcx);
                    f.abi() == Abi::RustIntrinsic ||
                        f.abi() == Abi::PlatformIntrinsic
                } =>
                {
                    debug!(" => intrinsic");
                    ty::InstanceDef::Intrinsic(def_id)
                }
                _ => {
                    if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
                        let ty = substs.type_at(0);
                        if ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All)) {
                            debug!(" => nontrivial drop glue");
                            ty::InstanceDef::DropGlue(def_id, Some(ty))
                        } else {
                            debug!(" => trivial drop glue");
                            ty::InstanceDef::DropGlue(def_id, None)
                        }
                    } else {
                        debug!(" => free item");
                        ty::InstanceDef::Item(def_id)
                    }
                }
            };
            Some(Instance {
                def: def,
                substs: substs
            })
        };
        debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
        result
    }

    pub fn resolve_closure(
                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
                    def_id: DefId,
                    substs: ty::ClosureSubsts<'tcx>,
                    requested_kind: ty::ClosureKind)
    -> Instance<'tcx>
    {
        let actual_kind = substs.closure_kind(def_id, tcx);

        match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
            Ok(true) => fn_once_adapter_instance(tcx, def_id, substs),
            _ => Instance::new(def_id, substs.substs)
        }
    }
}

fn resolve_associated_item<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    trait_item: &ty::AssociatedItem,
    param_env: ty::ParamEnv<'tcx>,
    trait_id: DefId,
    rcvr_substs: &'tcx Substs<'tcx>,
) -> Option<Instance<'tcx>> {
    let def_id = trait_item.def_id;
    debug!("resolve_associated_item(trait_item={:?}, \
                                    trait_id={:?}, \
           rcvr_substs={:?})",
           def_id, trait_id, rcvr_substs);

    let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
    let vtbl = tcx.trans_fulfill_obligation((param_env, ty::Binder(trait_ref)));

    // Now that we know which impl is being used, we can dispatch to
    // the actual function:
    match vtbl {
        traits::VtableImpl(impl_data) => {
            let (def_id, substs) = traits::find_associated_item(
                tcx, trait_item, rcvr_substs, &impl_data);
            let substs = tcx.erase_regions(&substs);
            Some(ty::Instance::new(def_id, substs))
        }
        traits::VtableGenerator(closure_data) => {
            Some(Instance {
                def: ty::InstanceDef::Item(closure_data.closure_def_id),
                substs: closure_data.substs.substs
            })
        }
        traits::VtableClosure(closure_data) => {
            let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap();
            Some(Instance::resolve_closure(tcx, closure_data.closure_def_id, closure_data.substs,
                                 trait_closure_kind))
        }
        traits::VtableFnPointer(ref data) => {
            Some(Instance {
                def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
                substs: rcvr_substs
            })
        }
        traits::VtableObject(ref data) => {
            let index = tcx.get_vtable_index_of_object_method(data, def_id);
            Some(Instance {
                def: ty::InstanceDef::Virtual(def_id, index),
                substs: rcvr_substs
            })
        }
        traits::VtableBuiltin(..) => {
            if let Some(_) = tcx.lang_items().clone_trait() {
                Some(Instance {
                    def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
                    substs: rcvr_substs
                })
            } else {
                None
            }
        }
        traits::VtableAutoImpl(..) | traits::VtableParam(..) => None
    }
}

fn needs_fn_once_adapter_shim<'a, 'tcx>(actual_closure_kind: ty::ClosureKind,
                              trait_closure_kind: ty::ClosureKind)
    -> Result<bool, ()>
{
    match (actual_closure_kind, trait_closure_kind) {
        (ty::ClosureKind::Fn, ty::ClosureKind::Fn) |
            (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) |
            (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => {
                // No adapter needed.
                Ok(false)
            }
        (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
            // The closure fn `llfn` is a `fn(&self, ...)`.  We want a
            // `fn(&mut self, ...)`. In fact, at trans time, these are
            // basically the same thing, so we can just return llfn.
            Ok(false)
        }
        (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) |
            (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
                // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
                // self, ...)`.  We want a `fn(self, ...)`. We can produce
                // this by doing something like:
                //
                //     fn call_once(self, ...) { call_mut(&self, ...) }
                //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
                //
                // These are both the same at trans time.
                Ok(true)
        }
        (ty::ClosureKind::FnMut, _) |
        (ty::ClosureKind::FnOnce, _) => Err(())
    }
}

fn fn_once_adapter_instance<'a, 'tcx>(
                            tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            closure_did: DefId,
                            substs: ty::ClosureSubsts<'tcx>,
                            ) -> Instance<'tcx> {
    debug!("fn_once_adapter_shim({:?}, {:?})",
    closure_did,
    substs);
    let fn_once = tcx.lang_items().fn_once_trait().unwrap();
    let call_once = tcx.associated_items(fn_once)
        .find(|it| it.kind == ty::AssociatedKind::Method)
        .unwrap().def_id;
    let def = ty::InstanceDef::ClosureOnceShim { call_once };

    let self_ty = tcx.mk_closure_from_closure_substs(
        closure_did, substs);

    let sig = substs.closure_sig(closure_did, tcx);
    let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
    assert_eq!(sig.inputs().len(), 1);
    let substs = tcx.mk_substs([
                               Kind::from(self_ty),
                               Kind::from(sig.inputs()[0]),
    ].iter().cloned());

    debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
    Instance { def, substs }
}
<commit_msg>Test with trans_apply_param_substs<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use hir::def_id::DefId;
use ty::{self, Ty, TypeFoldable, Substs, TyCtxt};
use ty::subst::Kind;
use traits;
use syntax::abi::Abi;
use util::ppaux;

use std::fmt;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Instance<'tcx> {
    pub def: InstanceDef<'tcx>,
    pub substs: &'tcx Substs<'tcx>,
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum InstanceDef<'tcx> {
    Item(DefId),
    Intrinsic(DefId),

    /// <fn() as FnTrait>::call_*
    /// def-id is FnTrait::call_*
    FnPtrShim(DefId, Ty<'tcx>),

    /// <Trait as Trait>::fn
    Virtual(DefId, usize),

    /// <[mut closure] as FnOnce>::call_once
    ClosureOnceShim { call_once: DefId },

    /// drop_in_place::<T>; None for empty drop glue.
    DropGlue(DefId, Option<Ty<'tcx>>),

    ///`<T as Clone>::clone` shim.
    CloneShim(DefId, Ty<'tcx>),
}

impl<'a, 'tcx> Instance<'tcx> {
    pub fn ty(&self,
              tcx: TyCtxt<'a, 'tcx, 'tcx>)
              -> Ty<'tcx>
    {
        let ty = self.def.def_ty(tcx);
        tcx.trans_apply_param_substs(self.substs, &ty)
    }
}

impl<'tcx> InstanceDef<'tcx> {
    #[inline]
    pub fn def_id(&self) -> DefId {
        match *self {
            InstanceDef::Item(def_id) |
            InstanceDef::FnPtrShim(def_id, _) |
            InstanceDef::Virtual(def_id, _) |
            InstanceDef::Intrinsic(def_id, ) |
            InstanceDef::ClosureOnceShim { call_once: def_id } |
            InstanceDef::DropGlue(def_id, _) |
            InstanceDef::CloneShim(def_id, _) => def_id
        }
    }

    #[inline]
    pub fn def_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
        tcx.type_of(self.def_id())
    }

    #[inline]
    pub fn attrs<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::Attributes<'tcx> {
        tcx.get_attrs(self.def_id())
    }

    pub fn is_inline<'a>(
        &self,
        tcx: TyCtxt<'a, 'tcx, 'tcx>
    ) -> bool {
        use hir::map::DefPathData;
        let def_id = match *self {
            ty::InstanceDef::Item(def_id) => def_id,
            ty::InstanceDef::DropGlue(_, Some(_)) => return false,
            _ => return true
        };
        match tcx.def_key(def_id).disambiguated_data.data {
            DefPathData::StructCtor |
            DefPathData::EnumVariant(..) |
            DefPathData::ClosureExpr => true,
            _ => false
        }
    }

    pub fn requires_local<'a>(
        &self,
        tcx: TyCtxt<'a, 'tcx, 'tcx>
    ) -> bool {
        use syntax::attr::requests_inline;
        if self.is_inline(tcx) {
            return true
        }
        if let ty::InstanceDef::DropGlue(..) = *self {
            // Drop glue wants to be instantiated at every translation
            // unit, but without an #[inline] hint. We should make this
            // available to normal end-users.
            return true
        }
        requests_inline(&self.attrs(tcx)[..]) ||
            tcx.is_const_fn(self.def_id())
    }
}

impl<'tcx> fmt::Display for Instance<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        ppaux::parameterized(f, self.substs, self.def_id(), &[])?;
        match self.def {
            InstanceDef::Item(_) => Ok(()),
            InstanceDef::Intrinsic(_) => {
                write!(f, " - intrinsic")
            }
            InstanceDef::Virtual(_, num) => {
                write!(f, " - shim(#{})", num)
            }
            InstanceDef::FnPtrShim(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
            InstanceDef::ClosureOnceShim { .. } => {
                write!(f, " - shim")
            }
            InstanceDef::DropGlue(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
            InstanceDef::CloneShim(_, ty) => {
                write!(f, " - shim({:?})", ty)
            }
        }
    }
}

impl<'a, 'b, 'tcx> Instance<'tcx> {
    pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
               -> Instance<'tcx> {
        assert!(!substs.has_escaping_regions(),
                "substs of instance {:?} not normalized for trans: {:?}",
                def_id, substs);
        Instance { def: InstanceDef::Item(def_id), substs: substs }
    }

    pub fn mono(tcx: TyCtxt<'a, 'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
        Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
    }

    #[inline]
    pub fn def_id(&self) -> DefId {
        self.def.def_id()
    }

    /// Resolve a (def_id, substs) pair to an (optional) instance -- most commonly,
    /// this is used to find the precise code that will run for a trait method invocation,
    /// if known.
    ///
    /// Returns `None` if we cannot resolve `Instance` to a specific instance.
    /// For example, in a context like this,
    ///
    /// ```
    /// fn foo<T: Debug>(t: T) { ... }
    /// ```
    ///
    /// trying to resolve `Debug::fmt` applied to `T` will yield `None`, because we do not
    /// know what code ought to run. (Note that this setting is also affected by the
    /// `RevealMode` in the parameter environment.)
    ///
    /// Presuming that coherence and type-check have succeeded, if this method is invoked
    /// in a monomorphic context (i.e., like during trans), then it is guaranteed to return
    /// `Some`.
    pub fn resolve(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                   param_env: ty::ParamEnv<'tcx>,
                   def_id: DefId,
                   substs: &'tcx Substs<'tcx>) -> Option<Instance<'tcx>> {
        debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
        let result = if let Some(trait_def_id) = tcx.trait_of_item(def_id) {
            debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
            let item = tcx.associated_item(def_id);
            resolve_associated_item(tcx, &item, param_env, trait_def_id, substs)
        } else {
            let ty = tcx.type_of(def_id);
            let item_type = tcx.trans_apply_param_substs_env(substs, param_env, &ty);

            let def = match item_type.sty {
                ty::TyFnDef(..) if {
                    let f = item_type.fn_sig(tcx);
                    f.abi() == Abi::RustIntrinsic ||
                        f.abi() == Abi::PlatformIntrinsic
                } =>
                {
                    debug!(" => intrinsic");
                    ty::InstanceDef::Intrinsic(def_id)
                }
                _ => {
                    if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
                        let ty = substs.type_at(0);
                        if ty.needs_drop(tcx, ty::ParamEnv::empty(traits::Reveal::All)) {
                            debug!(" => nontrivial drop glue");
                            ty::InstanceDef::DropGlue(def_id, Some(ty))
                        } else {
                            debug!(" => trivial drop glue");
                            ty::InstanceDef::DropGlue(def_id, None)
                        }
                    } else {
                        debug!(" => free item");
                        ty::InstanceDef::Item(def_id)
                    }
                }
            };
            Some(Instance {
                def: def,
                substs: substs
            })
        };
        debug!("resolve(def_id={:?}, substs={:?}) = {:?}", def_id, substs, result);
        result
    }

    pub fn resolve_closure(
                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
                    def_id: DefId,
                    substs: ty::ClosureSubsts<'tcx>,
                    requested_kind: ty::ClosureKind)
    -> Instance<'tcx>
    {
        let actual_kind = substs.closure_kind(def_id, tcx);

        match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
            Ok(true) => fn_once_adapter_instance(tcx, def_id, substs),
            _ => Instance::new(def_id, substs.substs)
        }
    }
}

fn resolve_associated_item<'a, 'tcx>(
    tcx: TyCtxt<'a, 'tcx, 'tcx>,
    trait_item: &ty::AssociatedItem,
    param_env: ty::ParamEnv<'tcx>,
    trait_id: DefId,
    rcvr_substs: &'tcx Substs<'tcx>,
) -> Option<Instance<'tcx>> {
    let def_id = trait_item.def_id;
    debug!("resolve_associated_item(trait_item={:?}, \
                                    trait_id={:?}, \
           rcvr_substs={:?})",
           def_id, trait_id, rcvr_substs);

    let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
    let vtbl = tcx.trans_fulfill_obligation((param_env, ty::Binder(trait_ref)));

    // Now that we know which impl is being used, we can dispatch to
    // the actual function:
    match vtbl {
        traits::VtableImpl(impl_data) => {
            let (def_id, substs) = traits::find_associated_item(
                tcx, trait_item, rcvr_substs, &impl_data);
            let substs = tcx.erase_regions(&substs);
            Some(ty::Instance::new(def_id, substs))
        }
        traits::VtableGenerator(closure_data) => {
            Some(Instance {
                def: ty::InstanceDef::Item(closure_data.closure_def_id),
                substs: closure_data.substs.substs
            })
        }
        traits::VtableClosure(closure_data) => {
            let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap();
            Some(Instance::resolve_closure(tcx, closure_data.closure_def_id, closure_data.substs,
                                 trait_closure_kind))
        }
        traits::VtableFnPointer(ref data) => {
            Some(Instance {
                def: ty::InstanceDef::FnPtrShim(trait_item.def_id, data.fn_ty),
                substs: rcvr_substs
            })
        }
        traits::VtableObject(ref data) => {
            let index = tcx.get_vtable_index_of_object_method(data, def_id);
            Some(Instance {
                def: ty::InstanceDef::Virtual(def_id, index),
                substs: rcvr_substs
            })
        }
        traits::VtableBuiltin(..) => {
            if let Some(_) = tcx.lang_items().clone_trait() {
                Some(Instance {
                    def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
                    substs: rcvr_substs
                })
            } else {
                None
            }
        }
        traits::VtableAutoImpl(..) | traits::VtableParam(..) => None
    }
}

fn needs_fn_once_adapter_shim<'a, 'tcx>(actual_closure_kind: ty::ClosureKind,
                              trait_closure_kind: ty::ClosureKind)
    -> Result<bool, ()>
{
    match (actual_closure_kind, trait_closure_kind) {
        (ty::ClosureKind::Fn, ty::ClosureKind::Fn) |
            (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) |
            (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => {
                // No adapter needed.
                Ok(false)
            }
        (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
            // The closure fn `llfn` is a `fn(&self, ...)`.  We want a
            // `fn(&mut self, ...)`. In fact, at trans time, these are
            // basically the same thing, so we can just return llfn.
            Ok(false)
        }
        (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) |
            (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
                // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
                // self, ...)`.  We want a `fn(self, ...)`. We can produce
                // this by doing something like:
                //
                //     fn call_once(self, ...) { call_mut(&self, ...) }
                //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
                //
                // These are both the same at trans time.
                Ok(true)
        }
        (ty::ClosureKind::FnMut, _) |
        (ty::ClosureKind::FnOnce, _) => Err(())
    }
}

fn fn_once_adapter_instance<'a, 'tcx>(
                            tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            closure_did: DefId,
                            substs: ty::ClosureSubsts<'tcx>,
                            ) -> Instance<'tcx> {
    debug!("fn_once_adapter_shim({:?}, {:?})",
    closure_did,
    substs);
    let fn_once = tcx.lang_items().fn_once_trait().unwrap();
    let call_once = tcx.associated_items(fn_once)
        .find(|it| it.kind == ty::AssociatedKind::Method)
        .unwrap().def_id;
    let def = ty::InstanceDef::ClosureOnceShim { call_once };

    let self_ty = tcx.mk_closure_from_closure_substs(
        closure_did, substs);

    let sig = substs.closure_sig(closure_did, tcx);
    let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
    assert_eq!(sig.inputs().len(), 1);
    let substs = tcx.mk_substs([
                               Kind::from(self_ty),
                               Kind::from(sig.inputs()[0]),
    ].iter().cloned());

    debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
    Instance { def, substs }
}
<|endoftext|>


<commit_before>import ast::{crate, expr_, mac_invoc,
                     mac_aq, mac_var};
import fold::*;
import visit::*;
import ext::base::*;
import ext::build::*;
import parse::parser;
import parse::parser::parse_from_source_str;
import dvec::{dvec, extensions};

import print::*;
import io::*;

import codemap::span;

type aq_ctxt = @{lo: uint,
                 gather: dvec<{lo: uint, hi: uint,
                               e: @ast::expr,
                               constr: str}>};
enum fragment {
    from_expr(@ast::expr),
    from_ty(@ast::ty)
}

iface qq_helper {
    fn span() -> span;
    fn visit(aq_ctxt, vt<aq_ctxt>);
    fn extract_mac() -> option<ast::mac_>;
    fn mk_parse_fn(ext_ctxt,span) -> @ast::expr;
    fn get_fold_fn() -> str;
}

impl of qq_helper for @ast::crate {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_crate"])
    }
    fn get_fold_fn() -> str {"fold_crate"}
}
impl of qq_helper for @ast::expr {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_expr(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::expr_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_expr"])
    }
    fn get_fold_fn() -> str {"fold_expr"}
}
impl of qq_helper for @ast::ty {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::ty_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_ty"])
    }
    fn get_fold_fn() -> str {"fold_ty"}
}
impl of qq_helper for @ast::item {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_item"])
    }
    fn get_fold_fn() -> str {"fold_item"}
}
impl of qq_helper for @ast::stmt {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_stmt"])
    }
    fn get_fold_fn() -> str {"fold_stmt"}
}
impl of qq_helper for @ast::pat {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_pat"])
    }
    fn get_fold_fn() -> str {"fold_pat"}
}

fn gather_anti_quotes<N: qq_helper>(lo: uint, node: N) -> aq_ctxt
{
    let v = @{visit_expr: {|node, &&cx, v|
                  visit_aq(node, "from_expr", cx, v)},
              visit_ty: {|node, &&cx, v|
                  visit_aq(node, "from_ty", cx, v)}
              with *default_visitor()};
    let cx = @{lo:lo, gather: dvec()};
    node.visit(cx, mk_vt(v));
    // FIXME: Maybe this is an overkill (merge_sort), it might be better
    //   to just keep the gather array in sorted order ... (Issue #2250)
    cx.gather.swap { |v|
        vec::to_mut(std::sort::merge_sort({|a,b| a.lo < b.lo}, v))
    };
    ret cx;
}

fn visit_aq<T:qq_helper>(node: T, constr: str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
{
    alt (node.extract_mac()) {
      some(mac_aq(sp, e)) {
        cx.gather.push({lo: sp.lo - cx.lo, hi: sp.hi - cx.lo,
                        e: e, constr: constr});
      }
      _ {node.visit(cx, v);}
    }
}

fn is_space(c: char) -> bool {
    parse::lexer::is_whitespace(c)
}

fn expand_ast(ecx: ext_ctxt, _sp: span,
              arg: ast::mac_arg, body: ast::mac_body)
    -> @ast::expr
{
    let mut what = "expr";
    option::iter(arg) {|arg|
        let args: [@ast::expr] =
            alt arg.node {
              ast::expr_vec(elts, _) { elts }
              _ {
                ecx.span_fatal
                    (_sp, "#ast requires arguments of the form `[...]`.")
              }
            };
        if vec::len::<@ast::expr>(args) != 1u {
            ecx.span_fatal(_sp, "#ast requires exactly one arg");
        }
        alt (args[0].node) {
          ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u
              {what = id[0]}
          _ {ecx.span_fatal(args[0].span, "expected an identifier");}
        }
    }
    let body = get_mac_body(ecx,_sp,body);

    ret alt what {
      "crate" {finish(ecx, body, parse_crate)}
      "expr" {finish(ecx, body, parse_expr)}
      "ty" {finish(ecx, body, parse_ty)}
      "item" {finish(ecx, body, parse_item)}
      "stmt" {finish(ecx, body, parse_stmt)}
      "pat" {finish(ecx, body, parse_pat)}
      _ {ecx.span_fatal(_sp, "unsupported ast type")}
    };
}

fn parse_crate(p: parser) -> @ast::crate { p.parse_crate_mod([]) }
fn parse_ty(p: parser) -> @ast::ty { p.parse_ty(false) }
fn parse_stmt(p: parser) -> @ast::stmt { p.parse_stmt([]) }
fn parse_expr(p: parser) -> @ast::expr { p.parse_expr() }
fn parse_pat(p: parser) -> @ast::pat { p.parse_pat() }

fn parse_item(p: parser) -> @ast::item {
    alt p.parse_item([], ast::public) {
      some(item) { item }
      none       { fail "parse_item: parsing an item failed"; }
    }
}

fn finish<T: qq_helper>
    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
    -> @ast::expr
{
    let cm = ecx.codemap();
    let str = @codemap::span_to_snippet(body.span, cm);
    #debug["qquote--str==%?", str];
    let fname = codemap::mk_substr_filename(cm, body.span);
    let node = parse_from_source_str
        (f, fname, codemap::fss_internal(body.span), str,
         ecx.cfg(), ecx.parse_sess());
    let loc = codemap::lookup_char_pos(cm, body.span.lo);

    let sp = node.span();
    let qcx = gather_anti_quotes(sp.lo, node);
    let cx = qcx;

    for uint::range(1u, cx.gather.len()) {|i|
        assert cx.gather[i-1u].lo < cx.gather[i].lo;
        // ^^ check that the vector is sorted
        assert cx.gather[i-1u].hi <= cx.gather[i].lo;
        // ^^ check that the spans are non-overlapping
    }

    let mut str2 = "";
    enum state {active, skip(uint), blank};
    let mut state = active;
    let mut i = 0u, j = 0u;
    let g_len = cx.gather.len();
    str::chars_iter(*str) {|ch|
        if (j < g_len && i == cx.gather[j].lo) {
            assert ch == '$';
            let repl = #fmt("$%u ", j);
            state = skip(str::char_len(repl));
            str2 += repl;
        }
        alt state {
          active {str::push_char(str2, ch);}
          skip(1u) {state = blank;}
          skip(sk) {state = skip (sk-1u);}
          blank if is_space(ch) {str::push_char(str2, ch);}
          blank {str::push_char(str2, ' ');}
        }
        i += 1u;
        if (j < g_len && i == cx.gather[j].hi) {
            assert ch == ')';
            state = active;
            j += 1u;
        }
    }

    let cx = ecx;

    let cfg_call = {||
        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "cfg"), [])
    };

    let parse_sess_call = {||
        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "parse_sess"), [])
    };

    let pcall = mk_call(cx,sp,
                       ["syntax", "parse", "parser",
                        "parse_from_source_str"],
                       [node.mk_parse_fn(cx,sp),
                        mk_str(cx,sp, fname),
                        mk_call(cx,sp,
                                ["syntax","ext","qquote", "mk_file_substr"],
                                [mk_str(cx,sp, loc.file.name),
                                 mk_uint(cx,sp, loc.line),
                                 mk_uint(cx,sp, loc.col)]),
                        mk_unary(cx,sp, ast::box(ast::m_imm),
                                 mk_str(cx,sp, str2)),
                        cfg_call(),
                        parse_sess_call()]
                      );
    let mut rcall = pcall;
    if (g_len > 0u) {
        rcall = mk_call(cx,sp,
                        ["syntax", "ext", "qquote", "replace"],
                        [pcall,
                         mk_vec_e(cx,sp, qcx.gather.map_to_vec {|g|
                             mk_call(cx,sp,
                                     ["syntax", "ext", "qquote", g.constr],
                                     [g.e])}),
                         mk_path(cx,sp,
                                 ["syntax", "ext", "qquote",
                                  node.get_fold_fn()])]);
    }
    ret rcall;
}

fn replace<T>(node: T, repls: [fragment], ff: fn (ast_fold, T) -> T)
    -> T
{
    let aft = default_ast_fold();
    let f_pre = @{fold_expr: bind replace_expr(repls, _, _, _,
                                               aft.fold_expr),
                  fold_ty: bind replace_ty(repls, _, _, _,
                                           aft.fold_ty)
                  with *aft};
    ret ff(make_fold(f_pre), node);
}
fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
    @f.fold_crate(*n)
}
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {f.fold_item(n)}
fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)}
fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)}

fn replace_expr(repls: [fragment],
                e: ast::expr_, s: span, fld: ast_fold,
                orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
    -> (ast::expr_, span)
{
    alt e {
      ast::expr_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_expr(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn replace_ty(repls: [fragment],
                e: ast::ty_, s: span, fld: ast_fold,
                orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span))
    -> (ast::ty_, span)
{
    alt e {
      ast::ty_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_ty(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn print_expr(expr: @ast::expr) {
    let stdout = io::stdout();
    let pp = pprust::rust_printer(stdout);
    pprust::print_expr(pp, expr);
    pp::eof(pp.s);
    stdout.write_str("\n");
}

fn mk_file_substr(fname: str, line: uint, col: uint) -> codemap::file_substr {
    codemap::fss_external({filename: fname, line: line, col: col})
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Move imports around in qquote to avoid another cyclic import<commit_after>import ast::{crate, expr_, mac_invoc,
                     mac_aq, mac_var};
import parse::parser;
import parse::parser::parse_from_source_str;
import dvec::{dvec, extensions};

import fold::*;
import visit::*;
import ext::base::*;
import ext::build::*;
import print::*;
import io::*;

import codemap::span;

type aq_ctxt = @{lo: uint,
                 gather: dvec<{lo: uint, hi: uint,
                               e: @ast::expr,
                               constr: str}>};
enum fragment {
    from_expr(@ast::expr),
    from_ty(@ast::ty)
}

iface qq_helper {
    fn span() -> span;
    fn visit(aq_ctxt, vt<aq_ctxt>);
    fn extract_mac() -> option<ast::mac_>;
    fn mk_parse_fn(ext_ctxt,span) -> @ast::expr;
    fn get_fold_fn() -> str;
}

impl of qq_helper for @ast::crate {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_crate"])
    }
    fn get_fold_fn() -> str {"fold_crate"}
}
impl of qq_helper for @ast::expr {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_expr(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::expr_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_expr"])
    }
    fn get_fold_fn() -> str {"fold_expr"}
}
impl of qq_helper for @ast::ty {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::ty_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_ty"])
    }
    fn get_fold_fn() -> str {"fold_ty"}
}
impl of qq_helper for @ast::item {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_item"])
    }
    fn get_fold_fn() -> str {"fold_item"}
}
impl of qq_helper for @ast::stmt {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_stmt"])
    }
    fn get_fold_fn() -> str {"fold_stmt"}
}
impl of qq_helper for @ast::pat {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_pat"])
    }
    fn get_fold_fn() -> str {"fold_pat"}
}

fn gather_anti_quotes<N: qq_helper>(lo: uint, node: N) -> aq_ctxt
{
    let v = @{visit_expr: {|node, &&cx, v|
                  visit_aq(node, "from_expr", cx, v)},
              visit_ty: {|node, &&cx, v|
                  visit_aq(node, "from_ty", cx, v)}
              with *default_visitor()};
    let cx = @{lo:lo, gather: dvec()};
    node.visit(cx, mk_vt(v));
    // FIXME: Maybe this is an overkill (merge_sort), it might be better
    //   to just keep the gather array in sorted order ... (Issue #2250)
    cx.gather.swap { |v|
        vec::to_mut(std::sort::merge_sort({|a,b| a.lo < b.lo}, v))
    };
    ret cx;
}

fn visit_aq<T:qq_helper>(node: T, constr: str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
{
    alt (node.extract_mac()) {
      some(mac_aq(sp, e)) {
        cx.gather.push({lo: sp.lo - cx.lo, hi: sp.hi - cx.lo,
                        e: e, constr: constr});
      }
      _ {node.visit(cx, v);}
    }
}

fn is_space(c: char) -> bool {
    parse::lexer::is_whitespace(c)
}

fn expand_ast(ecx: ext_ctxt, _sp: span,
              arg: ast::mac_arg, body: ast::mac_body)
    -> @ast::expr
{
    let mut what = "expr";
    option::iter(arg) {|arg|
        let args: [@ast::expr] =
            alt arg.node {
              ast::expr_vec(elts, _) { elts }
              _ {
                ecx.span_fatal
                    (_sp, "#ast requires arguments of the form `[...]`.")
              }
            };
        if vec::len::<@ast::expr>(args) != 1u {
            ecx.span_fatal(_sp, "#ast requires exactly one arg");
        }
        alt (args[0].node) {
          ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u
              {what = id[0]}
          _ {ecx.span_fatal(args[0].span, "expected an identifier");}
        }
    }
    let body = get_mac_body(ecx,_sp,body);

    ret alt what {
      "crate" {finish(ecx, body, parse_crate)}
      "expr" {finish(ecx, body, parse_expr)}
      "ty" {finish(ecx, body, parse_ty)}
      "item" {finish(ecx, body, parse_item)}
      "stmt" {finish(ecx, body, parse_stmt)}
      "pat" {finish(ecx, body, parse_pat)}
      _ {ecx.span_fatal(_sp, "unsupported ast type")}
    };
}

fn parse_crate(p: parser) -> @ast::crate { p.parse_crate_mod([]) }
fn parse_ty(p: parser) -> @ast::ty { p.parse_ty(false) }
fn parse_stmt(p: parser) -> @ast::stmt { p.parse_stmt([]) }
fn parse_expr(p: parser) -> @ast::expr { p.parse_expr() }
fn parse_pat(p: parser) -> @ast::pat { p.parse_pat() }

fn parse_item(p: parser) -> @ast::item {
    alt p.parse_item([], ast::public) {
      some(item) { item }
      none       { fail "parse_item: parsing an item failed"; }
    }
}

fn finish<T: qq_helper>
    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
    -> @ast::expr
{
    let cm = ecx.codemap();
    let str = @codemap::span_to_snippet(body.span, cm);
    #debug["qquote--str==%?", str];
    let fname = codemap::mk_substr_filename(cm, body.span);
    let node = parse_from_source_str
        (f, fname, codemap::fss_internal(body.span), str,
         ecx.cfg(), ecx.parse_sess());
    let loc = codemap::lookup_char_pos(cm, body.span.lo);

    let sp = node.span();
    let qcx = gather_anti_quotes(sp.lo, node);
    let cx = qcx;

    for uint::range(1u, cx.gather.len()) {|i|
        assert cx.gather[i-1u].lo < cx.gather[i].lo;
        // ^^ check that the vector is sorted
        assert cx.gather[i-1u].hi <= cx.gather[i].lo;
        // ^^ check that the spans are non-overlapping
    }

    let mut str2 = "";
    enum state {active, skip(uint), blank};
    let mut state = active;
    let mut i = 0u, j = 0u;
    let g_len = cx.gather.len();
    str::chars_iter(*str) {|ch|
        if (j < g_len && i == cx.gather[j].lo) {
            assert ch == '$';
            let repl = #fmt("$%u ", j);
            state = skip(str::char_len(repl));
            str2 += repl;
        }
        alt state {
          active {str::push_char(str2, ch);}
          skip(1u) {state = blank;}
          skip(sk) {state = skip (sk-1u);}
          blank if is_space(ch) {str::push_char(str2, ch);}
          blank {str::push_char(str2, ' ');}
        }
        i += 1u;
        if (j < g_len && i == cx.gather[j].hi) {
            assert ch == ')';
            state = active;
            j += 1u;
        }
    }

    let cx = ecx;

    let cfg_call = {||
        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "cfg"), [])
    };

    let parse_sess_call = {||
        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "parse_sess"), [])
    };

    let pcall = mk_call(cx,sp,
                       ["syntax", "parse", "parser",
                        "parse_from_source_str"],
                       [node.mk_parse_fn(cx,sp),
                        mk_str(cx,sp, fname),
                        mk_call(cx,sp,
                                ["syntax","ext","qquote", "mk_file_substr"],
                                [mk_str(cx,sp, loc.file.name),
                                 mk_uint(cx,sp, loc.line),
                                 mk_uint(cx,sp, loc.col)]),
                        mk_unary(cx,sp, ast::box(ast::m_imm),
                                 mk_str(cx,sp, str2)),
                        cfg_call(),
                        parse_sess_call()]
                      );
    let mut rcall = pcall;
    if (g_len > 0u) {
        rcall = mk_call(cx,sp,
                        ["syntax", "ext", "qquote", "replace"],
                        [pcall,
                         mk_vec_e(cx,sp, qcx.gather.map_to_vec {|g|
                             mk_call(cx,sp,
                                     ["syntax", "ext", "qquote", g.constr],
                                     [g.e])}),
                         mk_path(cx,sp,
                                 ["syntax", "ext", "qquote",
                                  node.get_fold_fn()])]);
    }
    ret rcall;
}

fn replace<T>(node: T, repls: [fragment], ff: fn (ast_fold, T) -> T)
    -> T
{
    let aft = default_ast_fold();
    let f_pre = @{fold_expr: bind replace_expr(repls, _, _, _,
                                               aft.fold_expr),
                  fold_ty: bind replace_ty(repls, _, _, _,
                                           aft.fold_ty)
                  with *aft};
    ret ff(make_fold(f_pre), node);
}
fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
    @f.fold_crate(*n)
}
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {f.fold_item(n)}
fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)}
fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)}

fn replace_expr(repls: [fragment],
                e: ast::expr_, s: span, fld: ast_fold,
                orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
    -> (ast::expr_, span)
{
    alt e {
      ast::expr_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_expr(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn replace_ty(repls: [fragment],
                e: ast::ty_, s: span, fld: ast_fold,
                orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span))
    -> (ast::ty_, span)
{
    alt e {
      ast::ty_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_ty(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn print_expr(expr: @ast::expr) {
    let stdout = io::stdout();
    let pp = pprust::rust_printer(stdout);
    pprust::print_expr(pp, expr);
    pp::eof(pp.s);
    stdout.write_str("\n");
}

fn mk_file_substr(fname: str, line: uint, col: uint) -> codemap::file_substr {
    codemap::fss_external({filename: fname, line: line, col: col})
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


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

extern mod std;

use core::io;
use std::time;
use std::treemap::TreeMap;
use core::hashmap::linear::{LinearMap, LinearSet};
use core::trie::TrieMap;

fn timed(label: &str, f: &fn()) {
    let start = time::precise_time_s();
    f();
    let end = time::precise_time_s();
    io::println(fmt!("  %s: %f", label, end - start));
}

fn ascending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Ascending integers:");

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn descending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Descending integers:");

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn vector<M: Map<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(dist[i], i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&dist[i]).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&dist[i]));
        }
    }
}

fn main() {
    let args = os::args();
    let n_keys = {
        if args.len() == 2 {
            uint::from_str(args[1]).get()
        } else {
            1000000
        }
    };

    let mut rand = vec::with_capacity(n_keys);

    {
        let rng = core::rand::seeded_rng([1, 1, 1, 1, 1, 1, 1]);
        let mut set = LinearSet::new();
        while set.len() != n_keys {
            let next = rng.next() as uint;
            if set.insert(next) {
                rand.push(next);
            }
        }
    }

    io::println(fmt!("%? keys", n_keys));

    io::println("\nTreeMap:");

    {
        let mut map = TreeMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TreeMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TreeMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nLinearMap:");

    {
        let mut map = LinearMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = LinearMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = LinearMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nTrieMap:");

    {
        let mut map = TrieMap::new::<uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TrieMap::new::<uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TrieMap::new::<uint>();
        vector(&mut map, n_keys, rand);
    }
}
<commit_msg>fix the core-map benchmark's descending range<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod std;

use core::io;
use std::time;
use std::treemap::TreeMap;
use core::hashmap::linear::{LinearMap, LinearSet};
use core::trie::TrieMap;

fn timed(label: &str, f: &fn()) {
    let start = time::precise_time_s();
    f();
    let end = time::precise_time_s();
    io::println(fmt!("  %s: %f", label, end - start));
}

fn ascending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Ascending integers:");

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn descending<M: Map<uint, uint>>(map: &mut M, n_keys: uint) {
    io::println(" Descending integers:");

    do timed("insert") {
        for uint::range_rev(n_keys, 0) |i| {
            map.insert(i, i + 1);
        }
    }

    do timed("search") {
        for uint::range_rev(n_keys, 0) |i| {
            fail_unless!(map.find(&i).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range_rev(n_keys, 0) |i| {
            fail_unless!(map.remove(&i));
        }
    }
}

fn vector<M: Map<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {

    do timed("insert") {
        for uint::range(0, n_keys) |i| {
            map.insert(dist[i], i + 1);
        }
    }

    do timed("search") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.find(&dist[i]).unwrap() == &(i + 1));
        }
    }

    do timed("remove") {
        for uint::range(0, n_keys) |i| {
            fail_unless!(map.remove(&dist[i]));
        }
    }
}

fn main() {
    let args = os::args();
    let n_keys = {
        if args.len() == 2 {
            uint::from_str(args[1]).get()
        } else {
            1000000
        }
    };

    let mut rand = vec::with_capacity(n_keys);

    {
        let rng = core::rand::seeded_rng([1, 1, 1, 1, 1, 1, 1]);
        let mut set = LinearSet::new();
        while set.len() != n_keys {
            let next = rng.next() as uint;
            if set.insert(next) {
                rand.push(next);
            }
        }
    }

    io::println(fmt!("%? keys", n_keys));

    io::println("\nTreeMap:");

    {
        let mut map = TreeMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TreeMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TreeMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nLinearMap:");

    {
        let mut map = LinearMap::new::<uint, uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = LinearMap::new::<uint, uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = LinearMap::new::<uint, uint>();
        vector(&mut map, n_keys, rand);
    }

    io::println("\nTrieMap:");

    {
        let mut map = TrieMap::new::<uint>();
        ascending(&mut map, n_keys);
    }

    {
        let mut map = TrieMap::new::<uint>();
        descending(&mut map, n_keys);
    }

    {
        io::println(" Random integers:");
        let mut map = TrieMap::new::<uint>();
        vector(&mut map, n_keys, rand);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a missing file that defines the `Unit` type.<commit_after>use traits::geometry::Norm;

/// A wrapper that ensures the undelying algebraic entity has a unit norm.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Unit<T> {
    v: T
}

impl<T: Norm> Unit<T> {
    /// Normalize the given value and return it wrapped on a `Unit` structure.
    #[inline]
    pub fn new(v: &T) -> Self {
        Unit { v: v.normalize() }
    }

    /// Attempts to normalize the given value and return it wrapped on a `Unit` structure.
    ///
    /// Returns `None` if the norm was smaller or equal to `min_norm`.
    #[inline]
    pub fn try_new(v: &T, min_norm: T::NormType) -> Option<Self> {
        v.try_normalize(min_norm).map(|v| Unit { v: v })
    }

    /// Normalize the given value and return it wrapped on a `Unit` structure and its norm.
    #[inline]
    pub fn new_and_get(mut v: T) -> (Self, T::NormType) {
        let n = v.normalize_mut();

        (Unit { v: v }, n)
    }

    /// Normalize the given value and return it wrapped on a `Unit` structure and its norm.
    ///
    /// Returns `None` if the norm was smaller or equal to `min_norm`.
    #[inline]
    pub fn try_new_and_get(mut v: T, min_norm: T::NormType) -> Option<(Self, T::NormType)> {
        if let Some(n) = v.try_normalize_mut(min_norm) {
            Some((Unit { v: v }, n))
        }
        else {
            None
        }
    }

    /// Normalizes this value again. This is useful when repeated computations
    /// might cause a drift in the norm because of float inaccuracies.
    ///
    /// Returns the norm beform re-normalization (should be close to `1.0`).
    #[inline]
    pub fn renormalize(&mut self) -> T::NormType {
        self.v.normalize_mut()
    }
}

impl<T> Unit<T> {
    /// Wraps the given value, assuming it is already normalized.
    ///
    /// This function is not safe because `v` is not verified to be actually normalized.
    #[inline]
    pub fn from_unit_value_unchecked(v: T) -> Self {
        Unit { v: v }
    }

    /// Retrieves the underlying value.
    #[inline]
    pub fn unwrap(self) -> T {
        self.v
    }
}

impl<T> AsRef<T> for Unit<T> {
    #[inline]
    fn as_ref(&self) -> &T {
        &self.v
    }
}
<|endoftext|>


<commit_before><commit_msg>Closes #24954<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.

macro_rules! foo {
    ($y:expr) => ({
        $y = 2;
    })
}

#[allow(unused_variables)]
#[allow(unused_assignments)]
fn main() {
    let mut x = 1;
    foo!(x);
}
<|endoftext|>


<commit_before><commit_msg>lnk example to view lnk strucure<commit_after>use std::io::Cursor;
extern crate rustylnk;
use rustylnk::lnkpkg::lnk;

fn lnk_test() {
    let buffer: &[u8] = &[
        0x4C,0x00,0x00,0x00,0x01,0x14,0x02,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
        0x00,0x00,0x00,0x46,0x9B,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x14,0xD5,0xA5,0x67,
        0x78,0xFD,0xCC,0x01,0x7D,0x84,0x6B,0xDE,0xAF,0x03,0xCD,0x01,0x40,0x52,0xED,0x67,
        0x78,0xFD,0xCC,0x01,0xFA,0x0A,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
        0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x01,0x14,0x00,
        0x1F,0x48,0xBA,0x8F,0x0D,0x45,0x25,0xAD,0xD0,0x11,0x98,0xA8,0x08,0x00,0x36,0x1B,
        0x11,0x03,0x4C,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x6C,0x40,0x62,0xAB,0x10,0x00,
        0x41,0x4C,0x4C,0x4F,0x59,0x52,0x7E,0x31,0x00,0x00,0x34,0x00,0x03,0x00,0x04,0x00,
        0xEF,0xBE,0x69,0x40,0x3A,0x8D,0x70,0x40,0x6B,0xA0,0x14,0x00,0x00,0x00,0x41,0x00,
        0x6C,0x00,0x6C,0x00,0x6F,0x00,0x79,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,
        0x65,0x00,0x61,0x00,0x72,0x00,0x63,0x00,0x68,0x00,0x00,0x00,0x18,0x00,0x54,0x00,
        0x31,0x00,0x00,0x00,0x00,0x00,0x70,0x40,0x72,0xA0,0x10,0x00,0x44,0x45,0x54,0x41,
        0x49,0x4C,0x7E,0x31,0x00,0x00,0x3C,0x00,0x03,0x00,0x04,0x00,0xEF,0xBE,0x68,0x40,
        0x5A,0xB1,0x70,0x40,0x72,0xA0,0x14,0x00,0x00,0x00,0x44,0x00,0x65,0x00,0x74,0x00,
        0x61,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x44,0x00,0x6F,0x00,
        0x63,0x00,0x75,0x00,0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x00,0x00,
        0x18,0x00,0x80,0x00,0x32,0x00,0xFA,0x0A,0x01,0x00,0x68,0x40,0x6E,0xB1,0x20,0x00,
        0x43,0x4F,0x50,0x59,0x4F,0x46,0x7E,0x31,0x2E,0x58,0x4C,0x53,0x00,0x00,0x64,0x00,
        0x03,0x00,0x04,0x00,0xEF,0xBE,0x68,0x40,0x6E,0xB1,0x70,0x40,0x70,0xA0,0x14,0x00,
        0x00,0x00,0x43,0x00,0x6F,0x00,0x70,0x00,0x79,0x00,0x20,0x00,0x6F,0x00,0x66,0x00,
        0x20,0x00,0x4D,0x00,0x65,0x00,0x74,0x00,0x61,0x00,0x6C,0x00,0x20,0x00,0x41,0x00,
        0x6C,0x00,0x6C,0x00,0x6F,0x00,0x79,0x00,0x20,0x00,0x4C,0x00,0x69,0x00,0x73,0x00,
        0x74,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,0x61,0x00,0x72,0x00,
        0x63,0x00,0x68,0x00,0x2E,0x00,0x78,0x00,0x6C,0x00,0x73,0x00,0x78,0x00,0x00,0x00,
        0x1C,0x00,0x00,0x00,0xA6,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
        0x1C,0x00,0x00,0x00,0x2D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0x00,0x00,0x00,
        0x11,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x22,0x4C,0x17,0x20,0x10,0x00,0x00,0x00,
        0x00,0x43,0x3A,0x5C,0x44,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,0x73,0x20,0x61,0x6E,
        0x64,0x20,0x53,0x65,0x74,0x74,0x69,0x6E,0x67,0x73,0x5C,0x74,0x64,0x75,0x6E,0x67,
        0x61,0x6E,0x5C,0x4D,0x79,0x20,0x44,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,0x73,0x5C,
        0x41,0x6C,0x6C,0x6F,0x79,0x20,0x52,0x65,0x73,0x65,0x61,0x72,0x63,0x68,0x5C,0x44,
        0x65,0x74,0x61,0x69,0x6C,0x65,0x64,0x20,0x44,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,
        0x73,0x5C,0x43,0x6F,0x70,0x79,0x20,0x6F,0x66,0x20,0x4D,0x65,0x74,0x61,0x6C,0x20,
        0x41,0x6C,0x6C,0x6F,0x79,0x20,0x4C,0x69,0x73,0x74,0x20,0x52,0x65,0x73,0x65,0x61,
        0x72,0x63,0x68,0x2E,0x78,0x6C,0x73,0x78,0x00,0x00,0x58,0x00,0x2E,0x00,0x2E,0x00,
        0x5C,0x00,0x4D,0x00,0x79,0x00,0x20,0x00,0x44,0x00,0x6F,0x00,0x63,0x00,0x75,0x00,
        0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x5C,0x00,0x41,0x00,0x6C,0x00,
        0x6C,0x00,0x6F,0x00,0x79,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,
        0x61,0x00,0x72,0x00,0x63,0x00,0x68,0x00,0x5C,0x00,0x44,0x00,0x65,0x00,0x74,0x00,
        0x61,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x44,0x00,0x6F,0x00,
        0x63,0x00,0x75,0x00,0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x5C,0x00,
        0x43,0x00,0x6F,0x00,0x70,0x00,0x79,0x00,0x20,0x00,0x6F,0x00,0x66,0x00,0x20,0x00,
        0x4D,0x00,0x65,0x00,0x74,0x00,0x61,0x00,0x6C,0x00,0x20,0x00,0x41,0x00,0x6C,0x00,
        0x6C,0x00,0x6F,0x00,0x79,0x00,0x20,0x00,0x4C,0x00,0x69,0x00,0x73,0x00,0x74,0x00,
        0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,0x61,0x00,0x72,0x00,0x63,0x00,
        0x68,0x00,0x2E,0x00,0x78,0x00,0x6C,0x00,0x73,0x00,0x78,0x00,0x50,0x00,0x43,0x00,
        0x3A,0x00,0x5C,0x00,0x44,0x00,0x6F,0x00,0x63,0x00,0x75,0x00,0x6D,0x00,0x65,0x00,
        0x6E,0x00,0x74,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x6E,0x00,0x64,0x00,0x20,0x00,
        0x53,0x00,0x65,0x00,0x74,0x00,0x74,0x00,0x69,0x00,0x6E,0x00,0x67,0x00,0x73,0x00,
        0x5C,0x00,0x74,0x00,0x64,0x00,0x75,0x00,0x6E,0x00,0x67,0x00,0x61,0x00,0x6E,0x00,
        0x5C,0x00,0x4D,0x00,0x79,0x00,0x20,0x00,0x44,0x00,0x6F,0x00,0x63,0x00,0x75,0x00,
        0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x5C,0x00,0x41,0x00,0x6C,0x00,
        0x6C,0x00,0x6F,0x00,0x79,0x00,0x20,0x00,0x52,0x00,0x65,0x00,0x73,0x00,0x65,0x00,
        0x61,0x00,0x72,0x00,0x63,0x00,0x68,0x00,0x5C,0x00,0x44,0x00,0x65,0x00,0x74,0x00,
        0x61,0x00,0x69,0x00,0x6C,0x00,0x65,0x00,0x64,0x00,0x20,0x00,0x44,0x00,0x6F,0x00,
        0x63,0x00,0x75,0x00,0x6D,0x00,0x65,0x00,0x6E,0x00,0x74,0x00,0x73,0x00,0x10,0x00,
        0x00,0x00,0x05,0x00,0x00,0xA0,0x05,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x60,0x00,
        0x00,0x00,0x03,0x00,0x00,0xA0,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x77,0x6B,
        0x73,0x2D,0x77,0x69,0x6E,0x78,0x70,0x33,0x32,0x62,0x69,0x74,0x00,0x00,0x4E,0xEB,
        0xCB,0x79,0x9D,0xF2,0x0C,0x4A,0xA7,0x0E,0xE5,0x64,0x7A,0x53,0x97,0x0B,0x7C,0x75,
        0x19,0xD9,0xD3,0x66,0xE1,0x11,0xA3,0xF6,0x00,0x50,0x56,0xA5,0x00,0x10,0x4E,0xEB,
        0xCB,0x79,0x9D,0xF2,0x0C,0x4A,0xA7,0x0E,0xE5,0x64,0x7A,0x53,0x97,0x0B,0x7C,0x75,
        0x19,0xD9,0xD3,0x66,0xE1,0x11,0xA3,0xF6,0x00,0x50,0x56,0xA5,0x00,0x10,0x00,0x00,
        0x00,0x00
    ];

    let lnk_file = match lnk::Lnk::new(Cursor::new(buffer)) {
        Ok(lnk) => lnk,
        Err(error) => panic!(error)
    };

    println!("{:#?}",lnk_file);
}

fn main(){
    lnk_test()
}
<|endoftext|>


<commit_before><commit_msg>Failing test<commit_after>#![feature(const_trait_impl)]
#![feature(const_mut_refs)]
#![feature(const_fn_trait_bound)]

struct NonTrivialDrop;

impl Drop for NonTrivialDrop {
    fn drop(&mut self) {
        println!("Non trivial drop");
    }
}

struct ConstImplWithDropGlue(NonTrivialDrop);

impl const Drop for ConstImplWithDropGlue {
    fn drop(&mut self) {}
}

const fn check<T: ~const Drop>() {}

macro_rules! check_all {
    ($($T:ty),*$(,)?) => {$(
        const _: () = check::<$T>();
    )*};
}

check_all! {
    ConstImplWithDropGlue,
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add more tests for ja_translator<commit_after>#![cfg(test)]

extern crate chrono;
extern crate tina;

use chrono::*;
use tina::*;

fn make_base_eew() -> EEW
{
	EEW {
		issue_pattern: IssuePattern::HighAccuracy, source: Source::Tokyo, kind: Kind::Normal,
		issued_at: UTC.ymd(2010, 1, 1).and_hms(1, 0, 2),
		occurred_at: UTC.ymd(2010, 1, 1).and_hms(0, 55, 59),
		id: "ND20100101005559".to_owned(), status: Status::Normal, number: 10,
		detail: Some(make_base_eew_detail()),
	}
}

fn make_base_eew_detail() -> EEWDetail
{
	EEWDetail {
		epicenter_name: "奈良県".to_owned(), epicenter: (34.4, 135.7),
		depth: Some(10.0), magnitude: Some(5.9),
		maximum_intensity: Some(IntensityClass::FiveLower),
		epicenter_accuracy: EpicenterAccuracy::GridSearchLow,
		depth_accuracy: DepthAccuracy::GridSearchLow,
		magnitude_accuracy: MagnitudeAccuracy::SWave,
		epicenter_category: EpicenterCategory::Land,
		warning_status: WarningStatus::Forecast,
		intensity_change: IntensityChange::Unknown,
		change_reason: ChangeReason::Unknown,
		area_info: vec!{},
	}
}

#[test]
fn it_should_format_eew_with_south_west_epicenter()
{
	let eew = EEW {
		detail: Some(EEWDetail {
			epicenter: (-34.4, -135.7),
			.. make_base_eew().detail.unwrap()
		}),
		.. make_base_eew()
	};

	let expected =
		"[予報] 奈良県 震度5弱 M5.9 10km (S34.4/W135.7) 09:55:59発生 \
		| 第10報 ND20100101005559".to_owned();

	let result = ja_format_eew_short(&eew, None);

	assert_eq!(result, Some(expected));
}

#[test]
fn it_should_format_drill_eew()
{
	let eew = EEW {
		kind: Kind::Drill,
		.. make_base_eew()
	};

	let expected =
		"[訓練 | 予報] 奈良県 震度5弱 M5.9 10km (N34.4/E135.7) 09:55:59発生 \
		| 第10報 ND20100101005559".to_owned();

	let result = ja_format_eew_short(&eew, None);

	assert_eq!(result, Some(expected));
}

#[test]
fn it_should_format_drill_cancel_eew()
{
	let eew = EEW {
		issue_pattern: IssuePattern::Cancel,
		kind: Kind::DrillCancel,
		detail: None,
		.. make_base_eew()
	};

	let expected =
		"[訓練 | 取消] --- | 第10報 ND20100101005559".to_owned();

	let result = ja_format_eew_short(&eew, None);

	assert_eq!(result, Some(expected));
}

#[test]
fn it_should_format_reference_eew()
{
	let eew = EEW {
		kind: Kind::Reference,
		.. make_base_eew()
	};

	let expected =
		"[テスト配信 | 予報] 奈良県 震度5弱 M5.9 10km (N34.4/E135.7) 09:55:59発生 \
		| 第10報 ND20100101005559".to_owned();

	let result = ja_format_eew_short(&eew, None);

	assert_eq!(result, Some(expected));
}

#[test]
fn it_should_format_trial_eew()
{
	let eew = EEW {
		kind: Kind::Trial,
		.. make_base_eew()
	};

	let expected =
		"[テスト配信 | 予報] 奈良県 震度5弱 M5.9 10km (N34.4/E135.7) 09:55:59発生 \
		| 第10報 ND20100101005559".to_owned();

	let result = ja_format_eew_short(&eew, None);

	assert_eq!(result, Some(expected));
}
<|endoftext|>


<commit_before><commit_msg>added Rust code<commit_after>fn main() {
  let mut s = 0i64;
  println!("START!");
  for i in 0..100000 {
    s += (1..1001).map(|q| q+10+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+11+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+12+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+13+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+14+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+15+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+16+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+17+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+18+i).collect::<Vec<i64>>()[9];
    s += (1..1001).map(|q| q+19+i).collect::<Vec<i64>>()[9];

    //s += (1..1000).map(|q| q+10+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+11+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+12+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+13+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+14+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+15+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+16+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+17+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+18+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
    //s += (1..1000).map(|q| q+19+i).nth(9).unwrap();//.collect::<Vec<i64>>()[9];
  }
  println!("{}", s);
}
<|endoftext|>


<commit_before><commit_msg>Add rustdoc comment<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor: cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>added windowed()<commit_after>// Kevin Cantu
// additional vector functions

use std;

fn windowed <copy TT> (nn: uint, xx: [TT]) -> [[TT]] {
   let ww = [];

   if nn < 1u {
      fail "windowed: n should be >= 1";
   }

   vec::iteri (xx, {|ii, _x|
      let len = vec::len(xx);

      if ii+nn <= len {
         let w = vec::slice ( xx, ii, ii+nn );
         vec::push (ww, w);
      }
   });

   ret ww;
}

#[test]
fn windowed_test_3of6 () {
   assert [[1u,2u,3u],[2u,3u,4u],[3u,4u,5u],[4u,5u,6u]]
          == windowed (3u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_4of6 () {
   assert [[1u,2u,3u,4u],[2u,3u,4u,5u],[3u,4u,5u,6u]]
          == windowed (4u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
#[should_fail]
fn windowed_test_0of6 () {
   let _x = windowed (0u, [1u,2u,3u,4u,5u,6u]);
}

#[test]
fn windowed_test_7of6 () {
   assert [] == windowed (7u, [1u,2u,3u,4u,5u,6u]);
}

<|endoftext|>


<commit_before><commit_msg>Create tokenizer<commit_after>use std::path::Path;
use std::io::fs::File;
use std::os;

fn main() {
    let args = os::args();

    if args.len() != 2 {
        fail!("invalid argument");
    }

    let path: Path = Path::new(args[1]);
    let file: File = File::open(&path).unwrap();
}

fn tokenize(text: ~str) -> Vec<Token> {
    let mut tokens: Vec<Token> = Vec::new();
    for c in text.chars() {
       match c {
           '>' => {tokens.push(Right)},
           '<' => {tokens.push(Left)},
           '+' => {tokens.push(Plus)},
           '-' => {tokens.push(Minus)},
           '.' => {tokens.push(Out)},
           ',' => {tokens.push(In)},
           '[' => {tokens.push(Jump)},
           ']' => {tokens.push(Loop)},
           _ => {}
       };
    }

    return tokens;
}

#[deriving(Clone, Eq, Show, TotalEq)]
enum Token {
    Right,
    Left,
    Plus,
    Minus,
    Out,
    In,
    Jump,
    Loop
}

#[test]
fn testTokenizer() {
    assert_eq!(tokenize("><+-.,[]".to_owned()).as_slice(),
               [Right, Left, Plus, Minus, Out, In, Jump, Loop].as_slice());

    assert_eq!(tokenize(">a<b+c-d. ,1[2]3 ".to_owned()).as_slice(),
               [Right, Left, Plus, Minus, Out, In, Jump, Loop].as_slice());
}
<|endoftext|>


<commit_before><commit_msg>Pass const data and the assembler into write_elf() as params<commit_after><|endoftext|>