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

//! "Object safety" refers to the ability for a trait to be converted
//! to an object. In general, traits may only be converted to an
//! object if all of their methods meet certain criteria. In particular,
//! they must:
//!
//!   - have a suitable receiver from which we can extract a vtable;
//!   - not reference the erased type `Self` except for in this receiver;
//!   - not have generic type parameters

use super::elaborate_predicates;

use hir::def_id::DefId;
use traits;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::subst::Substs;
use std::borrow::Cow;
use syntax::ast;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation {
    /// Self : Sized declared on the trait
    SizedSelf,

    /// Supertrait reference references `Self` an in illegal location
    /// (e.g. `trait Foo : Bar<Self>`)
    SupertraitSelf,

    /// Method has something illegal
    Method(ast::Name, MethodViolationCode),
}

impl ObjectSafetyViolation {
    pub fn error_msg(&self) -> Cow<'static, str> {
        match *self {
            ObjectSafetyViolation::SizedSelf =>
                "the trait cannot require that `Self : Sized`".into(),
            ObjectSafetyViolation::SupertraitSelf =>
                "the trait cannot use `Self` as a type parameter \
                 in the supertraits or where-clauses".into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
                format!("method `{}` has no receiver", name).into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
                format!("method `{}` references the `Self` type \
                         in its arguments or return type", name).into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
                format!("method `{}` has generic type parameters", name).into(),
        }
    }
}

/// Reasons a method might not be object-safe.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum MethodViolationCode {
    /// e.g., `fn foo()`
    StaticMethod,

    /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
    ReferencesSelf,

    /// e.g., `fn foo<A>()`
    Generic,
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
    pub fn is_object_safe(self, trait_def_id: DefId) -> bool {
        // Because we query yes/no results frequently, we keep a cache:
        let def = self.lookup_trait_def(trait_def_id);

        let result = def.object_safety().unwrap_or_else(|| {
            let result = self.object_safety_violations(trait_def_id).is_empty();

            // Record just a yes/no result in the cache; this is what is
            // queried most frequently. Note that this may overwrite a
            // previous result, but always with the same thing.
            def.set_object_safety(result);

            result
        });

        debug!("is_object_safe({:?}) = {}", trait_def_id, result);

        result
    }

    /// Returns the object safety violations that affect
    /// astconv - currently, Self in supertraits. This is needed
    /// because `object_safety_violations` can't be used during
    /// type collection.
    pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
                                            -> Vec<ObjectSafetyViolation>
    {
        let mut violations = vec![];

        for def_id in traits::supertrait_def_ids(self, trait_def_id) {
            if self.predicates_reference_self(def_id, true) {
                violations.push(ObjectSafetyViolation::SupertraitSelf);
            }
        }

        debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
               trait_def_id,
               violations);

        violations
    }

    pub fn object_safety_violations(self, trait_def_id: DefId)
                                    -> Vec<ObjectSafetyViolation>
    {
        traits::supertrait_def_ids(self, trait_def_id)
            .flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
            .collect()
    }

    fn object_safety_violations_for_trait(self, trait_def_id: DefId)
                                          -> Vec<ObjectSafetyViolation>
    {
        // Check methods for violations.
        let mut violations: Vec<_> = self.associated_items(trait_def_id)
            .filter(|item| item.kind == ty::AssociatedKind::Method)
            .filter_map(|item| {
                self.object_safety_violation_for_method(trait_def_id, &item)
                    .map(|code| ObjectSafetyViolation::Method(item.name, code))
            }).collect();

        // Check the trait itself.
        if self.trait_has_sized_self(trait_def_id) {
            violations.push(ObjectSafetyViolation::SizedSelf);
        }
        if self.predicates_reference_self(trait_def_id, false) {
            violations.push(ObjectSafetyViolation::SupertraitSelf);
        }

        debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
               trait_def_id,
               violations);

        violations
    }

    fn predicates_reference_self(
        self,
        trait_def_id: DefId,
        supertraits_only: bool) -> bool
    {
        let trait_ref = ty::Binder(ty::TraitRef {
            def_id: trait_def_id,
            substs: Substs::identity_for_item(self, trait_def_id)
        });
        let predicates = if supertraits_only {
            self.item_super_predicates(trait_def_id)
        } else {
            self.item_predicates(trait_def_id)
        };
        predicates
            .predicates
            .into_iter()
            .map(|predicate| predicate.subst_supertrait(self, &trait_ref))
            .any(|predicate| {
                match predicate {
                    ty::Predicate::Trait(ref data) => {
                        // In the case of a trait predicate, we can skip the "self" type.
                        data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
                    }
                    ty::Predicate::Projection(..) |
                    ty::Predicate::WellFormed(..) |
                    ty::Predicate::ObjectSafe(..) |
                    ty::Predicate::TypeOutlives(..) |
                    ty::Predicate::RegionOutlives(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::Equate(..) => {
                        false
                    }
                }
            })
    }

    fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
        self.generics_require_sized_self(trait_def_id)
    }

    fn generics_require_sized_self(self, def_id: DefId) -> bool {
        let sized_def_id = match self.lang_items.sized_trait() {
            Some(def_id) => def_id,
            None => { return false; /* No Sized trait, can't require it! */ }
        };

        // Search for a predicate like `Self : Sized` amongst the trait bounds.
        let free_substs = self.construct_free_substs(def_id,
            self.region_maps.node_extent(ast::DUMMY_NODE_ID));
        let predicates = self.item_predicates(def_id);
        let predicates = predicates.instantiate(self, free_substs).predicates;
        elaborate_predicates(self, predicates)
            .any(|predicate| {
                match predicate {
                    ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
                        trait_pred.0.self_ty().is_self()
                    }
                    ty::Predicate::Projection(..) |
                    ty::Predicate::Trait(..) |
                    ty::Predicate::Equate(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::RegionOutlives(..) |
                    ty::Predicate::WellFormed(..) |
                    ty::Predicate::ObjectSafe(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::TypeOutlives(..) => {
                        false
                    }
                }
            })
    }

    /// Returns `Some(_)` if this method makes the containing trait not object safe.
    fn object_safety_violation_for_method(self,
                                          trait_def_id: DefId,
                                          method: &ty::AssociatedItem)
                                          -> Option<MethodViolationCode>
    {
        // Any method that has a `Self : Sized` requisite is otherwise
        // exempt from the regulations.
        if self.generics_require_sized_self(method.def_id) {
            return None;
        }

        self.virtual_call_violation_for_method(trait_def_id, method)
    }

    /// We say a method is *vtable safe* if it can be invoked on a trait
    /// object.  Note that object-safe traits can have some
    /// non-vtable-safe methods, so long as they require `Self:Sized` or
    /// otherwise ensure that they cannot be used when `Self=Trait`.
    pub fn is_vtable_safe_method(self,
                                 trait_def_id: DefId,
                                 method: &ty::AssociatedItem)
                                 -> bool
    {
        // Any method that has a `Self : Sized` requisite can't be called.
        if self.generics_require_sized_self(method.def_id) {
            return false;
        }

        self.virtual_call_violation_for_method(trait_def_id, method).is_none()
    }

    /// Returns `Some(_)` if this method cannot be called on a trait
    /// object; this does not necessarily imply that the enclosing trait
    /// is not object safe, because the method might have a where clause
    /// `Self:Sized`.
    fn virtual_call_violation_for_method(self,
                                         trait_def_id: DefId,
                                         method: &ty::AssociatedItem)
                                         -> Option<MethodViolationCode>
    {
        // The method's first parameter must be something that derefs (or
        // autorefs) to `&self`. For now, we only accept `self`, `&self`
        // and `Box<Self>`.
        if !method.method_has_self_argument {
            return Some(MethodViolationCode::StaticMethod);
        }

        // The `Self` type is erased, so it should not appear in list of
        // arguments or return type apart from the receiver.
        let ref sig = self.item_type(method.def_id).fn_sig();
        for input_ty in &sig.skip_binder().inputs()[1..] {
            if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
                return Some(MethodViolationCode::ReferencesSelf);
            }
        }
        if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
            return Some(MethodViolationCode::ReferencesSelf);
        }

        // We can't monomorphize things like `fn foo<A>(...)`.
        if !self.item_generics(method.def_id).types.is_empty() {
            return Some(MethodViolationCode::Generic);
        }

        None
    }

    fn contains_illegal_self_type_reference(self,
                                            trait_def_id: DefId,
                                            ty: Ty<'tcx>)
                                            -> bool
    {
        // This is somewhat subtle. In general, we want to forbid
        // references to `Self` in the argument and return types,
        // since the value of `Self` is erased. However, there is one
        // exception: it is ok to reference `Self` in order to access
        // an associated type of the current trait, since we retain
        // the value of those associated types in the object type
        // itself.
        //
        // ```rust
        // trait SuperTrait {
        //     type X;
        // }
        //
        // trait Trait : SuperTrait {
        //     type Y;
        //     fn foo(&self, x: Self) // bad
        //     fn foo(&self) -> Self // bad
        //     fn foo(&self) -> Option<Self> // bad
        //     fn foo(&self) -> Self::Y // OK, desugars to next example
        //     fn foo(&self) -> <Self as Trait>::Y // OK
        //     fn foo(&self) -> Self::X // OK, desugars to next example
        //     fn foo(&self) -> <Self as SuperTrait>::X // OK
        // }
        // ```
        //
        // However, it is not as simple as allowing `Self` in a projected
        // type, because there are illegal ways to use `Self` as well:
        //
        // ```rust
        // trait Trait : SuperTrait {
        //     ...
        //     fn foo(&self) -> <Self as SomeOtherTrait>::X;
        // }
        // ```
        //
        // Here we will not have the type of `X` recorded in the
        // object type, and we cannot resolve `Self as SomeOtherTrait`
        // without knowing what `Self` is.

        let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
        let mut error = false;
        ty.maybe_walk(|ty| {
            match ty.sty {
                ty::TyParam(ref param_ty) => {
                    if param_ty.is_self() {
                        error = true;
                    }

                    false // no contained types to walk
                }

                ty::TyProjection(ref data) => {
                    // This is a projected type `<Foo as SomeTrait>::X`.

                    // Compute supertraits of current trait lazily.
                    if supertraits.is_none() {
                        let trait_ref = ty::Binder(ty::TraitRef {
                            def_id: trait_def_id,
                            substs: Substs::identity_for_item(self, trait_def_id)
                        });
                        supertraits = Some(traits::supertraits(self, trait_ref).collect());
                    }

                    // Determine whether the trait reference `Foo as
                    // SomeTrait` is in fact a supertrait of the
                    // current trait. In that case, this type is
                    // legal, because the type `X` will be specified
                    // in the object type.  Note that we can just use
                    // direct equality here because all of these types
                    // are part of the formal parameter listing, and
                    // hence there should be no inference variables.
                    let projection_trait_ref = ty::Binder(data.trait_ref.clone());
                    let is_supertrait_of_current_trait =
                        supertraits.as_ref().unwrap().contains(&projection_trait_ref);

                    if is_supertrait_of_current_trait {
                        false // do not walk contained types, do not report error, do collect $200
                    } else {
                        true // DO walk contained types, POSSIBLY reporting an error
                    }
                }

                _ => true, // walk contained types, if any
            }
        });

        error
    }
}
<commit_msg>Associated consts are not object safe.<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.

//! "Object safety" refers to the ability for a trait to be converted
//! to an object. In general, traits may only be converted to an
//! object if all of their methods meet certain criteria. In particular,
//! they must:
//!
//!   - have a suitable receiver from which we can extract a vtable;
//!   - not reference the erased type `Self` except for in this receiver;
//!   - not have generic type parameters

use super::elaborate_predicates;

use hir::def_id::DefId;
use traits;
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::subst::Substs;
use std::borrow::Cow;
use syntax::ast;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation {
    /// Self : Sized declared on the trait
    SizedSelf,

    /// Supertrait reference references `Self` an in illegal location
    /// (e.g. `trait Foo : Bar<Self>`)
    SupertraitSelf,

    /// Method has something illegal
    Method(ast::Name, MethodViolationCode),

    /// Associated const
    AssociatedConst(ast::Name),
}

impl ObjectSafetyViolation {
    pub fn error_msg(&self) -> Cow<'static, str> {
        match *self {
            ObjectSafetyViolation::SizedSelf =>
                "the trait cannot require that `Self : Sized`".into(),
            ObjectSafetyViolation::SupertraitSelf =>
                "the trait cannot use `Self` as a type parameter \
                 in the supertraits or where-clauses".into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
                format!("method `{}` has no receiver", name).into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
                format!("method `{}` references the `Self` type \
                         in its arguments or return type", name).into(),
            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
                format!("method `{}` has generic type parameters", name).into(),
            ObjectSafetyViolation::AssociatedConst(name) =>
                format!("the trait cannot contain associated consts, such as `{}`", name),
        }
    }
}

/// Reasons a method might not be object-safe.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum MethodViolationCode {
    /// e.g., `fn foo()`
    StaticMethod,

    /// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
    ReferencesSelf,

    /// e.g., `fn foo<A>()`
    Generic,
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
    pub fn is_object_safe(self, trait_def_id: DefId) -> bool {
        // Because we query yes/no results frequently, we keep a cache:
        let def = self.lookup_trait_def(trait_def_id);

        let result = def.object_safety().unwrap_or_else(|| {
            let result = self.object_safety_violations(trait_def_id).is_empty();

            // Record just a yes/no result in the cache; this is what is
            // queried most frequently. Note that this may overwrite a
            // previous result, but always with the same thing.
            def.set_object_safety(result);

            result
        });

        debug!("is_object_safe({:?}) = {}", trait_def_id, result);

        result
    }

    /// Returns the object safety violations that affect
    /// astconv - currently, Self in supertraits. This is needed
    /// because `object_safety_violations` can't be used during
    /// type collection.
    pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
                                            -> Vec<ObjectSafetyViolation>
    {
        let mut violations = vec![];

        for def_id in traits::supertrait_def_ids(self, trait_def_id) {
            if self.predicates_reference_self(def_id, true) {
                violations.push(ObjectSafetyViolation::SupertraitSelf);
            }
        }

        debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
               trait_def_id,
               violations);

        violations
    }

    pub fn object_safety_violations(self, trait_def_id: DefId)
                                    -> Vec<ObjectSafetyViolation>
    {
        traits::supertrait_def_ids(self, trait_def_id)
            .flat_map(|def_id| self.object_safety_violations_for_trait(def_id))
            .collect()
    }

    fn object_safety_violations_for_trait(self, trait_def_id: DefId)
                                          -> Vec<ObjectSafetyViolation>
    {
        // Check methods for violations.
        let mut violations: Vec<_> = self.associated_items(trait_def_id)
            .filter(|item| item.kind == ty::AssociatedKind::Method)
            .filter_map(|item| {
                self.object_safety_violation_for_method(trait_def_id, &item)
                    .map(|code| ObjectSafetyViolation::Method(item.name, code))
            }).collect();

        // Check the trait itself.
        if self.trait_has_sized_self(trait_def_id) {
            violations.push(ObjectSafetyViolation::SizedSelf);
        }
        if self.predicates_reference_self(trait_def_id, false) {
            violations.push(ObjectSafetyViolation::SupertraitSelf);
        }

        violations.extend(self.associated_items(trait_def_id)
            .filter(|item| item.kind == ty::AssociatedKind::Const)
            .map(|item| ObjectSafetyViolation::AssociatedConst(item.name)));

        debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
               trait_def_id,
               violations);

        violations
    }

    fn predicates_reference_self(
        self,
        trait_def_id: DefId,
        supertraits_only: bool) -> bool
    {
        let trait_ref = ty::Binder(ty::TraitRef {
            def_id: trait_def_id,
            substs: Substs::identity_for_item(self, trait_def_id)
        });
        let predicates = if supertraits_only {
            self.item_super_predicates(trait_def_id)
        } else {
            self.item_predicates(trait_def_id)
        };
        predicates
            .predicates
            .into_iter()
            .map(|predicate| predicate.subst_supertrait(self, &trait_ref))
            .any(|predicate| {
                match predicate {
                    ty::Predicate::Trait(ref data) => {
                        // In the case of a trait predicate, we can skip the "self" type.
                        data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty())
                    }
                    ty::Predicate::Projection(..) |
                    ty::Predicate::WellFormed(..) |
                    ty::Predicate::ObjectSafe(..) |
                    ty::Predicate::TypeOutlives(..) |
                    ty::Predicate::RegionOutlives(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::Equate(..) => {
                        false
                    }
                }
            })
    }

    fn trait_has_sized_self(self, trait_def_id: DefId) -> bool {
        self.generics_require_sized_self(trait_def_id)
    }

    fn generics_require_sized_self(self, def_id: DefId) -> bool {
        let sized_def_id = match self.lang_items.sized_trait() {
            Some(def_id) => def_id,
            None => { return false; /* No Sized trait, can't require it! */ }
        };

        // Search for a predicate like `Self : Sized` amongst the trait bounds.
        let free_substs = self.construct_free_substs(def_id,
            self.region_maps.node_extent(ast::DUMMY_NODE_ID));
        let predicates = self.item_predicates(def_id);
        let predicates = predicates.instantiate(self, free_substs).predicates;
        elaborate_predicates(self, predicates)
            .any(|predicate| {
                match predicate {
                    ty::Predicate::Trait(ref trait_pred) if trait_pred.def_id() == sized_def_id => {
                        trait_pred.0.self_ty().is_self()
                    }
                    ty::Predicate::Projection(..) |
                    ty::Predicate::Trait(..) |
                    ty::Predicate::Equate(..) |
                    ty::Predicate::Subtype(..) |
                    ty::Predicate::RegionOutlives(..) |
                    ty::Predicate::WellFormed(..) |
                    ty::Predicate::ObjectSafe(..) |
                    ty::Predicate::ClosureKind(..) |
                    ty::Predicate::TypeOutlives(..) => {
                        false
                    }
                }
            })
    }

    /// Returns `Some(_)` if this method makes the containing trait not object safe.
    fn object_safety_violation_for_method(self,
                                          trait_def_id: DefId,
                                          method: &ty::AssociatedItem)
                                          -> Option<MethodViolationCode>
    {
        // Any method that has a `Self : Sized` requisite is otherwise
        // exempt from the regulations.
        if self.generics_require_sized_self(method.def_id) {
            return None;
        }

        self.virtual_call_violation_for_method(trait_def_id, method)
    }

    /// We say a method is *vtable safe* if it can be invoked on a trait
    /// object.  Note that object-safe traits can have some
    /// non-vtable-safe methods, so long as they require `Self:Sized` or
    /// otherwise ensure that they cannot be used when `Self=Trait`.
    pub fn is_vtable_safe_method(self,
                                 trait_def_id: DefId,
                                 method: &ty::AssociatedItem)
                                 -> bool
    {
        // Any method that has a `Self : Sized` requisite can't be called.
        if self.generics_require_sized_self(method.def_id) {
            return false;
        }

        self.virtual_call_violation_for_method(trait_def_id, method).is_none()
    }

    /// Returns `Some(_)` if this method cannot be called on a trait
    /// object; this does not necessarily imply that the enclosing trait
    /// is not object safe, because the method might have a where clause
    /// `Self:Sized`.
    fn virtual_call_violation_for_method(self,
                                         trait_def_id: DefId,
                                         method: &ty::AssociatedItem)
                                         -> Option<MethodViolationCode>
    {
        // The method's first parameter must be something that derefs (or
        // autorefs) to `&self`. For now, we only accept `self`, `&self`
        // and `Box<Self>`.
        if !method.method_has_self_argument {
            return Some(MethodViolationCode::StaticMethod);
        }

        // The `Self` type is erased, so it should not appear in list of
        // arguments or return type apart from the receiver.
        let ref sig = self.item_type(method.def_id).fn_sig();
        for input_ty in &sig.skip_binder().inputs()[1..] {
            if self.contains_illegal_self_type_reference(trait_def_id, input_ty) {
                return Some(MethodViolationCode::ReferencesSelf);
            }
        }
        if self.contains_illegal_self_type_reference(trait_def_id, sig.output().skip_binder()) {
            return Some(MethodViolationCode::ReferencesSelf);
        }

        // We can't monomorphize things like `fn foo<A>(...)`.
        if !self.item_generics(method.def_id).types.is_empty() {
            return Some(MethodViolationCode::Generic);
        }

        None
    }

    fn contains_illegal_self_type_reference(self,
                                            trait_def_id: DefId,
                                            ty: Ty<'tcx>)
                                            -> bool
    {
        // This is somewhat subtle. In general, we want to forbid
        // references to `Self` in the argument and return types,
        // since the value of `Self` is erased. However, there is one
        // exception: it is ok to reference `Self` in order to access
        // an associated type of the current trait, since we retain
        // the value of those associated types in the object type
        // itself.
        //
        // ```rust
        // trait SuperTrait {
        //     type X;
        // }
        //
        // trait Trait : SuperTrait {
        //     type Y;
        //     fn foo(&self, x: Self) // bad
        //     fn foo(&self) -> Self // bad
        //     fn foo(&self) -> Option<Self> // bad
        //     fn foo(&self) -> Self::Y // OK, desugars to next example
        //     fn foo(&self) -> <Self as Trait>::Y // OK
        //     fn foo(&self) -> Self::X // OK, desugars to next example
        //     fn foo(&self) -> <Self as SuperTrait>::X // OK
        // }
        // ```
        //
        // However, it is not as simple as allowing `Self` in a projected
        // type, because there are illegal ways to use `Self` as well:
        //
        // ```rust
        // trait Trait : SuperTrait {
        //     ...
        //     fn foo(&self) -> <Self as SomeOtherTrait>::X;
        // }
        // ```
        //
        // Here we will not have the type of `X` recorded in the
        // object type, and we cannot resolve `Self as SomeOtherTrait`
        // without knowing what `Self` is.

        let mut supertraits: Option<Vec<ty::PolyTraitRef<'tcx>>> = None;
        let mut error = false;
        ty.maybe_walk(|ty| {
            match ty.sty {
                ty::TyParam(ref param_ty) => {
                    if param_ty.is_self() {
                        error = true;
                    }

                    false // no contained types to walk
                }

                ty::TyProjection(ref data) => {
                    // This is a projected type `<Foo as SomeTrait>::X`.

                    // Compute supertraits of current trait lazily.
                    if supertraits.is_none() {
                        let trait_ref = ty::Binder(ty::TraitRef {
                            def_id: trait_def_id,
                            substs: Substs::identity_for_item(self, trait_def_id)
                        });
                        supertraits = Some(traits::supertraits(self, trait_ref).collect());
                    }

                    // Determine whether the trait reference `Foo as
                    // SomeTrait` is in fact a supertrait of the
                    // current trait. In that case, this type is
                    // legal, because the type `X` will be specified
                    // in the object type.  Note that we can just use
                    // direct equality here because all of these types
                    // are part of the formal parameter listing, and
                    // hence there should be no inference variables.
                    let projection_trait_ref = ty::Binder(data.trait_ref.clone());
                    let is_supertrait_of_current_trait =
                        supertraits.as_ref().unwrap().contains(&projection_trait_ref);

                    if is_supertrait_of_current_trait {
                        false // do not walk contained types, do not report error, do collect $200
                    } else {
                        true // DO walk contained types, POSSIBLY reporting an error
                    }
                }

                _ => true, // walk contained types, if any
            }
        });

        error
    }
}
<|endoftext|>


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

//! Prune things that are private

use core::prelude::*;

use astsrv;
use doc;
use fold::Fold;
use fold;
use pass::Pass;

use core::util;

pub fn mk_pass() -> Pass {
    Pass {
        name: ~"prune_private",
        f: run
    }
}

pub fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
    let fold = Fold {
        ctxt: srv.clone(),
        fold_mod: fold_mod,
        .. fold::default_any_fold(srv)
    };
    (fold.fold_doc)(&fold, doc)
}

fn fold_mod(
    fold: &fold::Fold<astsrv::Srv>,
    doc: doc::ModDoc
) -> doc::ModDoc {
    let doc = fold::default_any_fold_mod(fold, doc);

    doc::ModDoc {
        items: doc.items.filtered(|ItemTag| {
            is_visible(fold.ctxt.clone(), ItemTag.item())
        }),
        .. doc
    }
}

fn is_visible(srv: astsrv::Srv, doc: doc::ItemDoc) -> bool {
    use syntax::ast_map;
    use syntax::ast;

    let id = doc.id;

    do astsrv::exec(srv) |ctxt| {
        match ctxt.ast_map.get(&id) {
            ast_map::node_item(item, _) => {
                item.vis == ast::public
            }
            _ => util::unreachable()
        }
    }
}

#[test]
fn should_prune_items_without_pub_modifier() {
    let doc = test::mk_doc(~"mod a { }");
    fail_unless!(vec::is_empty(doc.cratemod().mods()));
}

#[cfg(test)]
pub mod test {
    use astsrv;
    use doc;
    use extract;
    use prune_private_pass::run;

    pub fn mk_doc(source: ~str) -> doc::Doc {
        do astsrv::from_str(copy source) |srv| {
            let doc = extract::from_srv(srv.clone(), ~"");
            run(srv.clone(), doc)
        }
    }
}

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

//! Prune things that are private

use core::prelude::*;

use astsrv;
use doc;
use fold::Fold;
use fold;
use pass::Pass;

use core::util;

pub fn mk_pass() -> Pass {
    Pass {
        name: ~"prune_private",
        f: run
    }
}

pub fn run(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc {
    let fold = Fold {
        ctxt: srv.clone(),
        fold_mod: fold_mod,
        .. fold::default_any_fold(srv)
    };
    (fold.fold_doc)(&fold, doc)
}

fn fold_mod(
    fold: &fold::Fold<astsrv::Srv>,
    doc: doc::ModDoc
) -> doc::ModDoc {
    let doc = fold::default_any_fold_mod(fold, doc);

    doc::ModDoc {
        items: doc.items.filtered(|ItemTag| {
            is_visible(fold.ctxt.clone(), ItemTag.item())
        }),
        .. doc
    }
}

fn is_visible(srv: astsrv::Srv, doc: doc::ItemDoc) -> bool {
    use syntax::ast_map;
    use syntax::ast;

    let id = doc.id;

    do astsrv::exec(srv) |ctxt| {
        match ctxt.ast_map.get(&id) {
            ast_map::node_item(item, _) => {
                match item.node {
                    ast::item_impl(_, Some(_), _, _) => {
                        // This is a trait implementation, make it visible
                        // NOTE: This is not quite right since this could be an impl
                        // of a private trait. We can't know that without running
                        // resolve though.
                        true
                    }
                    _ => {
                        // Otherwise just look at the visibility
                        item.vis == ast::public
                    }
                }
            }
            _ => util::unreachable()
        }
    }
}

#[test]
fn should_prune_items_without_pub_modifier() {
    let doc = test::mk_doc(~"mod a { }");
    fail_unless!(vec::is_empty(doc.cratemod().mods()));
}

#[test]
fn unless_they_are_trait_impls() {
    let doc = test::mk_doc(
        ~" \
          trait Foo { } \
          impl Foo for int { } \
          ");
    fail_unless!(!doc.cratemod().impls().is_empty());
}

#[cfg(test)]
pub mod test {
    use astsrv;
    use doc;
    use extract;
    use prune_private_pass::run;

    pub fn mk_doc(source: ~str) -> doc::Doc {
        do astsrv::from_str(copy source) |srv| {
            let doc = extract::from_srv(srv.clone(), ~"");
            run(srv.clone(), doc)
        }
    }
}

<|endoftext|>


<commit_before>use std::collections::{BitSet, BTreeSet};
use std::cell::{RefCell, Ref, RefMut};

use value::{Id};
use relation::{Change, Relation};
use view::{View, Table};
use compiler;

#[derive(Clone, Debug)]
pub struct Node {
    pub id: Id,
    pub view: View,
    pub upstream: Vec<usize>,
    pub downstream: Vec<usize>,
}

pub type Changes = Vec<(Id, Change)>;

#[derive(Clone, Debug)]
pub struct Flow {
    pub nodes: Vec<Node>,
    pub outputs: Vec<RefCell<Relation>>,
    pub dirty: BitSet,
    pub needs_recompile: bool,
}

impl Flow {
    pub fn new() -> Self {
        let flow = Flow {
            nodes: Vec::new(),
            outputs: Vec::new(),
            dirty: BitSet::new(),
            needs_recompile: true,
        };
        compiler::bootstrap(flow)
    }

    pub fn get_ix(&self, id: &str) -> Option<usize> {
        self.nodes.iter().position(|node| &node.id[..] == id)
    }

    pub fn get_output(&self, id: &str) -> Ref<Relation> {
        self.outputs[self.get_ix(id).unwrap()].borrow()
    }

    pub fn get_output_mut(&self, id: &str) -> RefMut<Relation> {
        self.outputs[self.get_ix(id).unwrap()].borrow_mut()
    }

    pub fn overwrite_output(&self, id: &str) -> RefMut<Relation> {
        let mut output = self.get_output_mut(id);
        output.index = BTreeSet::new();
        output
    }

    pub fn change(&mut self, changes: Changes) {
        let code_schema = compiler::code_schema();
        for (id, change) in changes.into_iter() {
            match self.get_ix(&*id) {
                Some(ix) => {
                    match self.nodes[ix].view {
                        View::Table(_) => (),
                        _ => println!("Warning: changing a non-table view with id: {:?}", id),
                    }
                    // TODO should we be checking diffs after the fact?
                    self.outputs[ix].borrow_mut().change(change);
                    if code_schema.iter().find(|&&(ref code_id, _)| **code_id == id).is_some() {
                        self.needs_recompile = true;
                    }
                    for ix in self.nodes[ix].downstream.iter() {
                        self.dirty.insert(*ix);
                    }
                }
                None => {
                    println!("Warning: creating a dummy view because you tried to change a non-existing view with id: {:?}", id);
                    self.nodes.push(Node{
                        id: id.to_owned(),
                        view: View::Table(Table{
                            insert:None,
                            remove:None,
                        }),
                        upstream: Vec::new(),
                        downstream: Vec::new(),
                    });
                    let fields = change.fields.clone();
                    // compiler tables will never be missing, so it's safe to just put dummy names in here
                    let names = change.fields.iter().map(|_| "".to_owned()).collect();
                    self.outputs.push(RefCell::new(Relation::new(id.to_owned(), fields, names)));
                    self.outputs[self.outputs.len()-1].borrow_mut().change(change);
                }
            }
        }
    }

    pub fn as_changes(&self) -> Changes {
        (0..self.nodes.len()).map(|ix|
            (
                self.nodes[ix].id.clone(),
                self.outputs[ix].borrow().as_insert()
            )
        ).collect()
    }

    pub fn changes_from(&self, old_self: Self) -> Changes {
        let mut changes = Vec::new();
        for (ix, node) in self.nodes.iter().enumerate() {
            match old_self.get_ix(&node.id[..]) {
                Some(old_ix) => {
                    let new_output = self.outputs[ix].borrow();
                    let old_output = old_self.outputs[old_ix].borrow();
                    if new_output.fields == old_output.fields {
                        let change = new_output.change_from(&*old_output);
                        changes.push((node.id.clone(), change));
                    } else {
                        changes.push((node.id.clone(), old_output.as_remove()));
                        changes.push((node.id.clone(), new_output.as_insert()));
                    }
                }
                None => {
                    let new_output = self.outputs[ix].borrow();
                    changes.push((node.id.clone(), new_output.as_insert()));
                }
            }
        }
        for (old_ix, old_node) in old_self.nodes.iter().enumerate() {
            match self.get_ix(&old_node.id[..]) {
                Some(_) => {
                    () // already handled above
                }
                None => {
                    let old_output = old_self.outputs[old_ix].borrow();
                    changes.push((old_node.id.clone(), old_output.as_remove()));
                }
            }
        }
        changes
    }

    pub fn recalculate(&mut self) {
        let Flow{ref nodes, ref mut outputs, ref mut dirty, ..} = *self;
        let code_schema = compiler::code_schema();
        while let Some(ix) = dirty.iter().next() {
            dirty.remove(&ix);
            let node = &nodes[ix];
            let new_output = {
                let upstream = node.upstream.iter().map(|&ix| outputs[ix].borrow()).collect::<Vec<_>>();
                let inputs = upstream.iter().map(|borrowed| &**borrowed).collect::<Vec<_>>();
                node.view.run(&*outputs[ix].borrow(), &inputs[..])
            };
            match new_output {
                None => (), // view does not want to update
                Some(new_output) => {
                    let change = new_output.change_from(&*outputs[ix].borrow());
                    if (change.insert.len() != 0) || (change.remove.len() != 0) {
                        if code_schema.iter().find(|&&(ref code_id, _)| **code_id == node.id).is_some() {
                            self.needs_recompile = true;
                        }
                        for ix in node.downstream.iter() {
                            dirty.insert(*ix);
                        }
                    }
                    outputs[ix] = RefCell::new(new_output);
                }
            }
        }
    }

    pub fn tick(&mut self) -> bool {
        let code_schema = compiler::code_schema();
        let mut flow_changed = false;
        for (ix, node) in self.nodes.iter().enumerate() {
            match node.view {
                View::Table(Table{ref insert, ref remove}) => {
                    let mut view_changed = false;
                    {
                        let upstream = node.upstream.iter().map(|ix| self.outputs[*ix].borrow()).collect::<Vec<_>>();
                        let inputs = upstream.iter().map(|borrowed| &**borrowed).collect::<Vec<_>>();
                        let mut inserts = match *insert {
                            Some(ref select) => select.select(&inputs[..]),
                            None => vec![],
                        };
                        let mut removes = match *remove {
                            Some(ref select) => select.select(&inputs[..]),
                            None => vec![],
                        };
                        inserts.sort();
                        removes.sort();
                        inserts.retain(|insert| removes.binary_search(&insert).is_err());
                        removes.retain(|remove| inserts.binary_search(&remove).is_err());
                        let mut output = self.outputs[ix].borrow_mut();
                        let mut index = &mut output.index;
                        for insert in inserts {
                            view_changed = view_changed || index.insert(insert);
                        }
                        for remove in removes {
                            view_changed = view_changed || !index.remove(&remove);
                        }
                    }
                    if view_changed {
                        if code_schema.iter().find(|&&(ref code_id, _)| **code_id == node.id).is_some() {
                            self.needs_recompile = true;
                        }
                        for ix in node.downstream.iter() {
                            self.dirty.insert(*ix);
                        }
                    }
                    flow_changed = flow_changed || view_changed;
                }
                _ => () // only tables tick
            }
        }
        flow_changed
    }

    pub fn quiesce(mut self, changes: Changes) -> Self {
        time!("changing", {
            self.change(changes);
        });
        loop {
            if self.needs_recompile {
                time!("compiling", {
                    self = compiler::recompile(self);
                });
            }
            time!("calculating", {
                self.recalculate();
            });
            let changed = time!("ticking", {
                self.tick()
            });
            if !changed {
                break
            }
        }
        self
    }
}
<commit_msg>Doh, BTreeSet.remove gives the opposite result to BTreeSet.insert<commit_after>use std::collections::{BitSet, BTreeSet};
use std::cell::{RefCell, Ref, RefMut};

use value::{Id};
use relation::{Change, Relation};
use view::{View, Table};
use compiler;

#[derive(Clone, Debug)]
pub struct Node {
    pub id: Id,
    pub view: View,
    pub upstream: Vec<usize>,
    pub downstream: Vec<usize>,
}

pub type Changes = Vec<(Id, Change)>;

#[derive(Clone, Debug)]
pub struct Flow {
    pub nodes: Vec<Node>,
    pub outputs: Vec<RefCell<Relation>>,
    pub dirty: BitSet,
    pub needs_recompile: bool,
}

impl Flow {
    pub fn new() -> Self {
        let flow = Flow {
            nodes: Vec::new(),
            outputs: Vec::new(),
            dirty: BitSet::new(),
            needs_recompile: true,
        };
        compiler::bootstrap(flow)
    }

    pub fn get_ix(&self, id: &str) -> Option<usize> {
        self.nodes.iter().position(|node| &node.id[..] == id)
    }

    pub fn get_output(&self, id: &str) -> Ref<Relation> {
        self.outputs[self.get_ix(id).unwrap()].borrow()
    }

    pub fn get_output_mut(&self, id: &str) -> RefMut<Relation> {
        self.outputs[self.get_ix(id).unwrap()].borrow_mut()
    }

    pub fn overwrite_output(&self, id: &str) -> RefMut<Relation> {
        let mut output = self.get_output_mut(id);
        output.index = BTreeSet::new();
        output
    }

    pub fn change(&mut self, changes: Changes) {
        let code_schema = compiler::code_schema();
        for (id, change) in changes.into_iter() {
            match self.get_ix(&*id) {
                Some(ix) => {
                    match self.nodes[ix].view {
                        View::Table(_) => (),
                        _ => println!("Warning: changing a non-table view with id: {:?}", id),
                    }
                    // TODO should we be checking diffs after the fact?
                    self.outputs[ix].borrow_mut().change(change);
                    if code_schema.iter().find(|&&(ref code_id, _)| **code_id == id).is_some() {
                        self.needs_recompile = true;
                    }
                    for ix in self.nodes[ix].downstream.iter() {
                        self.dirty.insert(*ix);
                    }
                }
                None => {
                    println!("Warning: creating a dummy view because you tried to change a non-existing view with id: {:?}", id);
                    self.nodes.push(Node{
                        id: id.to_owned(),
                        view: View::Table(Table{
                            insert:None,
                            remove:None,
                        }),
                        upstream: Vec::new(),
                        downstream: Vec::new(),
                    });
                    let fields = change.fields.clone();
                    // compiler tables will never be missing, so it's safe to just put dummy names in here
                    let names = change.fields.iter().map(|_| "".to_owned()).collect();
                    self.outputs.push(RefCell::new(Relation::new(id.to_owned(), fields, names)));
                    self.outputs[self.outputs.len()-1].borrow_mut().change(change);
                }
            }
        }
    }

    pub fn as_changes(&self) -> Changes {
        (0..self.nodes.len()).map(|ix|
            (
                self.nodes[ix].id.clone(),
                self.outputs[ix].borrow().as_insert()
            )
        ).collect()
    }

    pub fn changes_from(&self, old_self: Self) -> Changes {
        let mut changes = Vec::new();
        for (ix, node) in self.nodes.iter().enumerate() {
            match old_self.get_ix(&node.id[..]) {
                Some(old_ix) => {
                    let new_output = self.outputs[ix].borrow();
                    let old_output = old_self.outputs[old_ix].borrow();
                    if new_output.fields == old_output.fields {
                        let change = new_output.change_from(&*old_output);
                        changes.push((node.id.clone(), change));
                    } else {
                        changes.push((node.id.clone(), old_output.as_remove()));
                        changes.push((node.id.clone(), new_output.as_insert()));
                    }
                }
                None => {
                    let new_output = self.outputs[ix].borrow();
                    changes.push((node.id.clone(), new_output.as_insert()));
                }
            }
        }
        for (old_ix, old_node) in old_self.nodes.iter().enumerate() {
            match self.get_ix(&old_node.id[..]) {
                Some(_) => {
                    () // already handled above
                }
                None => {
                    let old_output = old_self.outputs[old_ix].borrow();
                    changes.push((old_node.id.clone(), old_output.as_remove()));
                }
            }
        }
        changes
    }

    pub fn recalculate(&mut self) {
        let Flow{ref nodes, ref mut outputs, ref mut dirty, ..} = *self;
        let code_schema = compiler::code_schema();
        while let Some(ix) = dirty.iter().next() {
            dirty.remove(&ix);
            let node = &nodes[ix];
            let new_output = {
                let upstream = node.upstream.iter().map(|&ix| outputs[ix].borrow()).collect::<Vec<_>>();
                let inputs = upstream.iter().map(|borrowed| &**borrowed).collect::<Vec<_>>();
                node.view.run(&*outputs[ix].borrow(), &inputs[..])
            };
            match new_output {
                None => (), // view does not want to update
                Some(new_output) => {
                    let change = new_output.change_from(&*outputs[ix].borrow());
                    if (change.insert.len() != 0) || (change.remove.len() != 0) {
                        if code_schema.iter().find(|&&(ref code_id, _)| **code_id == node.id).is_some() {
                            self.needs_recompile = true;
                        }
                        for ix in node.downstream.iter() {
                            dirty.insert(*ix);
                        }
                    }
                    outputs[ix] = RefCell::new(new_output);
                }
            }
        }
    }

    pub fn tick(&mut self) -> bool {
        let code_schema = compiler::code_schema();
        let mut flow_changed = false;
        for (ix, node) in self.nodes.iter().enumerate() {
            match node.view {
                View::Table(Table{ref insert, ref remove}) => {
                    let mut view_changed = false;
                    {
                        let upstream = node.upstream.iter().map(|ix| self.outputs[*ix].borrow()).collect::<Vec<_>>();
                        let inputs = upstream.iter().map(|borrowed| &**borrowed).collect::<Vec<_>>();
                        let mut inserts = match *insert {
                            Some(ref select) => select.select(&inputs[..]),
                            None => vec![],
                        };
                        let mut removes = match *remove {
                            Some(ref select) => select.select(&inputs[..]),
                            None => vec![],
                        };
                        inserts.sort();
                        removes.sort();
                        inserts.retain(|insert| removes.binary_search(&insert).is_err());
                        removes.retain(|remove| inserts.binary_search(&remove).is_err());
                        let mut output = self.outputs[ix].borrow_mut();
                        let mut index = &mut output.index;
                        for insert in inserts {
                            view_changed = view_changed || index.insert(insert);
                        }
                        for remove in removes {
                            view_changed = view_changed || index.remove(&remove);
                        }
                    }
                    if view_changed {
                        if code_schema.iter().find(|&&(ref code_id, _)| **code_id == node.id).is_some() {
                            self.needs_recompile = true;
                        }
                        for ix in node.downstream.iter() {
                            self.dirty.insert(*ix);
                        }
                    }
                    flow_changed = flow_changed || view_changed;
                }
                _ => () // only tables tick
            }
        }
        flow_changed
    }

    pub fn quiesce(mut self, changes: Changes) -> Self {
        time!("changing", {
            self.change(changes);
        });
        loop {
            if self.needs_recompile {
                time!("compiling", {
                    self = compiler::recompile(self);
                });
            }
            time!("calculating", {
                self.recalculate();
            });
            let changed = time!("ticking", {
                self.tick()
            });
            if !changed {
                break
            }
        }
        self
    }
}
<|endoftext|>


<commit_before>//! Pointers and their events

use types::input_device::InputDevice;

use wlroots_sys::{wlr_button_state, wlr_event_pointer_axis, wlr_event_pointer_button,
                  wlr_event_pointer_motion, wlr_event_pointer_motion_absolute};

#[derive(Debug)]
/// Event that triggers when the pointer device scrolls (e.g using a wheel
// or in the case of a touchpad when you use two fingers to scroll).
pub struct AxisEvent {
    event: *mut wlr_event_pointer_axis,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when a button is pressed (e.g left click, right click,
/// a gaming mouse button, etc.).
pub struct ButtonEvent {
    event: *mut wlr_event_pointer_button,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when the pointer moves.
pub struct MotionEvent {
    event: *mut wlr_event_pointer_motion,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when data from a device that supports absolute motion
/// sends data to the compositor.
///
/// For more information on absolute motion, [see this link](https://wayland.freedesktop.org/libinput/doc/latest/absolute_axes.html).
pub struct AbsoluteMotionEvent {
    event: *mut wlr_event_pointer_motion_absolute,
    device: InputDevice
}

impl ButtonEvent {
    /// Constructs a `ButtonEvent` from the raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_button) -> Self {
        ButtonEvent { device: InputDevice::from_ptr((*event).device),
                      event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the state of the button (e.g pressed or released).
    pub fn state(&self) -> wlr_button_state {
        unsafe { (*self.event).state }
    }

    /// Get the value of the button pressed. This will generally be an atomically
    /// increasing value, with e.g left click being 1 and right click being 2...
    ///
    /// We make no guarantees that 1 always maps to left click, as this is device
    /// driver specific.
    pub fn button(&self) -> u32 {
        unsafe { (*self.event).button }
    }
}

impl AxisEvent {
    /// Constructs a `AxisEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_axis) -> Self {
        AxisEvent { device: InputDevice::from_ptr((*event).device),
                    event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the change from the last axis value.
    ///
    /// Useful to determine e.g how much to scroll.
    pub fn delta(&self) -> f64 {
        unsafe { (*self.event).delta }
    }
}

impl MotionEvent {
    /// Constructs a `MotionEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_motion) -> Self {
        MotionEvent { device: InputDevice::from_ptr((*event).device),
                      event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the change from the last positional value.
    ///
    /// Returned in (x, y) form.
    ///
    /// Note you should not cast this to a type with less precision,
    /// otherwise you'll lose important motion data which can cause bugs
    /// (e.g see [this fun wlc bug](https://github.com/Cloudef/wlc/issues/181)).
    pub fn delta(&self) -> (f64, f64) {
        unsafe { ((*self.event).delta_x, (*self.event).delta_y) }
    }
}

impl AbsoluteMotionEvent {
    /// Construct an `AbsoluteMotionEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_motion_absolute) -> Self {
        AbsoluteMotionEvent { device: InputDevice::from_ptr((*event).device),
                              event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }
}
<commit_msg>wlr_button_state wrapper type ButtonState<commit_after>//! Pointers and their events

use types::input_device::InputDevice;

use wlroots_sys::{wlr_button_state, wlr_event_pointer_axis, wlr_event_pointer_button,
                  wlr_event_pointer_motion, wlr_event_pointer_motion_absolute};

pub type ButtonState = wlr_button_state;

#[derive(Debug)]
/// Event that triggers when the pointer device scrolls (e.g using a wheel
// or in the case of a touchpad when you use two fingers to scroll).
pub struct AxisEvent {
    event: *mut wlr_event_pointer_axis,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when a button is pressed (e.g left click, right click,
/// a gaming mouse button, etc.).
pub struct ButtonEvent {
    event: *mut wlr_event_pointer_button,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when the pointer moves.
pub struct MotionEvent {
    event: *mut wlr_event_pointer_motion,
    device: InputDevice
}

#[derive(Debug)]
/// Event that triggers when data from a device that supports absolute motion
/// sends data to the compositor.
///
/// For more information on absolute motion, [see this link](https://wayland.freedesktop.org/libinput/doc/latest/absolute_axes.html).
pub struct AbsoluteMotionEvent {
    event: *mut wlr_event_pointer_motion_absolute,
    device: InputDevice
}

impl ButtonEvent {
    /// Constructs a `ButtonEvent` from the raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_button) -> Self {
        ButtonEvent { device: InputDevice::from_ptr((*event).device),
                      event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the state of the button (e.g pressed or released).
    pub fn state(&self) -> ButtonState {
        unsafe { (*self.event).state }
    }

    /// Get the value of the button pressed. This will generally be an atomically
    /// increasing value, with e.g left click being 1 and right click being 2...
    ///
    /// We make no guarantees that 1 always maps to left click, as this is device
    /// driver specific.
    pub fn button(&self) -> u32 {
        unsafe { (*self.event).button }
    }
}

impl AxisEvent {
    /// Constructs a `AxisEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_axis) -> Self {
        AxisEvent { device: InputDevice::from_ptr((*event).device),
                    event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the change from the last axis value.
    ///
    /// Useful to determine e.g how much to scroll.
    pub fn delta(&self) -> f64 {
        unsafe { (*self.event).delta }
    }
}

impl MotionEvent {
    /// Constructs a `MotionEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_motion) -> Self {
        MotionEvent { device: InputDevice::from_ptr((*event).device),
                      event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }

    /// Get the change from the last positional value.
    ///
    /// Returned in (x, y) form.
    ///
    /// Note you should not cast this to a type with less precision,
    /// otherwise you'll lose important motion data which can cause bugs
    /// (e.g see [this fun wlc bug](https://github.com/Cloudef/wlc/issues/181)).
    pub fn delta(&self) -> (f64, f64) {
        unsafe { ((*self.event).delta_x, (*self.event).delta_y) }
    }
}

impl AbsoluteMotionEvent {
    /// Construct an `AbsoluteMotionEvent` from a raw event pointer.
    pub(crate) unsafe fn from_ptr(event: *mut wlr_event_pointer_motion_absolute) -> Self {
        AbsoluteMotionEvent { device: InputDevice::from_ptr((*event).device),
                              event }
    }

    /// Get the device this event refers to.
    pub fn device(&self) -> &InputDevice {
        &self.device
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;

use progress::nested::subgraph::Source::ScopeOutput;
use progress::nested::subgraph::Target::ScopeInput;

use communication::*;
use progress::count_map::CountMap;
use progress::notificator::Notificator;
use progress::{Timestamp, Scope, Antichain};
use communication::channels::ObserverHelper;

use example_static::builder::*;
use example_static::unary::PullableHelper;
use example_static::stream::{ActiveStream, Stream};

pub trait BinaryStreamExt<G: GraphBuilder, D1: Data> {
    fn binary_stream<D2: Data,
              D3: Data,
              L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                       &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                       &mut ObserverHelper<OutputPort<G::Timestamp, D3>>)+'static,
              P1: ParallelizationContract<G::Timestamp, D1>,
              P2: ParallelizationContract<G::Timestamp, D2>>
            (self, Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, logic: L) -> ActiveStream<G, D3>;
}

impl<G: GraphBuilder, D1: Data> BinaryStreamExt<G, D1> for ActiveStream<G, D1> {
    fn binary_stream<
             D2: Data,
             D3: Data,
             L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                      &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                      &mut ObserverHelper<OutputPort<G::Timestamp, D3>>)+'static,
             P1: ParallelizationContract<G::Timestamp, D1>,
             P2: ParallelizationContract<G::Timestamp, D2>>
             (mut self, other: Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, mut logic: L) -> ActiveStream<G, D3> {
        let (sender1, receiver1) = pact1.connect(self.builder.communicator());
        let (sender2, receiver2) = pact2.connect(self.builder.communicator());;
        let (targets, registrar) = OutputPort::<G::Timestamp,D3>::new();
        let scope = BinaryScope::new(receiver1, receiver2, targets, name, None, move |i1, i2, o, _| logic(i1, i2, o));
        let index = self.builder.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender1);

        // other.connect_to(ScopeInput(index, 1), sender2);
        self.builder.connect(other.name, ScopeInput(index, 1));
        other.ports.add_observer(sender2);

        self.transfer_borrow_to(ScopeOutput(index, 0), registrar)
    }
}

pub trait BinaryNotifyExt<G: GraphBuilder, D1: Data> {
    fn binary_notify<D2: Data,
              D3: Data,
              L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                       &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                       &mut ObserverHelper<OutputPort<G::Timestamp, D3>>,
                       &mut Notificator<G::Timestamp>)+'static,
              P1: ParallelizationContract<G::Timestamp, D1>,
              P2: ParallelizationContract<G::Timestamp, D2>>
            (self, Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, notify: Vec<G::Timestamp>, logic: L) -> ActiveStream<G, D3>;
}

impl<G: GraphBuilder, D1: Data> BinaryNotifyExt<G, D1> for ActiveStream<G, D1> {
    fn binary_notify<
             D2: Data,
             D3: Data,
             L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                      &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                      &mut ObserverHelper<OutputPort<G::Timestamp, D3>>,
                      &mut Notificator<G::Timestamp>)+'static,
             P1: ParallelizationContract<G::Timestamp, D1>,
             P2: ParallelizationContract<G::Timestamp, D2>>
             (mut self, other: Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, notify: Vec<G::Timestamp>, logic: L) -> ActiveStream<G, D3> {
        let (sender1, receiver1) = pact1.connect(self.builder.communicator());
        let (sender2, receiver2) = pact2.connect(self.builder.communicator());;
        let (targets, registrar) = OutputPort::<G::Timestamp,D3>::new();
        let scope = BinaryScope::new(receiver1, receiver2, targets, name, Some((notify, self.builder.communicator().peers())), logic);
        let index = self.builder.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender1);

        // other.connect_to(ScopeInput(index, 1), sender2);
        self.builder.connect(other.name, ScopeInput(index, 1));
        other.ports.add_observer(sender2);

        self.transfer_borrow_to(ScopeOutput(index, 0), registrar)
    }
}

pub struct BinaryScopeHandle<T: Timestamp, D1: Data, D2: Data, D3: Data, P1: Pullable<(T, Vec<D1>)>, P2: Pullable<(T, Vec<D2>)>> {
    pub input1:         PullableHelper<T, D1, P1>,
    pub input2:         PullableHelper<T, D2, P2>,
    pub output:         ObserverHelper<OutputPort<T, D3>>,
    pub notificator:    Notificator<T>,
}

pub struct BinaryScope<T: Timestamp,
                       D1: Data, D2: Data, D3: Data,
                       P1: Pullable<(T, Vec<D1>)>,
                       P2: Pullable<(T, Vec<D2>)>,
                       L: FnMut(&mut PullableHelper<T, D1, P1>,
                                &mut PullableHelper<T, D2, P2>,
                                &mut ObserverHelper<OutputPort<T, D3>>,
                                &mut Notificator<T>)> {
    name:           String,
    handle:         BinaryScopeHandle<T, D1, D2, D3, P1, P2>,
    logic:          L,
    notify:         Option<(Vec<T>, u64)>,  // initial notifications and peers
}

impl<T: Timestamp,
     D1: Data, D2: Data, D3: Data,
     P1: Pullable<(T, Vec<D1>)>,
     P2: Pullable<(T, Vec<D2>)>,
     L: FnMut(&mut PullableHelper<T, D1, P1>,
              &mut PullableHelper<T, D2, P2>,
              &mut ObserverHelper<OutputPort<T, D3>>,
              &mut Notificator<T>)+'static>
BinaryScope<T, D1, D2, D3, P1, P2, L> {
    pub fn new(receiver1: P1, receiver2: P2, targets: OutputPort<T, D3>, name: String, notify: Option<(Vec<T>, u64)>, logic: L)
            -> BinaryScope<T, D1, D2, D3, P1, P2, L> {
        BinaryScope {
            name: name,
            handle: BinaryScopeHandle {
                input1:      PullableHelper::new(receiver1),
                input2:      PullableHelper::new(receiver2),
                output:      ObserverHelper::new(targets, Rc::new(RefCell::new(CountMap::new()))),
                notificator: Default::default(),
            },
            logic: logic,
            notify: notify,
        }
    }
}

impl<T, D1, D2, D3, P1, P2, L> Scope<T> for BinaryScope<T, D1, D2, D3, P1, P2, L>
where T: Timestamp,
      D1: Data, D2: Data, D3: Data,
      P1: Pullable<(T, Vec<D1>)>,
      P2: Pullable<(T, Vec<D2>)>,
      L: FnMut(&mut PullableHelper<T, D1, P1>,
               &mut PullableHelper<T, D2, P2>,
               &mut ObserverHelper<OutputPort<T, D3>>,
               &mut Notificator<T>)+'static {
    fn inputs(&self) -> u64 { 2 }
    fn outputs(&self) -> u64 { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<T::Summary>>>, Vec<CountMap<T>>) {
        let mut internal = vec![CountMap::new()];
        if let Some((ref mut initial, peers)) = self.notify {
            for time in initial.drain() {
                for _ in (0..peers) {
                    self.handle.notificator.notify_at(&time);
                }
            }

            self.handle.notificator.pull_progress(&mut internal[0]);
        }
        (vec![vec![Antichain::from_elem(Default::default())]], internal)
    }

    fn set_external_summary(&mut self, _summaries: Vec<Vec<Antichain<T::Summary>>>, frontier: &mut [CountMap<T>]) -> () {
        self.handle.notificator.update_frontier_from_cm(frontier);
    }

    fn push_external_progress(&mut self, external: &mut [CountMap<T>]) -> () {
        self.handle.notificator.update_frontier_from_cm(external);
    }

    fn pull_internal_progress(&mut self, internal: &mut [CountMap<T>],
                                         consumed: &mut [CountMap<T>],
                                         produced: &mut [CountMap<T>]) -> bool
    {
        (self.logic)(&mut self.handle.input1, &mut self.handle.input2, &mut self.handle.output, &mut self.handle.notificator);

        // extract what we know about progress from the input and output adapters.
        self.handle.input1.pull_progress(&mut consumed[0]);
        self.handle.input2.pull_progress(&mut consumed[1]);
        self.handle.output.pull_progress(&mut produced[0]);
        self.handle.notificator.pull_progress(&mut internal[0]);

        return false;   // no unannounced internal work
    }

    fn name(&self) -> String { format!("{}", self.name) }
    fn notify_me(&self) -> bool { self.notify.is_some() }
}
<commit_msg>incorrect description of internal binary reachability<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::default::Default;

use progress::nested::subgraph::Source::ScopeOutput;
use progress::nested::subgraph::Target::ScopeInput;

use communication::*;
use progress::count_map::CountMap;
use progress::notificator::Notificator;
use progress::{Timestamp, Scope, Antichain};
use communication::channels::ObserverHelper;

use example_static::builder::*;
use example_static::unary::PullableHelper;
use example_static::stream::{ActiveStream, Stream};

pub trait BinaryStreamExt<G: GraphBuilder, D1: Data> {
    fn binary_stream<D2: Data,
              D3: Data,
              L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                       &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                       &mut ObserverHelper<OutputPort<G::Timestamp, D3>>)+'static,
              P1: ParallelizationContract<G::Timestamp, D1>,
              P2: ParallelizationContract<G::Timestamp, D2>>
            (self, Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, logic: L) -> ActiveStream<G, D3>;
}

impl<G: GraphBuilder, D1: Data> BinaryStreamExt<G, D1> for ActiveStream<G, D1> {
    fn binary_stream<
             D2: Data,
             D3: Data,
             L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                      &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                      &mut ObserverHelper<OutputPort<G::Timestamp, D3>>)+'static,
             P1: ParallelizationContract<G::Timestamp, D1>,
             P2: ParallelizationContract<G::Timestamp, D2>>
             (mut self, other: Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, mut logic: L) -> ActiveStream<G, D3> {
        let (sender1, receiver1) = pact1.connect(self.builder.communicator());
        let (sender2, receiver2) = pact2.connect(self.builder.communicator());;
        let (targets, registrar) = OutputPort::<G::Timestamp,D3>::new();
        let scope = BinaryScope::new(receiver1, receiver2, targets, name, None, move |i1, i2, o, _| logic(i1, i2, o));
        let index = self.builder.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender1);

        // other.connect_to(ScopeInput(index, 1), sender2);
        self.builder.connect(other.name, ScopeInput(index, 1));
        other.ports.add_observer(sender2);

        self.transfer_borrow_to(ScopeOutput(index, 0), registrar)
    }
}

pub trait BinaryNotifyExt<G: GraphBuilder, D1: Data> {
    fn binary_notify<D2: Data,
              D3: Data,
              L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                       &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                       &mut ObserverHelper<OutputPort<G::Timestamp, D3>>,
                       &mut Notificator<G::Timestamp>)+'static,
              P1: ParallelizationContract<G::Timestamp, D1>,
              P2: ParallelizationContract<G::Timestamp, D2>>
            (self, Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, notify: Vec<G::Timestamp>, logic: L) -> ActiveStream<G, D3>;
}

impl<G: GraphBuilder, D1: Data> BinaryNotifyExt<G, D1> for ActiveStream<G, D1> {
    fn binary_notify<
             D2: Data,
             D3: Data,
             L: FnMut(&mut PullableHelper<G::Timestamp, D1, P1::Pullable>,
                      &mut PullableHelper<G::Timestamp, D2, P2::Pullable>,
                      &mut ObserverHelper<OutputPort<G::Timestamp, D3>>,
                      &mut Notificator<G::Timestamp>)+'static,
             P1: ParallelizationContract<G::Timestamp, D1>,
             P2: ParallelizationContract<G::Timestamp, D2>>
             (mut self, other: Stream<G::Timestamp, D2>, pact1: P1, pact2: P2, name: String, notify: Vec<G::Timestamp>, logic: L) -> ActiveStream<G, D3> {
        let (sender1, receiver1) = pact1.connect(self.builder.communicator());
        let (sender2, receiver2) = pact2.connect(self.builder.communicator());;
        let (targets, registrar) = OutputPort::<G::Timestamp,D3>::new();
        let scope = BinaryScope::new(receiver1, receiver2, targets, name, Some((notify, self.builder.communicator().peers())), logic);
        let index = self.builder.add_scope(scope);
        self.connect_to(ScopeInput(index, 0), sender1);

        // other.connect_to(ScopeInput(index, 1), sender2);
        self.builder.connect(other.name, ScopeInput(index, 1));
        other.ports.add_observer(sender2);

        self.transfer_borrow_to(ScopeOutput(index, 0), registrar)
    }
}

pub struct BinaryScopeHandle<T: Timestamp, D1: Data, D2: Data, D3: Data, P1: Pullable<(T, Vec<D1>)>, P2: Pullable<(T, Vec<D2>)>> {
    pub input1:         PullableHelper<T, D1, P1>,
    pub input2:         PullableHelper<T, D2, P2>,
    pub output:         ObserverHelper<OutputPort<T, D3>>,
    pub notificator:    Notificator<T>,
}

pub struct BinaryScope<T: Timestamp,
                       D1: Data, D2: Data, D3: Data,
                       P1: Pullable<(T, Vec<D1>)>,
                       P2: Pullable<(T, Vec<D2>)>,
                       L: FnMut(&mut PullableHelper<T, D1, P1>,
                                &mut PullableHelper<T, D2, P2>,
                                &mut ObserverHelper<OutputPort<T, D3>>,
                                &mut Notificator<T>)> {
    name:           String,
    handle:         BinaryScopeHandle<T, D1, D2, D3, P1, P2>,
    logic:          L,
    notify:         Option<(Vec<T>, u64)>,  // initial notifications and peers
}

impl<T: Timestamp,
     D1: Data, D2: Data, D3: Data,
     P1: Pullable<(T, Vec<D1>)>,
     P2: Pullable<(T, Vec<D2>)>,
     L: FnMut(&mut PullableHelper<T, D1, P1>,
              &mut PullableHelper<T, D2, P2>,
              &mut ObserverHelper<OutputPort<T, D3>>,
              &mut Notificator<T>)+'static>
BinaryScope<T, D1, D2, D3, P1, P2, L> {
    pub fn new(receiver1: P1, receiver2: P2, targets: OutputPort<T, D3>, name: String, notify: Option<(Vec<T>, u64)>, logic: L)
            -> BinaryScope<T, D1, D2, D3, P1, P2, L> {
        BinaryScope {
            name: name,
            handle: BinaryScopeHandle {
                input1:      PullableHelper::new(receiver1),
                input2:      PullableHelper::new(receiver2),
                output:      ObserverHelper::new(targets, Rc::new(RefCell::new(CountMap::new()))),
                notificator: Default::default(),
            },
            logic: logic,
            notify: notify,
        }
    }
}

impl<T, D1, D2, D3, P1, P2, L> Scope<T> for BinaryScope<T, D1, D2, D3, P1, P2, L>
where T: Timestamp,
      D1: Data, D2: Data, D3: Data,
      P1: Pullable<(T, Vec<D1>)>,
      P2: Pullable<(T, Vec<D2>)>,
      L: FnMut(&mut PullableHelper<T, D1, P1>,
               &mut PullableHelper<T, D2, P2>,
               &mut ObserverHelper<OutputPort<T, D3>>,
               &mut Notificator<T>)+'static {
    fn inputs(&self) -> u64 { 2 }
    fn outputs(&self) -> u64 { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<T::Summary>>>, Vec<CountMap<T>>) {
        let mut internal = vec![CountMap::new()];
        if let Some((ref mut initial, peers)) = self.notify {
            for time in initial.drain() {
                for _ in (0..peers) {
                    self.handle.notificator.notify_at(&time);
                }
            }

            self.handle.notificator.pull_progress(&mut internal[0]);
        }
        (vec![vec![Antichain::from_elem(Default::default())],
              vec![Antichain::from_elem(Default::default())]], internal)
    }

    fn set_external_summary(&mut self, _summaries: Vec<Vec<Antichain<T::Summary>>>, frontier: &mut [CountMap<T>]) -> () {
        self.handle.notificator.update_frontier_from_cm(frontier);
    }

    fn push_external_progress(&mut self, external: &mut [CountMap<T>]) -> () {
        self.handle.notificator.update_frontier_from_cm(external);
    }

    fn pull_internal_progress(&mut self, internal: &mut [CountMap<T>],
                                         consumed: &mut [CountMap<T>],
                                         produced: &mut [CountMap<T>]) -> bool
    {
        (self.logic)(&mut self.handle.input1, &mut self.handle.input2, &mut self.handle.output, &mut self.handle.notificator);

        // extract what we know about progress from the input and output adapters.
        self.handle.input1.pull_progress(&mut consumed[0]);
        self.handle.input2.pull_progress(&mut consumed[1]);
        self.handle.output.pull_progress(&mut produced[0]);
        self.handle.notificator.pull_progress(&mut internal[0]);

        return false;   // no unannounced internal work
    }

    fn name(&self) -> String { format!("{}", self.name) }
    fn notify_me(&self) -> bool { self.notify.is_some() }
}
<|endoftext|>


<commit_before>//! Default shaders.

use luminance::Sem;
use luminance_gl::gl33::Uniform;
use std::ops::Deref;

use id::Id;
use shader::Program;
use scene::Scene;

pub type ColorUniform = Uniform<[f32; 4]>;
pub const DEFAULT_2D_COLOR: ColorUniform = Uniform::new(0);

pub struct DefaultProgram2D<'a>(Id<'a, Program>);

impl<'a> Deref for DefaultProgram2D<'a> {
  type Target = Id<'a, Program>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl<'a> DefaultProgram2D<'a> {
  pub fn get_from(scene: &mut Scene<'a>) -> Option<Self> {
    get_id!(scene, "default_2d.glsl", vec![ColorUniform::sem("color")]).map(DefaultProgram)
  }
}
<commit_msg>DefaultProgram -> DefaultProgram2D.<commit_after>//! Default shaders.

use luminance::Sem;
use luminance_gl::gl33::Uniform;
use std::ops::Deref;

use id::Id;
use shader::Program;
use scene::Scene;

pub type ColorUniform = Uniform<[f32; 4]>;
pub const DEFAULT_2D_COLOR: ColorUniform = Uniform::new(0);

pub struct DefaultProgram2D<'a>(Id<'a, Program>);

impl<'a> Deref for DefaultProgram2D<'a> {
  type Target = Id<'a, Program>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl<'a> DefaultProgram2D<'a> {
  pub fn get_from(scene: &mut Scene<'a>) -> Option<Self> {
    get_id!(scene, "default_2d.glsl", vec![ColorUniform::sem("color")]).map(DefaultProgram2D)
  }
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::io::prelude::*;
use std::iter::repeat;
use std::net::{TcpStream, TcpListener};
use std::str;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;

use self::Op::{SendBytes, ReceiveBytes, Wait, Shutdown};

// Global handle to the running test HTTP server
thread_local!(static HANDLE: Handle = start_server());

// Setup an op sequence with the test HTTP server
pub fn setup(ops: OpSequence) -> OpSequenceResult {
    // Setup a channel to receive the response on
    let (tx, rx) = channel();

    // Send the op sequence to the server task
    HANDLE.with(move |h| {
        h.send(ops, tx);
    });

    OpSequenceResult::new(rx)
}

pub fn url(path: &str) -> String {
    format!("http://localhost:{}{}", port(), path)
}

fn port() -> usize {
    HANDLE.with(|h| {
        h.port()
    })
}

/* Handle to the running HTTP server task. Communication with the server
 * happens over channels.
 */
struct Handle {
    port: u16,
    tx: Sender<(OpSequence, Sender<Result<(),String>>)>
}

/* Operations for the test server to perform:
 * - Send some bytes
 * - Expect to receive bytes
 * - Wait for a certain amount of time
 * - Shutdown the server (allows a clean exit at the end of the tests)
 */
#[derive(Clone,PartialEq,Debug)]
pub enum Op {
    SendBytes(&'static [u8]),
    ReceiveBytes(&'static [u8]),
    Wait(usize),
    Shutdown
}

/* An ordered sequence of operations for the HTTP server to perform
*/
#[derive(Debug)]
pub struct OpSequence {
    ops: Vec<Op>
}

/* Represents the completion of the of the op sequence by the HTTP
 * server.
 */
pub struct OpSequenceResult {
    rx: Receiver<Result<(),String>>
}

impl OpSequence {
    pub fn new(op: Op) -> OpSequence {
        OpSequence { ops: vec!(op) }
    }

    pub fn concat(op: Op, seq: OpSequence) -> OpSequence {
        let mut ops = vec!(op);
        ops.extend(seq.ops.iter().cloned());
        OpSequence { ops: ops }
    }

    pub fn is_shutdown(&self) -> bool {
        self.ops.len() == 1 && self.ops[0] == Shutdown
    }

    pub fn apply(&self, sock: &mut TcpStream, port: usize)
                 -> Result<(), String> {
        for op in self.ops.iter() {
            match op {
                &SendBytes(b) => {
                    let b = insert_port(b, port);
                    match sock.write_all(&b) {
                        Ok(_) => {}
                        Err(e) => return Err(e.to_string())
                    }
                }
                &ReceiveBytes(b) => {
                    let b = insert_port(b, port);
                    let mut rem = b.len();
                    let mut act = repeat(0u8).take(rem).collect::<Vec<_>>();

                    while rem > 0 {
                        match sock.read(&mut act[b.len() - rem..]) {
                            Ok(i) => rem = rem - i,
                            Err(e) => {
                                debug!("aborting due to error; error={}; \
                                        remaining={}; bytes=\n{}", e, rem,
                                       to_debug_str(&act));
                                return Err(e.to_string())
                            }
                        }
                    }

                    debug!("server received bytes; rem={}; bytes=\n{}\n~~~~~~~~~~~~~~",
                           rem, to_debug_str(&act));

                    let req1 = parse_request(&b);
                    let req2 = parse_request(&act);

                    if req1 != req2 {
                        return Err(format!(
                                "received unexpected byte sequence.\n\n\
                                 Expected:\n{}\n\nReceived:\n{}",
                                to_debug_str(&b), to_debug_str(&act)));
                    }
                }
                &Wait(ms) => thread::sleep_ms(ms as u32),
                &Shutdown => {
                    return Err("Shutdown must be sent on its own".to_string())
                }
            }
        }

        return Ok(());

        fn insert_port(bytes: &'static [u8], port: usize) -> Vec<u8> {
            let s = str::from_utf8(bytes).unwrap();
            let p = port.to_string();
            s.replace("{PORT}", &p).into_bytes()
        }

        fn parse_request<'a>(req: &'a [u8]) -> (&'a [u8],
                                                HashSet<&'a [u8]>,
                                                &'a [u8]) {
            let mut start = None;
            let mut headers = HashSet::new();
            let mut taken = 0;

            for part in req.split(|a| *a == b'\n') {
                taken += part.len() + 1;

                if start.is_none() {
                    start = Some(part);
                } else if part.len() == 1 {
                    break;
                } else {
                    headers.insert(part);
                }
            }

            if taken > req.len() {
                taken = req.len();
            }

            (start.unwrap(), headers, &req[taken..])
        }
    }
}

fn to_debug_str(bytes: &[u8]) -> String {
    let mut ret = String::new();

    for b in bytes.iter() {
        let b = *b as char;

        if b >= ' ' && b <= '~' {
            ret.push(b);
        }
        else if b == '\n' {
            ret.push_str("\\n\n");
        }
        else if b == '\r' {
            ret.push_str("\\r");
        }
        else {
            ret.push('?');
        }
    }

    ret
}

impl Handle {
    fn new(tx: Sender<(OpSequence, Sender<Result<(),String>>)>, port: u16)
           -> Handle {
        Handle { tx: tx, port: port }
    }

    fn send(&self, ops: OpSequence, resp: Sender<Result<(),String>>) {
        self.tx.send((ops, resp)).unwrap();
    }

    fn port(&self) -> usize {
        self.port as usize
    }
}

impl Drop for Handle {
    fn drop(&mut self) {
        let (tx, _) = channel();
        self.send(OpSequence::new(Shutdown), tx);
    }
}

impl OpSequenceResult {
    pub fn new(rx: Receiver<Result<(),String>>) -> OpSequenceResult {
        OpSequenceResult { rx: rx }
    }

    pub fn assert(&self) {
        match self.rx.recv().unwrap() {
            Ok(_) => {}
            Err(e) => panic!("http exchange did not proceed as expected: {}", e)
        }
    }
}

fn start_server() -> Handle {
    let (ops_tx, ops_rx) = channel();

    let srv = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = srv.local_addr().unwrap().port();

    thread::spawn(move || {
        loop {
            let (ops, resp_tx): (OpSequence, Sender<Result<(),String>>) =
                    ops_rx.recv().unwrap();

            if ops.is_shutdown() {
                return;
            }

            let mut sock = match srv.accept() {
                Ok(s) => s.0,
                Err(e) => {
                    resp_tx.send(Err(format!("server accept err: {}", e))).unwrap();
                    return;
                }
            };

            resp_tx.send(ops.apply(&mut sock, port as usize)).unwrap();
        }
    });

    Handle::new(ops_tx, port)
}
<commit_msg>Fix compilation warnings<commit_after>use std::collections::HashSet;
use std::io::prelude::*;
use std::iter::repeat;
use std::net::{TcpStream, TcpListener};
use std::str;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::thread;
use std::time::Duration;

use self::Op::{SendBytes, ReceiveBytes, Wait, Shutdown};

// Global handle to the running test HTTP server
thread_local!(static HANDLE: Handle = start_server());

// Setup an op sequence with the test HTTP server
pub fn setup(ops: OpSequence) -> OpSequenceResult {
    // Setup a channel to receive the response on
    let (tx, rx) = channel();

    // Send the op sequence to the server task
    HANDLE.with(move |h| {
        h.send(ops, tx);
    });

    OpSequenceResult::new(rx)
}

pub fn url(path: &str) -> String {
    format!("http://localhost:{}{}", port(), path)
}

fn port() -> usize {
    HANDLE.with(|h| {
        h.port()
    })
}

/* Handle to the running HTTP server task. Communication with the server
 * happens over channels.
 */
struct Handle {
    port: u16,
    tx: Sender<(OpSequence, Sender<Result<(),String>>)>
}

/* Operations for the test server to perform:
 * - Send some bytes
 * - Expect to receive bytes
 * - Wait for a certain amount of time
 * - Shutdown the server (allows a clean exit at the end of the tests)
 */
#[derive(Clone,PartialEq,Debug)]
pub enum Op {
    SendBytes(&'static [u8]),
    ReceiveBytes(&'static [u8]),
    #[allow(dead_code)]
    Wait(usize),
    Shutdown
}

/* An ordered sequence of operations for the HTTP server to perform
*/
#[derive(Debug)]
pub struct OpSequence {
    ops: Vec<Op>
}

/* Represents the completion of the of the op sequence by the HTTP
 * server.
 */
pub struct OpSequenceResult {
    rx: Receiver<Result<(),String>>
}

impl OpSequence {
    pub fn new(op: Op) -> OpSequence {
        OpSequence { ops: vec!(op) }
    }

    pub fn concat(op: Op, seq: OpSequence) -> OpSequence {
        let mut ops = vec!(op);
        ops.extend(seq.ops.iter().cloned());
        OpSequence { ops: ops }
    }

    pub fn is_shutdown(&self) -> bool {
        self.ops.len() == 1 && self.ops[0] == Shutdown
    }

    pub fn apply(&self, sock: &mut TcpStream, port: usize)
                 -> Result<(), String> {
        for op in self.ops.iter() {
            match op {
                &SendBytes(b) => {
                    let b = insert_port(b, port);
                    match sock.write_all(&b) {
                        Ok(_) => {}
                        Err(e) => return Err(e.to_string())
                    }
                }
                &ReceiveBytes(b) => {
                    let b = insert_port(b, port);
                    let mut rem = b.len();
                    let mut act = repeat(0u8).take(rem).collect::<Vec<_>>();

                    while rem > 0 {
                        match sock.read(&mut act[b.len() - rem..]) {
                            Ok(i) => rem = rem - i,
                            Err(e) => {
                                debug!("aborting due to error; error={}; \
                                        remaining={}; bytes=\n{}", e, rem,
                                       to_debug_str(&act));
                                return Err(e.to_string())
                            }
                        }
                    }

                    debug!("server received bytes; rem={}; bytes=\n{}\n~~~~~~~~~~~~~~",
                           rem, to_debug_str(&act));

                    let req1 = parse_request(&b);
                    let req2 = parse_request(&act);

                    if req1 != req2 {
                        return Err(format!(
                                "received unexpected byte sequence.\n\n\
                                 Expected:\n{}\n\nReceived:\n{}",
                                to_debug_str(&b), to_debug_str(&act)));
                    }
                }
                &Wait(ms) => thread::sleep(Duration::from_millis(ms as u64)),
                &Shutdown => {
                    return Err("Shutdown must be sent on its own".to_string())
                }
            }
        }

        return Ok(());

        fn insert_port(bytes: &'static [u8], port: usize) -> Vec<u8> {
            let s = str::from_utf8(bytes).unwrap();
            let p = port.to_string();
            s.replace("{PORT}", &p).into_bytes()
        }

        fn parse_request<'a>(req: &'a [u8]) -> (&'a [u8],
                                                HashSet<&'a [u8]>,
                                                &'a [u8]) {
            let mut start = None;
            let mut headers = HashSet::new();
            let mut taken = 0;

            for part in req.split(|a| *a == b'\n') {
                taken += part.len() + 1;

                if start.is_none() {
                    start = Some(part);
                } else if part.len() == 1 {
                    break;
                } else {
                    headers.insert(part);
                }
            }

            if taken > req.len() {
                taken = req.len();
            }

            (start.unwrap(), headers, &req[taken..])
        }
    }
}

fn to_debug_str(bytes: &[u8]) -> String {
    let mut ret = String::new();

    for b in bytes.iter() {
        let b = *b as char;

        if b >= ' ' && b <= '~' {
            ret.push(b);
        }
        else if b == '\n' {
            ret.push_str("\\n\n");
        }
        else if b == '\r' {
            ret.push_str("\\r");
        }
        else {
            ret.push('?');
        }
    }

    ret
}

impl Handle {
    fn new(tx: Sender<(OpSequence, Sender<Result<(),String>>)>, port: u16)
           -> Handle {
        Handle { tx: tx, port: port }
    }

    fn send(&self, ops: OpSequence, resp: Sender<Result<(),String>>) {
        self.tx.send((ops, resp)).unwrap();
    }

    fn port(&self) -> usize {
        self.port as usize
    }
}

impl Drop for Handle {
    fn drop(&mut self) {
        let (tx, _) = channel();
        self.send(OpSequence::new(Shutdown), tx);
    }
}

impl OpSequenceResult {
    pub fn new(rx: Receiver<Result<(),String>>) -> OpSequenceResult {
        OpSequenceResult { rx: rx }
    }

    pub fn assert(&self) {
        match self.rx.recv().unwrap() {
            Ok(_) => {}
            Err(e) => panic!("http exchange did not proceed as expected: {}", e)
        }
    }
}

fn start_server() -> Handle {
    let (ops_tx, ops_rx) = channel();

    let srv = TcpListener::bind("127.0.0.1:0").unwrap();
    let port = srv.local_addr().unwrap().port();

    thread::spawn(move || {
        loop {
            let (ops, resp_tx): (OpSequence, Sender<Result<(),String>>) =
                    ops_rx.recv().unwrap();

            if ops.is_shutdown() {
                return;
            }

            let mut sock = match srv.accept() {
                Ok(s) => s.0,
                Err(e) => {
                    resp_tx.send(Err(format!("server accept err: {}", e))).unwrap();
                    return;
                }
            };

            resp_tx.send(ops.apply(&mut sock, port as usize)).unwrap();
        }
    });

    Handle::new(ops_tx, port)
}
<|endoftext|>