<commit_before>//! The type system. We currently use this to infer types for completion, hover
//! information and various assists.

mod autoderef;
pub(crate) mod primitive;
#[cfg(test)]
mod tests;
pub(crate) mod method_resolution;
mod op;
mod lower;
mod infer;
pub(crate) mod display;

use std::sync::Arc;
use std::{fmt, mem};

use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase};

pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig};
pub(crate) use infer::{infer, InferenceResult, InferTy};
use display::{HirDisplay, HirFormatter};

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum TypeCtor {
    /// The primitive boolean type. Written as `bool`.
    Bool,

    /// The primitive character type; holds a Unicode scalar value
    /// (a non-surrogate code point). Written as `char`.
    Char,

    /// A primitive integer type. For example, `i32`.
    Int(primitive::UncertainIntTy),

    /// A primitive floating-point type. For example, `f64`.
    Float(primitive::UncertainFloatTy),

    /// Structures, enumerations and unions.
    Adt(AdtDef),

    /// The pointee of a string slice. Written as `str`.
    Str,

    /// The pointee of an array slice.  Written as `[T]`.
    Slice,

    /// An array with the given length. Written as `[T; n]`.
    Array,

    /// A raw pointer. Written as `*mut T` or `*const T`
    RawPtr(Mutability),

    /// A reference; a pointer with an associated lifetime. Written as
    /// `&'a mut T` or `&'a T`.
    Ref(Mutability),

    /// The anonymous type of a function declaration/definition. Each
    /// function has a unique type, which is output (for a function
    /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
    ///
    /// This includes tuple struct / enum variant constructors as well.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar = foo; // bar: fn() -> i32 {foo}
    /// ```
    FnDef(CallableDef),

    /// A pointer to a function.  Written as `fn() -> i32`.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar: fn() -> i32 = foo;
    /// ```
    FnPtr,

    /// The never type `!`.
    Never,

    /// A tuple type.  For example, `(i32, bool)`.
    Tuple,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ApplicationTy {
    pub name: TypeCtor,
    pub parameters: Substs,
}

/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
///
/// This should be cheap to clone.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Ty {
    /// A nominal type with (maybe 0) type parameters. This might be a primitive
    /// type like `bool`, a struct, tuple, function pointer, reference or
    /// several other things.
    Apply(ApplicationTy),

    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
    Param {
        /// The index of the parameter (starting with parameters from the
        /// surrounding impl, then the current function).
        idx: u32,
        /// The name of the parameter, for displaying.
        name: Name,
    },

    /// A type variable used during type checking. Not to be confused with a
    /// type parameter.
    Infer(InferTy),

    /// A placeholder for a type which could not be computed; this is propagated
    /// to avoid useless error messages. Doubles as a placeholder where type
    /// variables are inserted before type checking, since we want to try to
    /// infer a better type here anyway -- for the IDE use case, we want to try
    /// to infer as much as possible even in the presence of type errors.
    Unknown,
}

/// A list of substitutions for generic parameters.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Substs(Arc<[Ty]>);

impl Substs {
    pub fn empty() -> Substs {
        Substs(Arc::new([]))
    }

    pub fn single(ty: Ty) -> Substs {
        Substs(Arc::new([ty]))
    }

    pub fn iter(&self) -> impl Iterator<Item = &Ty> {
        self.0.iter()
    }

    pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        // Without an Arc::make_mut_slice, we can't avoid the clone here:
        let mut v: Vec<_> = self.0.iter().cloned().collect();
        for t in &mut v {
            t.walk_mut(f);
        }
        self.0 = v.into();
    }

    pub fn as_single(&self) -> &Ty {
        if self.0.len() != 1 {
            panic!("expected substs of len 1, got {:?}", self);
        }
        &self.0[0]
    }
}

/// A function signature.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FnSig {
    params_and_return: Arc<[Ty]>,
}

impl FnSig {
    pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
        params.push(ret);
        FnSig { params_and_return: params.into() }
    }

    pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig {
        FnSig { params_and_return: Arc::clone(&substs.0) }
    }

    pub fn params(&self) -> &[Ty] {
        &self.params_and_return[0..self.params_and_return.len() - 1]
    }

    pub fn ret(&self) -> &Ty {
        &self.params_and_return[self.params_and_return.len() - 1]
    }

    pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        // Without an Arc::make_mut_slice, we can't avoid the clone here:
        let mut v: Vec<_> = self.params_and_return.iter().cloned().collect();
        for t in &mut v {
            t.walk_mut(f);
        }
        self.params_and_return = v.into();
    }
}

impl Ty {
    pub fn simple(name: TypeCtor) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters: Substs::empty() })
    }
    pub fn apply_one(name: TypeCtor, param: Ty) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters: Substs::single(param) })
    }
    pub fn apply(name: TypeCtor, parameters: Substs) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters })
    }
    pub fn unit() -> Self {
        Ty::apply(TypeCtor::Tuple, Substs::empty())
    }

    pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
        match self {
            Ty::Apply(a_ty) => {
                for t in a_ty.parameters.iter() {
                    t.walk(f);
                }
            }
            Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
        }
        f(self);
    }

    fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        match self {
            Ty::Apply(a_ty) => {
                a_ty.parameters.walk_mut(f);
            }
            Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
        }
        f(self);
    }

    fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty {
        self.walk_mut(&mut |ty_mut| {
            let ty = mem::replace(ty_mut, Ty::Unknown);
            *ty_mut = f(ty);
        });
        self
    }

    pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Ref(mutability), parameters }) => {
                Some((parameters.as_single(), *mutability))
            }
            _ => None,
        }
    }

    pub fn as_adt(&self) -> Option<(AdtDef, &Substs)> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Adt(adt_def), parameters }) => {
                Some((*adt_def, parameters))
            }
            _ => None,
        }
    }

    pub fn as_tuple(&self) -> Option<&Substs> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Tuple, parameters }) => Some(parameters),
            _ => None,
        }
    }

    fn builtin_deref(&self) -> Option<Ty> {
        match self {
            Ty::Apply(a_ty) => match a_ty.name {
                TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())),
                TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
                _ => None,
            },
            _ => None,
        }
    }

    /// If this is a type with type parameters (an ADT or function), replaces
    /// the `Substs` for these type parameters with the given ones. (So e.g. if
    /// `self` is `Option<_>` and the substs contain `u32`, we'll have
    /// `Option<u32>` afterwards.)
    pub fn apply_substs(self, substs: Substs) -> Ty {
        match self {
            Ty::Apply(ApplicationTy { name, .. }) => {
                Ty::Apply(ApplicationTy { name, parameters: substs })
            }
            _ => self,
        }
    }

    /// Replaces type parameters in this type using the given `Substs`. (So e.g.
    /// if `self` is `&[T]`, where type parameter T has index 0, and the
    /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
    pub fn subst(self, substs: &Substs) -> Ty {
        self.fold(&mut |ty| match ty {
            Ty::Param { idx, name } => {
                if (idx as usize) < substs.0.len() {
                    substs.0[idx as usize].clone()
                } else {
                    Ty::Param { idx, name }
                }
            }
            ty => ty,
        })
    }

    /// Returns the type parameters of this type if it has some (i.e. is an ADT
    /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
    fn substs(&self) -> Option<Substs> {
        match self {
            Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
            _ => None,
        }
    }
}

impl HirDisplay for &Ty {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        HirDisplay::hir_fmt(*self, f)
    }
}

impl HirDisplay for ApplicationTy {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        match self.name {
            TypeCtor::Bool => write!(f, "bool")?,
            TypeCtor::Char => write!(f, "char")?,
            TypeCtor::Int(t) => write!(f, "{}", t)?,
            TypeCtor::Float(t) => write!(f, "{}", t)?,
            TypeCtor::Str => write!(f, "str")?,
            TypeCtor::Slice | TypeCtor::Array => {
                let t = self.parameters.as_single();
                write!(f, "[{}]", t.display(f.db))?;
            }
            TypeCtor::RawPtr(m) => {
                let t = self.parameters.as_single();
                write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
            }
            TypeCtor::Ref(m) => {
                let t = self.parameters.as_single();
                write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
            }
            TypeCtor::Never => write!(f, "!")?,
            TypeCtor::Tuple => {
                let ts = &self.parameters;
                if ts.0.len() == 1 {
                    write!(f, "({},)", ts.0[0].display(f.db))?;
                } else {
                    write!(f, "(")?;
                    f.write_joined(&*ts.0, ", ")?;
                    write!(f, ")")?;
                }
            }
            TypeCtor::FnPtr => {
                let sig = FnSig::from_fn_ptr_substs(&self.parameters);
                write!(f, "fn(")?;
                f.write_joined(sig.params(), ", ")?;
                write!(f, ") -> {}", sig.ret().display(f.db))?;
            }
            TypeCtor::FnDef(def) => {
                let sig = f.db.callable_item_signature(def);
                let name = match def {
                    CallableDef::Function(ff) => ff.name(f.db),
                    CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),
                    CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing),
                };
                match def {
                    CallableDef::Function(_) => write!(f, "fn {}", name)?,
                    CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?,
                }
                if self.parameters.0.len() > 0 {
                    write!(f, "<")?;
                    f.write_joined(&*self.parameters.0, ", ")?;
                    write!(f, ">")?;
                }
                write!(f, "(")?;
                f.write_joined(sig.params(), ", ")?;
                write!(f, ") -> {}", sig.ret().display(f.db))?;
            }
            TypeCtor::Adt(def_id) => {
                let name = match def_id {
                    AdtDef::Struct(s) => s.name(f.db),
                    AdtDef::Enum(e) => e.name(f.db),
                }
                .unwrap_or_else(Name::missing);
                write!(f, "{}", name)?;
                if self.parameters.0.len() > 0 {
                    write!(f, "<")?;
                    f.write_joined(&*self.parameters.0, ", ")?;
                    write!(f, ">")?;
                }
            }
        }
        Ok(())
    }
}

impl HirDisplay for Ty {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        match self {
            Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
            Ty::Param { name, .. } => write!(f, "{}", name)?,
            Ty::Unknown => write!(f, "{{unknown}}")?,
            Ty::Infer(..) => write!(f, "_")?,
        }
        Ok(())
    }
}
<commit_msg>Some more doc comments<commit_after>//! The type system. We currently use this to infer types for completion, hover
//! information and various assists.

mod autoderef;
pub(crate) mod primitive;
#[cfg(test)]
mod tests;
pub(crate) mod method_resolution;
mod op;
mod lower;
mod infer;
pub(crate) mod display;

use std::sync::Arc;
use std::{fmt, mem};

use crate::{Name, AdtDef, type_ref::Mutability, db::HirDatabase};

pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, callable_item_sig};
pub(crate) use infer::{infer, InferenceResult, InferTy};
use display::{HirDisplay, HirFormatter};

/// A type constructor or type name: this might be something like the primitive
/// type `bool`, a struct like `Vec`, or things like function pointers or
/// tuples.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum TypeCtor {
    /// The primitive boolean type. Written as `bool`.
    Bool,

    /// The primitive character type; holds a Unicode scalar value
    /// (a non-surrogate code point). Written as `char`.
    Char,

    /// A primitive integer type. For example, `i32`.
    Int(primitive::UncertainIntTy),

    /// A primitive floating-point type. For example, `f64`.
    Float(primitive::UncertainFloatTy),

    /// Structures, enumerations and unions.
    Adt(AdtDef),

    /// The pointee of a string slice. Written as `str`.
    Str,

    /// The pointee of an array slice.  Written as `[T]`.
    Slice,

    /// An array with the given length. Written as `[T; n]`.
    Array,

    /// A raw pointer. Written as `*mut T` or `*const T`
    RawPtr(Mutability),

    /// A reference; a pointer with an associated lifetime. Written as
    /// `&'a mut T` or `&'a T`.
    Ref(Mutability),

    /// The anonymous type of a function declaration/definition. Each
    /// function has a unique type, which is output (for a function
    /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
    ///
    /// This includes tuple struct / enum variant constructors as well.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar = foo; // bar: fn() -> i32 {foo}
    /// ```
    FnDef(CallableDef),

    /// A pointer to a function.  Written as `fn() -> i32`.
    ///
    /// For example the type of `bar` here:
    ///
    /// ```rust
    /// fn foo() -> i32 { 1 }
    /// let bar: fn() -> i32 = foo;
    /// ```
    FnPtr,

    /// The never type `!`.
    Never,

    /// A tuple type.  For example, `(i32, bool)`.
    Tuple,
}

/// A nominal type with (maybe 0) type parameters. This might be a primitive
/// type like `bool`, a struct, tuple, function pointer, reference or
/// several other things.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ApplicationTy {
    pub name: TypeCtor,
    pub parameters: Substs,
}

/// A type.
///
/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
/// the same thing (but in a different way).
///
/// This should be cheap to clone.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Ty {
    /// A nominal type with (maybe 0) type parameters. This might be a primitive
    /// type like `bool`, a struct, tuple, function pointer, reference or
    /// several other things.
    Apply(ApplicationTy),

    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
    Param {
        /// The index of the parameter (starting with parameters from the
        /// surrounding impl, then the current function).
        idx: u32,
        /// The name of the parameter, for displaying.
        name: Name,
    },

    /// A type variable used during type checking. Not to be confused with a
    /// type parameter.
    Infer(InferTy),

    /// A placeholder for a type which could not be computed; this is propagated
    /// to avoid useless error messages. Doubles as a placeholder where type
    /// variables are inserted before type checking, since we want to try to
    /// infer a better type here anyway -- for the IDE use case, we want to try
    /// to infer as much as possible even in the presence of type errors.
    Unknown,
}

/// A list of substitutions for generic parameters.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Substs(Arc<[Ty]>);

impl Substs {
    pub fn empty() -> Substs {
        Substs(Arc::new([]))
    }

    pub fn single(ty: Ty) -> Substs {
        Substs(Arc::new([ty]))
    }

    pub fn iter(&self) -> impl Iterator<Item = &Ty> {
        self.0.iter()
    }

    pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        // Without an Arc::make_mut_slice, we can't avoid the clone here:
        let mut v: Vec<_> = self.0.iter().cloned().collect();
        for t in &mut v {
            t.walk_mut(f);
        }
        self.0 = v.into();
    }

    pub fn as_single(&self) -> &Ty {
        if self.0.len() != 1 {
            panic!("expected substs of len 1, got {:?}", self);
        }
        &self.0[0]
    }
}

/// A function signature as seen by type inference: Several parameter types and
/// one return type.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct FnSig {
    params_and_return: Arc<[Ty]>,
}

impl FnSig {
    pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
        params.push(ret);
        FnSig { params_and_return: params.into() }
    }

    pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig {
        FnSig { params_and_return: Arc::clone(&substs.0) }
    }

    pub fn params(&self) -> &[Ty] {
        &self.params_and_return[0..self.params_and_return.len() - 1]
    }

    pub fn ret(&self) -> &Ty {
        &self.params_and_return[self.params_and_return.len() - 1]
    }

    pub fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        // Without an Arc::make_mut_slice, we can't avoid the clone here:
        let mut v: Vec<_> = self.params_and_return.iter().cloned().collect();
        for t in &mut v {
            t.walk_mut(f);
        }
        self.params_and_return = v.into();
    }
}

impl Ty {
    pub fn simple(name: TypeCtor) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters: Substs::empty() })
    }
    pub fn apply_one(name: TypeCtor, param: Ty) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters: Substs::single(param) })
    }
    pub fn apply(name: TypeCtor, parameters: Substs) -> Ty {
        Ty::Apply(ApplicationTy { name, parameters })
    }
    pub fn unit() -> Self {
        Ty::apply(TypeCtor::Tuple, Substs::empty())
    }

    pub fn walk(&self, f: &mut impl FnMut(&Ty)) {
        match self {
            Ty::Apply(a_ty) => {
                for t in a_ty.parameters.iter() {
                    t.walk(f);
                }
            }
            Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
        }
        f(self);
    }

    fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
        match self {
            Ty::Apply(a_ty) => {
                a_ty.parameters.walk_mut(f);
            }
            Ty::Param { .. } | Ty::Infer(_) | Ty::Unknown => {}
        }
        f(self);
    }

    fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Ty {
        self.walk_mut(&mut |ty_mut| {
            let ty = mem::replace(ty_mut, Ty::Unknown);
            *ty_mut = f(ty);
        });
        self
    }

    pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Ref(mutability), parameters }) => {
                Some((parameters.as_single(), *mutability))
            }
            _ => None,
        }
    }

    pub fn as_adt(&self) -> Option<(AdtDef, &Substs)> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Adt(adt_def), parameters }) => {
                Some((*adt_def, parameters))
            }
            _ => None,
        }
    }

    pub fn as_tuple(&self) -> Option<&Substs> {
        match self {
            Ty::Apply(ApplicationTy { name: TypeCtor::Tuple, parameters }) => Some(parameters),
            _ => None,
        }
    }

    fn builtin_deref(&self) -> Option<Ty> {
        match self {
            Ty::Apply(a_ty) => match a_ty.name {
                TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())),
                TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
                _ => None,
            },
            _ => None,
        }
    }

    /// If this is a type with type parameters (an ADT or function), replaces
    /// the `Substs` for these type parameters with the given ones. (So e.g. if
    /// `self` is `Option<_>` and the substs contain `u32`, we'll have
    /// `Option<u32>` afterwards.)
    pub fn apply_substs(self, substs: Substs) -> Ty {
        match self {
            Ty::Apply(ApplicationTy { name, .. }) => {
                Ty::Apply(ApplicationTy { name, parameters: substs })
            }
            _ => self,
        }
    }

    /// Replaces type parameters in this type using the given `Substs`. (So e.g.
    /// if `self` is `&[T]`, where type parameter T has index 0, and the
    /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
    pub fn subst(self, substs: &Substs) -> Ty {
        self.fold(&mut |ty| match ty {
            Ty::Param { idx, name } => {
                if (idx as usize) < substs.0.len() {
                    substs.0[idx as usize].clone()
                } else {
                    Ty::Param { idx, name }
                }
            }
            ty => ty,
        })
    }

    /// Returns the type parameters of this type if it has some (i.e. is an ADT
    /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
    fn substs(&self) -> Option<Substs> {
        match self {
            Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
            _ => None,
        }
    }
}

impl HirDisplay for &Ty {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        HirDisplay::hir_fmt(*self, f)
    }
}

impl HirDisplay for ApplicationTy {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        match self.name {
            TypeCtor::Bool => write!(f, "bool")?,
            TypeCtor::Char => write!(f, "char")?,
            TypeCtor::Int(t) => write!(f, "{}", t)?,
            TypeCtor::Float(t) => write!(f, "{}", t)?,
            TypeCtor::Str => write!(f, "str")?,
            TypeCtor::Slice | TypeCtor::Array => {
                let t = self.parameters.as_single();
                write!(f, "[{}]", t.display(f.db))?;
            }
            TypeCtor::RawPtr(m) => {
                let t = self.parameters.as_single();
                write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
            }
            TypeCtor::Ref(m) => {
                let t = self.parameters.as_single();
                write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
            }
            TypeCtor::Never => write!(f, "!")?,
            TypeCtor::Tuple => {
                let ts = &self.parameters;
                if ts.0.len() == 1 {
                    write!(f, "({},)", ts.0[0].display(f.db))?;
                } else {
                    write!(f, "(")?;
                    f.write_joined(&*ts.0, ", ")?;
                    write!(f, ")")?;
                }
            }
            TypeCtor::FnPtr => {
                let sig = FnSig::from_fn_ptr_substs(&self.parameters);
                write!(f, "fn(")?;
                f.write_joined(sig.params(), ", ")?;
                write!(f, ") -> {}", sig.ret().display(f.db))?;
            }
            TypeCtor::FnDef(def) => {
                let sig = f.db.callable_item_signature(def);
                let name = match def {
                    CallableDef::Function(ff) => ff.name(f.db),
                    CallableDef::Struct(s) => s.name(f.db).unwrap_or_else(Name::missing),
                    CallableDef::EnumVariant(e) => e.name(f.db).unwrap_or_else(Name::missing),
                };
                match def {
                    CallableDef::Function(_) => write!(f, "fn {}", name)?,
                    CallableDef::Struct(_) | CallableDef::EnumVariant(_) => write!(f, "{}", name)?,
                }
                if self.parameters.0.len() > 0 {
                    write!(f, "<")?;
                    f.write_joined(&*self.parameters.0, ", ")?;
                    write!(f, ">")?;
                }
                write!(f, "(")?;
                f.write_joined(sig.params(), ", ")?;
                write!(f, ") -> {}", sig.ret().display(f.db))?;
            }
            TypeCtor::Adt(def_id) => {
                let name = match def_id {
                    AdtDef::Struct(s) => s.name(f.db),
                    AdtDef::Enum(e) => e.name(f.db),
                }
                .unwrap_or_else(Name::missing);
                write!(f, "{}", name)?;
                if self.parameters.0.len() > 0 {
                    write!(f, "<")?;
                    f.write_joined(&*self.parameters.0, ", ")?;
                    write!(f, ">")?;
                }
            }
        }
        Ok(())
    }
}

impl HirDisplay for Ty {
    fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
        match self {
            Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
            Ty::Param { name, .. } => write!(f, "{}", name)?,
            Ty::Unknown => write!(f, "{{unknown}}")?,
            Ty::Infer(..) => write!(f, "_")?,
        }
        Ok(())
    }
}
<|endoftext|>


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

use model::Subsystem;
use juniper::Context as JuniperContext;

/// Context used to pass global data into Juniper queries
pub struct Context {
    pub subsystem: Subsystem,
}

impl JuniperContext for Context {}

impl Context {
    /// Give us a reference to subsystem for passing
    /// along the Juniper chain
    pub fn get_subsystem(&self) -> &Subsystem {
        &self.subsystem
    }
}

/// GraphQL model for Subsystem
graphql_object!(Subsystem: Context as "Subsystem" |&self| {
    description: "Handler subsystem"

    field power() -> bool as "Power state of subsystem" {
        self.power()
    }

    field uptime() -> i32 as "Uptime of subsystem" {
        self.uptime()
    }
});

pub struct QueryRoot;

/// GraphQL model for base query
graphql_object!(QueryRoot : Context as "Query" |&self| {
    field subsystem(&executor) -> Option<&Subsystem>
        as "Subsystem query"
    {
        Some(executor.context().get_subsystem())
    }
});
<commit_msg>Moved from using Option to FieldResult for field return type.<commit_after>//
// Copyright (C) 2017 Kubos Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use model::Subsystem;
use juniper::Context as JuniperContext;

use juniper::FieldResult;

/// Context used to pass global data into Juniper queries
pub struct Context {
    pub subsystem: Subsystem,
}

impl JuniperContext for Context {}

impl Context {
    /// Give us a reference to subsystem for passing
    /// along the Juniper chain
    pub fn get_subsystem(&self) -> &Subsystem {
        &self.subsystem
    }
}

/// GraphQL model for Subsystem
graphql_object!(Subsystem: Context as "Subsystem" |&self| {
    description: "Handler subsystem"

    field power() -> bool as "Power state of subsystem" {
        self.power()
    }

    field uptime() -> i32 as "Uptime of subsystem" {
        self.uptime()
    }
});

pub struct QueryRoot;

/// GraphQL model for base query
graphql_object!(QueryRoot : Context as "Query" |&self| {
    field subsystem(&executor) -> FieldResult<&Subsystem>
        as "Subsystem query"
    {
        Ok(executor.context().get_subsystem())
    }
});
<|endoftext|>


<commit_before>// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::env;
use std::path::PathBuf;

use anyhow::{Context, Result};

fn main() -> Result<()> {
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

    let target_dir = env::var("OUT_DIR").context("failed to get OUT_DIR")?;
    let output_file = PathBuf::from(target_dir)
        .join("crosvm_control.h")
        .display()
        .to_string();

    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .generate()
        .context("Unable to generate bindings")?
        .write_to_file(&output_file);

    Ok(())
}
<commit_msg>crosvm_control: Skip build.rs when cargo-doc is called<commit_after>// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::env;
use std::path::PathBuf;

use anyhow::{Context, Result};

fn main() -> Result<()> {
    // Skip building dependencies when generating documents.
    if std::env::var("CARGO_DOC").is_ok() {
        return Ok(());
    }

    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

    let target_dir = env::var("OUT_DIR").context("failed to get OUT_DIR")?;
    let output_file = PathBuf::from(target_dir)
        .join("crosvm_control.h")
        .display()
        .to_string();

    cbindgen::Builder::new()
        .with_crate(crate_dir)
        .generate()
        .context("Unable to generate bindings")?
        .write_to_file(&output_file);

    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate image;

use std::thread;

#[allow(unused_imports)]
use glium::{glutin, Surface};
use glium::index::PrimitiveType;

mod screenshot {
    use glium::Surface;
    use std::collections::VecDeque;
    use std::vec::Vec;
    use std::borrow::Cow;

    use glium;

    // Container that holds image data as vector of (u8, u8, u8, u8).
    // This is used to take data from PixelBuffer and move it to another thread
    // with minimum conversions done on main thread.
    pub struct RGBAImageData {
        pub data: Vec<(u8, u8, u8, u8)>,
        pub width: u32,
        pub height: u32,
    }

    impl glium::texture::Texture2dDataSink<(u8, u8, u8, u8)> for RGBAImageData {
        fn from_raw(data: Cow<[(u8, u8, u8, u8)]>, width: u32, height: u32) -> Self {
            RGBAImageData {
                data: data.into_owned(),
                width: width,
                height: height,
            }
        }
    }

    struct AsyncScreenshotTask {
        pub target_frame: u64,
        pub pixel_buffer: glium::texture::pixel_buffer::PixelBuffer<(u8, u8, u8, u8)>,
    }

    impl AsyncScreenshotTask {
        fn new(facade: &dyn glium::backend::Facade, target_frame: u64) -> Self {
            // Get information about current framebuffer
            let dimensions = facade.get_context().get_framebuffer_dimensions();
            let rect = glium::Rect {
                left: 0,
                bottom: 0,
                width: dimensions.0,
                height: dimensions.1,
            };
            let blit_target = glium::BlitTarget {
                left: 0,
                bottom: 0,
                width: dimensions.0 as i32,
                height: dimensions.1 as i32,
            };

            // Create temporary texture and blit the front buffer to it
            let texture = glium::texture::Texture2d::empty(facade, dimensions.0, dimensions.1)
                .unwrap();
            let framebuffer = glium::framebuffer::SimpleFrameBuffer::new(facade, &texture).unwrap();
            framebuffer.blit_from_frame(&rect,
                                        &blit_target,
                                        glium::uniforms::MagnifySamplerFilter::Nearest);

            // Read the texture into new pixel buffer
            let pixel_buffer = texture.read_to_pixel_buffer();

            AsyncScreenshotTask {
                target_frame: target_frame,
                pixel_buffer: pixel_buffer,
            }
        }

        fn read_image_data(self) -> RGBAImageData {
            self.pixel_buffer.read_as_texture_2d().unwrap()
        }
    }

    pub struct ScreenshotIterator<'a>(&'a mut AsyncScreenshotTaker);

    impl<'a> Iterator for ScreenshotIterator<'a> {
        type Item = RGBAImageData;

        fn next(&mut self) -> Option<RGBAImageData> {
            if self.0.screenshot_tasks.front().map(|task| task.target_frame) == Some(self.0.frame) {
                let task = self.0.screenshot_tasks.pop_front().unwrap();
                Some(task.read_image_data())
            } else {
                None
            }
        }
    }

    pub struct AsyncScreenshotTaker {
        screenshot_delay: u64,
        frame: u64,
        screenshot_tasks: VecDeque<AsyncScreenshotTask>,
    }

    impl AsyncScreenshotTaker {
        pub fn new(screenshot_delay: u64) -> Self {
            AsyncScreenshotTaker {
                screenshot_delay: screenshot_delay,
                frame: 0,
                screenshot_tasks: VecDeque::new(),
            }
        }

        pub fn next_frame(&mut self) {
            self.frame += 1;
        }

        pub fn pickup_screenshots(&mut self) -> ScreenshotIterator {
            ScreenshotIterator(self)
        }

        pub fn take_screenshot(&mut self, facade: &dyn glium::backend::Facade) {
            self.screenshot_tasks
                .push_back(AsyncScreenshotTask::new(facade, self.frame + self.screenshot_delay));
        }
    }
}

fn main() {
    // building the display, ie. the main object
    let event_loop = glutin::event_loop::EventLoop::new();
    let wb = glutin::window::WindowBuilder::new().with_title("Press S to take screenshot");
    let cb = glutin::ContextBuilder::new();
    let display = glium::Display::new(wb, cb, &event_loop).unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
            color: [f32; 3],
        }

        implement_vertex!(Vertex, position, color);

        glium::VertexBuffer::new(&display,
                                 &[Vertex {
                                       position: [-0.5, -0.5],
                                       color: [0.0, 1.0, 0.0],
                                   },
                                   Vertex {
                                       position: [0.0, 0.5],
                                       color: [0.0, 0.0, 1.0],
                                   },
                                   Vertex {
                                       position: [0.5, -0.5],
                                       color: [1.0, 0.0, 0.0],
                                   }])
            .unwrap()
    };

    // building the index buffer
    let index_buffer =
        glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList, &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        140 => {
            vertex: "
                #version 140

                uniform mat4 matrix;

                in vec2 position;
                in vec3 color;

                out vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 140
                in vec3 vColor;
                out vec4 f_color;

                void main() {
                    f_color = vec4(vColor, 1.0);
                }
            "
        },

        110 => {
            vertex: "
                #version 110

                uniform mat4 matrix;

                attribute vec2 position;
                attribute vec3 color;

                varying vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 110
                varying vec3 vColor;

                void main() {
                    gl_FragColor = vec4(vColor, 1.0);
                }
            ",
        },
    )
        .unwrap();

    // drawing once

    // building the uniforms
    let uniforms = uniform! {
        matrix: [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0f32]
        ]
    };

    // The parameter sets the amount of frames between requesting the image
    // transfer and picking it up. If the value is too small, the main thread
    // will block waiting for the image to finish transferring. Tune it based on
    // your requirements.
    let mut screenshot_taker = screenshot::AsyncScreenshotTaker::new(5);

    loop {
        let mut closed = false;
        let mut take_screenshot = false;

        // React to events
        event_loop.poll_events(|event| {
            use glium::glutin::event::{Event, WindowEvent, ElementState, VirtualKeyCode};

            match event {
                Event::WindowEvent { event, .. } => match event {
                    WindowEvent::CloseRequested => closed = true,
                    WindowEvent::KeyboardInput { input, .. } => {
                        if let ElementState::Pressed = input.state {
                            if let Some(VirtualKeyCode::S) = input.virtual_keycode {
                                take_screenshot = true;
                            }
                        }
                    },
                    _ => (),
                },
                _ => (),
            }
        });

        if closed {
            return;
        }

        // Tell Screenshot Taker to count next frame
        screenshot_taker.next_frame();

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer,
                  &index_buffer,
                  &program,
                  &uniforms,
                  &Default::default())
            .unwrap();
        target.finish().unwrap();

        if take_screenshot {
            // Take screenshot and queue it's delivery
            screenshot_taker.take_screenshot(&display);
        }

        // Pick up screenshots that are ready this frame
        for image_data in screenshot_taker.pickup_screenshots() {
            // Process and write the image in separate thread to not block the rendering thread.
            thread::spawn(move || {
                // Convert (u8, u8, u8, u8) given by glium's PixelBuffer to flat u8 required by
                // image's ImageBuffer.
                let pixels = {
                    let mut v = Vec::with_capacity(image_data.data.len() * 4);
                    for (a, b, c, d) in image_data.data {
                        v.push(a);
                        v.push(b);
                        v.push(c);
                        v.push(d);
                    }
                    v
                };

                // Create ImageBuffer
                let image_buffer =
                    image::ImageBuffer::from_raw(image_data.width, image_data.height, pixels)
                        .unwrap();

                // Save the screenshot to file
                let image = image::DynamicImage::ImageRgba8(image_buffer).flipv();
                image.save("glium-example-screenshot.png").unwrap();
            });
        }
    }
}
<commit_msg>Fix screenshot example<commit_after>#[macro_use]
extern crate glium;
extern crate image;

use std::thread;

#[allow(unused_imports)]
use glium::{glutin, Surface};
use glium::index::PrimitiveType;

mod screenshot {
    use glium::Surface;
    use std::collections::VecDeque;
    use std::vec::Vec;
    use std::borrow::Cow;

    use glium;

    // Container that holds image data as vector of (u8, u8, u8, u8).
    // This is used to take data from PixelBuffer and move it to another thread
    // with minimum conversions done on main thread.
    pub struct RGBAImageData {
        pub data: Vec<(u8, u8, u8, u8)>,
        pub width: u32,
        pub height: u32,
    }

    impl glium::texture::Texture2dDataSink<(u8, u8, u8, u8)> for RGBAImageData {
        fn from_raw(data: Cow<[(u8, u8, u8, u8)]>, width: u32, height: u32) -> Self {
            RGBAImageData {
                data: data.into_owned(),
                width: width,
                height: height,
            }
        }
    }

    struct AsyncScreenshotTask {
        pub target_frame: u64,
        pub pixel_buffer: glium::texture::pixel_buffer::PixelBuffer<(u8, u8, u8, u8)>,
    }

    impl AsyncScreenshotTask {
        fn new(facade: &dyn glium::backend::Facade, target_frame: u64) -> Self {
            // Get information about current framebuffer
            let dimensions = facade.get_context().get_framebuffer_dimensions();
            let rect = glium::Rect {
                left: 0,
                bottom: 0,
                width: dimensions.0,
                height: dimensions.1,
            };
            let blit_target = glium::BlitTarget {
                left: 0,
                bottom: 0,
                width: dimensions.0 as i32,
                height: dimensions.1 as i32,
            };

            // Create temporary texture and blit the front buffer to it
            let texture = glium::texture::Texture2d::empty(facade, dimensions.0, dimensions.1)
                .unwrap();
            let framebuffer = glium::framebuffer::SimpleFrameBuffer::new(facade, &texture).unwrap();
            framebuffer.blit_from_frame(&rect,
                                        &blit_target,
                                        glium::uniforms::MagnifySamplerFilter::Nearest);

            // Read the texture into new pixel buffer
            let pixel_buffer = texture.read_to_pixel_buffer();

            AsyncScreenshotTask {
                target_frame: target_frame,
                pixel_buffer: pixel_buffer,
            }
        }

        fn read_image_data(self) -> RGBAImageData {
            self.pixel_buffer.read_as_texture_2d().unwrap()
        }
    }

    pub struct ScreenshotIterator<'a>(&'a mut AsyncScreenshotTaker);

    impl<'a> Iterator for ScreenshotIterator<'a> {
        type Item = RGBAImageData;

        fn next(&mut self) -> Option<RGBAImageData> {
            if self.0.screenshot_tasks.front().map(|task| task.target_frame) == Some(self.0.frame) {
                let task = self.0.screenshot_tasks.pop_front().unwrap();
                Some(task.read_image_data())
            } else {
                None
            }
        }
    }

    pub struct AsyncScreenshotTaker {
        screenshot_delay: u64,
        frame: u64,
        screenshot_tasks: VecDeque<AsyncScreenshotTask>,
    }

    impl AsyncScreenshotTaker {
        pub fn new(screenshot_delay: u64) -> Self {
            AsyncScreenshotTaker {
                screenshot_delay: screenshot_delay,
                frame: 0,
                screenshot_tasks: VecDeque::new(),
            }
        }

        pub fn next_frame(&mut self) {
            self.frame += 1;
        }

        pub fn pickup_screenshots(&mut self) -> ScreenshotIterator {
            ScreenshotIterator(self)
        }

        pub fn take_screenshot(&mut self, facade: &dyn glium::backend::Facade) {
            self.screenshot_tasks
                .push_back(AsyncScreenshotTask::new(facade, self.frame + self.screenshot_delay));
        }
    }
}

fn main() {
    // building the display, ie. the main object
    let event_loop = glutin::event_loop::EventLoop::new();
    let wb = glutin::window::WindowBuilder::new().with_title("Press S to take screenshot");
    let cb = glutin::ContextBuilder::new();
    let display = glium::Display::new(wb, cb, &event_loop).unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
            color: [f32; 3],
        }

        implement_vertex!(Vertex, position, color);

        glium::VertexBuffer::new(&display,
                                 &[Vertex {
                                       position: [-0.5, -0.5],
                                       color: [0.0, 1.0, 0.0],
                                   },
                                   Vertex {
                                       position: [0.0, 0.5],
                                       color: [0.0, 0.0, 1.0],
                                   },
                                   Vertex {
                                       position: [0.5, -0.5],
                                       color: [1.0, 0.0, 0.0],
                                   }])
            .unwrap()
    };

    // building the index buffer
    let index_buffer =
        glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList, &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        140 => {
            vertex: "
                #version 140

                uniform mat4 matrix;

                in vec2 position;
                in vec3 color;

                out vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 140
                in vec3 vColor;
                out vec4 f_color;

                void main() {
                    f_color = vec4(vColor, 1.0);
                }
            "
        },

        110 => {
            vertex: "
                #version 110

                uniform mat4 matrix;

                attribute vec2 position;
                attribute vec3 color;

                varying vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 110
                varying vec3 vColor;

                void main() {
                    gl_FragColor = vec4(vColor, 1.0);
                }
            ",
        },
    )
        .unwrap();

    // drawing once

    // building the uniforms
    let uniforms = uniform! {
        matrix: [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0f32]
        ]
    };

    // The parameter sets the amount of frames between requesting the image
    // transfer and picking it up. If the value is too small, the main thread
    // will block waiting for the image to finish transferring. Tune it based on
    // your requirements.
    let mut screenshot_taker = screenshot::AsyncScreenshotTaker::new(5);

    event_loop.run(move |event, _, control_flow| {

        // React to events
        use glium::glutin::event::{Event, WindowEvent, ElementState, VirtualKeyCode};

        let mut take_screenshot = false;

        let next_frame_time = std::time::Instant::now() +
            std::time::Duration::from_nanos(16_666_667);
        *control_flow = glutin::event_loop::ControlFlow::WaitUntil(next_frame_time);

        match event {
            Event::WindowEvent { event, .. } => match event {
                WindowEvent::CloseRequested => {
                    *control_flow = glutin::event_loop::ControlFlow::Exit;
                    return;
                },
                WindowEvent::KeyboardInput { input, .. } => {
                    if let ElementState::Pressed = input.state {
                        if let Some(VirtualKeyCode::S) = input.virtual_keycode {
                            take_screenshot = true;
                        }
                    }
                },
                _ => return,
            },
            Event::NewEvents(cause) => match cause {
                glutin::event::StartCause::ResumeTimeReached { .. } => (),
                glutin::event::StartCause::Init => (),
                _ => return,
            },
            _ => return,
        }

        // Tell Screenshot Taker to count next frame
        screenshot_taker.next_frame();

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer,
                  &index_buffer,
                  &program,
                  &uniforms,
                  &Default::default())
            .unwrap();
        target.finish().unwrap();

        if take_screenshot {
            // Take screenshot and queue it's delivery
            screenshot_taker.take_screenshot(&display);
        }

        // Pick up screenshots that are ready this frame
        for image_data in screenshot_taker.pickup_screenshots() {
            // Process and write the image in separate thread to not block the rendering thread.
            thread::spawn(move || {
                // Convert (u8, u8, u8, u8) given by glium's PixelBuffer to flat u8 required by
                // image's ImageBuffer.
                let pixels = {
                    let mut v = Vec::with_capacity(image_data.data.len() * 4);
                    for (a, b, c, d) in image_data.data {
                        v.push(a);
                        v.push(b);
                        v.push(c);
                        v.push(d);
                    }
                    v
                };

                // Create ImageBuffer
                let image_buffer =
                    image::ImageBuffer::from_raw(image_data.width, image_data.height, pixels)
                        .unwrap();

                // Save the screenshot to file
                let image = image::DynamicImage::ImageRgba8(image_buffer).flipv();
                image.save("glium-example-screenshot.png").unwrap();
            });
        }
    });
}
<|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.

#![forbid(non_camel_case_types)]
#![allow(dead_code)]

struct ONE_TWO_THREE;
//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`

struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
    bar: isize,
}

enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
    Bar
}

struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
    bar: isize
}

type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`

enum Foo5 {
    bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
}

trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
    fn dummy(&self) { }
}

fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`

#[repr(C)]
struct foo7 {
    bar: isize,
}

type __ = isize; //~ ERROR type `__` should have a camel case name such as `CamelCase`

fn main() { }
<commit_msg>Add tests<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.

#![forbid(non_camel_case_types)]
#![allow(dead_code)]

struct ONE_TWO_THREE;
//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`

struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
    bar: isize,
}

enum foo2 { //~ ERROR type `foo2` should have a camel case name such as `Foo2`
    Bar
}

struct foo3 { //~ ERROR type `foo3` should have a camel case name such as `Foo3`
    bar: isize
}

type foo4 = isize; //~ ERROR type `foo4` should have a camel case name such as `Foo4`

enum Foo5 {
    bar //~ ERROR variant `bar` should have a camel case name such as `Bar`
}

trait foo6 { //~ ERROR trait `foo6` should have a camel case name such as `Foo6`
    fn dummy(&self) { }
}

fn f<ty>(_: ty) {} //~ ERROR type parameter `ty` should have a camel case name such as `Ty`

#[repr(C)]
struct foo7 {
    bar: isize,
}

type __ = isize; //~ ERROR type `__` should have a camel case name such as `CamelCase`

struct X86_64;

struct X86__64; //~ ERROR type `X86__64` should have a camel case name such as `X86_64`

struct Abc_123; //~ ERROR type `Abc_123` should have a camel case name such as `Abc123`

struct A1_b2_c3; //~ ERROR type `A1_b2_c3` should have a camel case name such as `A1B2C3`

fn main() { }
<|endoftext|>


<commit_before>// AsRef and AsMut allow for cheap reference-to-reference conversions.
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.

// I AM NOT DONE
// Obtain the number of bytes (not characters) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn byte_counter<T>(arg: T) -> usize {
    arg.as_ref().as_bytes().len()
}

// I AM NOT DONE
// Obtain the number of characters (not bytes) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn char_counter<T>(arg: T) -> usize {
    arg.as_ref().chars().collect::<Vec<_>>().len()
}

fn main() {
    let s = "Café au lait";
    println!("{}", char_counter(s));
    println!("{}", byte_counter(s));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn different_counts() {
        let s = "Café au lait";
        assert_ne!(char_counter(s), byte_counter(s));
    }
    fn same_counts() {
        let s = "Cafe au lait";
        assert_eq!(char_counter(s), byte_counter(s));
    }
}<commit_msg>Enable a test and improve per clippy's suggestion. (#256)<commit_after>// AsRef and AsMut allow for cheap reference-to-reference conversions.
// Read more about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html
// and https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively.

// I AM NOT DONE
// Obtain the number of bytes (not characters) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn byte_counter<T>(arg: T) -> usize {
    arg.as_ref().as_bytes().len()
}

// I AM NOT DONE
// Obtain the number of characters (not bytes) in the given argument
// Add the AsRef trait appropriately as a trait bound
fn char_counter<T>(arg: T) -> usize {
    arg.as_ref().chars().count()
}

fn main() {
    let s = "Café au lait";
    println!("{}", char_counter(s));
    println!("{}", byte_counter(s));
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn different_counts() {
        let s = "Café au lait";
        assert_ne!(char_counter(s), byte_counter(s));
    }

    #[test]
    fn same_counts() {
        let s = "Cafe au lait";
        assert_eq!(char_counter(s), byte_counter(s));
    }
}
<|endoftext|>


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

extern crate glob;
extern crate libloading;

use ::engine::App;
use ::engine::backend::{Config, Plugin, State, Type};
use ::util::Version;

use self::glob::glob;
use self::libloading::{Library, Symbol};

/*===============================================================================================*/
/*------MANAGER STRUCT---------------------------------------------------------------------------*/
/*===============================================================================================*/

/// Manages the loading of the various backend systems.
#[derive (Default)]
pub struct Manager {

    // Private
    _config: Config,
    _backend_list: Vec<Plugin>,
    _ext: String,
}

/*===============================================================================================*/
/*------MANAGER PUBLIC METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl Manager {

    /// Loads the configuration file.
    pub fn load_config (&mut self) {

        // Get a pointer to the config manager
        let cfg_mgr = App::get_config_manager ().unwrap ();
        let cfg_exists = cfg_mgr.borrow ().config_exists ("backend_manager");

        // Check if the config file for the backend manager exists.
        // If so, load it.
        // If not, create it.
        let cfg = {

            if cfg_exists {
                cfg_mgr.borrow ().load_config::<Config> ("backend_manager").unwrap ()
            }

            else {

                cfg_mgr.borrow_mut ().create_config::<Config> ("backend_manager");
                cfg_mgr.borrow ().load_config::<Config> ("backend_manager").unwrap ()
            }
        };

        self._config = cfg;
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Queries the backend directory for plugins.
    ///
    /// All valid backend plugins are then registered with the manager for loading.
    /// Any plugins with errors are ignored.
    pub fn query_backend_dir (&mut self) {

        // Clear the old backend list
        self._backend_list.clear ();
        info! ("Searching for backend plugins...");

        // Recurse through the backend directory, and get all backend plugins
        for path in glob (&format! ("{}/*{}", &self._config.backend_dir, &self._ext)).unwrap ().filter_map (Result::ok) {

            info! ("Found: {:?}", &path.file_name ());

            // Load the library and get the function symbols.
            match Library::new (&path) {

                Ok (lib) => {

                    // Plugin name
                    let get_name: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_name\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_name' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin author
                    let get_author: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_author\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_author' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin version
                    let get_version: Symbol<unsafe extern fn () -> Version> = unsafe {

                        match lib.get (b"get_version\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_version' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin description
                    let get_description: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_description\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_description' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin type
                    let get_type: Symbol<unsafe extern fn () -> Type> = unsafe {

                        match lib.get (b"get_type\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_type' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Create a new instance of the plugin, and add it to the list
                    unsafe {

                        self._backend_list.push (Plugin {name: get_name (),
                                                         author: get_author (),
                                                         version: get_version (),
                                                         description: get_description (),
                                                         path: path.to_str ().unwrap ().to_string (),
                                                         b_type: get_type (),
                                                         state: State::Unloaded});
                    }

                    info! ("Added: {:?}", &path.file_name ());
                },

                Err (e) => {

                    warn! ("Could not load library {:?}\n{}", &path.file_name ().unwrap (), e);
                    continue;
                }
            }
        }
    }

/*===============================================================================================*/
/*------MANAGER PUBLIC STATIC METHODS------------------------------------------------------------*/
/*===============================================================================================*/

    /// Creates a new instance of the BackendManager.
    ///
    /// # Return value
    /// A new instance of the backend manager.
    pub fn new () -> Manager {

        // Set the platform extension
        let plug_ext = if cfg! (target_os = "windows") {".dll"}
                       else if cfg! (target_os = "linux") {".so"}
                       else if cfg! (target_os = "macos") {".dylib"}
                       else {panic! ("Platform unsupported")};
        Manager {

            _config: Config::default (),
            _backend_list: Vec::new (),
            _ext: plug_ext.to_string ()
        }
    }
}
<commit_msg>Added list backends method and directory checking<commit_after>/*===============================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*===============================================================================================*/

extern crate glob;
extern crate libloading;

use ::engine::App;
use ::engine::backend::{Config, Plugin, State, Type};
use ::util::Version;

use self::glob::glob;
use self::libloading::{Library, Symbol};

use std::fs;

/*===============================================================================================*/
/*------MANAGER STRUCT---------------------------------------------------------------------------*/
/*===============================================================================================*/

/// Manages the loading of the various backend systems.
#[derive (Default)]
pub struct Manager {

    // Private
    _config: Config,
    _backend_list: Vec<Plugin>,
    _ext: String,
}

/*===============================================================================================*/
/*------MANAGER PUBLIC METHODS-------------------------------------------------------------------*/
/*===============================================================================================*/

impl Manager {

    /// Loads the configuration file.
    pub fn load_config (&mut self) {

        // Get a pointer to the config manager
        let cfg_mgr = App::get_config_manager ().unwrap ();
        let cfg_exists = cfg_mgr.borrow ().config_exists ("backend_manager");

        // Check if the config file for the backend manager exists.
        // If so, load it.
        // If not, create it.
        let cfg = {

            if cfg_exists {
                cfg_mgr.borrow ().load_config::<Config> ("backend_manager").unwrap ()
            }

            else {

                cfg_mgr.borrow_mut ().create_config::<Config> ("backend_manager");
                cfg_mgr.borrow ().load_config::<Config> ("backend_manager").unwrap ()
            }
        };

        self._config = cfg;
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Queries the backend directory for plugins.
    ///
    /// All valid backend plugins are then registered with the manager for loading.
    /// Any plugins with errors are ignored.
    pub fn query_backend_dir (&mut self) {

        // Clear the old backend list
        self._backend_list.clear ();
        info! ("Searching for backend plugins...");

        if !&self._check_backend_dir_exists () {
            return;
        }

        // Recurse through the backend directory, and get all backend plugins
        for path in glob (&format! ("{}/*{}", &self._config.backend_dir, &self._ext)).unwrap ().filter_map (Result::ok) {

            info! ("Found: {:?}", &path.file_name ().unwrap ());

            // Load the library and get the function symbols.
            match Library::new (&path) {

                Ok (lib) => {

                    // Plugin name
                    let get_name: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_name\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_name' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin author
                    let get_author: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_author\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_author' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin version
                    let get_version: Symbol<unsafe extern fn () -> Version> = unsafe {

                        match lib.get (b"get_version\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_version' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin description
                    let get_description: Symbol<unsafe extern fn () -> String> = unsafe {

                        match lib.get (b"get_description\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_description' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Plugin type
                    let get_type: Symbol<unsafe extern fn () -> Type> = unsafe {

                        match lib.get (b"get_type\0") {

                            Ok (l) => l,
                            Err (e) => {

                                warn! ("Could not find function 'get_type' in library {:?}\n{}",
                                       &path.file_name ().unwrap (), e);
                                continue;
                            }
                        }
                    };

                    // Create a new instance of the plugin, and add it to the list
                    unsafe {

                        self._backend_list.push (Plugin {name: get_name (),
                                                         author: get_author (),
                                                         version: get_version (),
                                                         description: get_description (),
                                                         path: path.to_str ().unwrap ().to_string (),
                                                         b_type: get_type (),
                                                         state: State::Unloaded});
                    }

                    info! ("Added: {:?}", &path.file_name ().unwrap ());
                },

                Err (e) => {

                    warn! ("Could not load library {:?}\n{}", &path.file_name ().unwrap (), e);
                    continue;
                }
            }
        }

        // If list is empty, print empty
        // Otherwise, print searching complete
        if self._backend_list.is_empty () {
            info! ("No backend plugins found.");
        }

        else {
            info! ("Backend searching complete.");
        }
    }

/*-----------------------------------------------------------------------------------------------*/

    /// Lists all avaliable backends of a given type.
    pub fn list_backends (&self, backend_type: Type) -> Vec<String> {

        let mut return_vec = Vec::<String>::new ();

        for backend in &self._backend_list {

            if backend.b_type == backend_type {
                return_vec.push (backend.name.clone ());
            }
        }

        return_vec
    }

/*===============================================================================================*/
/*------MANAGER PUBLIC STATIC METHODS------------------------------------------------------------*/
/*===============================================================================================*/

    /// Creates a new instance of the BackendManager.
    ///
    /// # Return value
    /// A new instance of the backend manager.
    pub fn new () -> Manager {

        // Set the platform extension
        let plug_ext = if cfg! (target_os = "windows") {".dll"}
                       else if cfg! (target_os = "linux") {".so"}
                       else if cfg! (target_os = "macos") {".dylib"}
                       else {panic! ("Platform unsupported")};
        Manager {

            _config: Config::default (),
            _backend_list: Vec::new (),
            _ext: plug_ext.to_string ()
        }
    }

/*===============================================================================================*/
/*------MANAGER PRIVATE METHODS------------------------------------------------------------------*/
/*===============================================================================================*/

    // Checks if the backend directory exists.
    // If not, a new one is created.
    fn _check_backend_dir_exists (&self) -> bool {

        if fs::metadata (&self._config.backend_dir).is_err () {

            warn! ("Backend directory does not exist. Creating one now.");

            // Create new directory and check for errors
            match fs::create_dir (&self._config.backend_dir) {

                Ok  (_) => {

                    info! ("Directory creation successful.");
                    info! ("No backend plugins found.");
                    return false;
                },

                Err (e) => {

                    error! ("Failed to create backend directory: {}", e);
                    panic! ();
                }
            }
        }

        true
    }
}
<|endoftext|>


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

use std::rc::Rc;
use syntax::codemap::CodeMap;
use syntax_pos::{BytePos, FileMap};

#[derive(Clone)]
struct CacheEntry {
    time_stamp: usize,
    line_number: usize,
    line_start: BytePos,
    line_end: BytePos,
    file: Rc<FileMap>,
    file_index: usize,
}

#[derive(Clone)]
pub struct CachingCodemapView<'cm> {
    codemap: &'cm CodeMap,
    line_cache: [CacheEntry; 3],
    time_stamp: usize,
}

impl<'cm> CachingCodemapView<'cm> {
    pub fn new(codemap: &'cm CodeMap) -> CachingCodemapView<'cm> {
        let files = codemap.files();
        let first_file = files[0].clone();
        let entry = CacheEntry {
            time_stamp: 0,
            line_number: 0,
            line_start: BytePos(0),
            line_end: BytePos(0),
            file: first_file,
            file_index: 0,
        };

        CachingCodemapView {
            codemap,
            line_cache: [entry.clone(), entry.clone(), entry.clone()],
            time_stamp: 0,
        }
    }

    pub fn byte_pos_to_line_and_col(&mut self,
                                    pos: BytePos)
                                    -> Option<(Rc<FileMap>, usize, BytePos)> {
        self.time_stamp += 1;

        // Check if the position is in one of the cached lines
        for cache_entry in self.line_cache.iter_mut() {
            if pos >= cache_entry.line_start && pos < cache_entry.line_end {
                cache_entry.time_stamp = self.time_stamp;

                return Some((cache_entry.file.clone(),
                             cache_entry.line_number,
                             pos - cache_entry.line_start));
            }
        }

        // No cache hit ...
        let mut oldest = 0;
        for index in 1 .. self.line_cache.len() {
            if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
                oldest = index;
            }
        }

        let cache_entry = &mut self.line_cache[oldest];

        // If the entry doesn't point to the correct file, fix it up
        if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
            let file_valid;
            let files = self.codemap.files();

            if files.len() > 0 {
                let file_index = self.codemap.lookup_filemap_idx(pos);
                let file = files[file_index].clone();

                if pos >= file.start_pos && pos < file.end_pos {
                    cache_entry.file = file;
                    cache_entry.file_index = file_index;
                    file_valid = true;
                } else {
                    file_valid = false;
                }
            } else {
                file_valid = false;
            }

            if !file_valid {
                return None;
            }
        }

        let line_index = cache_entry.file.lookup_line(pos).unwrap();
        let line_bounds = cache_entry.file.line_bounds(line_index);

        cache_entry.line_number = line_index + 1;
        cache_entry.line_start = line_bounds.0;
        cache_entry.line_end = line_bounds.1;
        cache_entry.time_stamp = self.time_stamp;

        return Some((cache_entry.file.clone(),
                     cache_entry.line_number,
                     pos - cache_entry.line_start));
    }
}
<commit_msg>Refactor code so the call to codemap.files() does not deadlock<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::rc::Rc;
use syntax::codemap::CodeMap;
use syntax_pos::{BytePos, FileMap};

#[derive(Clone)]
struct CacheEntry {
    time_stamp: usize,
    line_number: usize,
    line_start: BytePos,
    line_end: BytePos,
    file: Rc<FileMap>,
    file_index: usize,
}

#[derive(Clone)]
pub struct CachingCodemapView<'cm> {
    codemap: &'cm CodeMap,
    line_cache: [CacheEntry; 3],
    time_stamp: usize,
}

impl<'cm> CachingCodemapView<'cm> {
    pub fn new(codemap: &'cm CodeMap) -> CachingCodemapView<'cm> {
        let files = codemap.files();
        let first_file = files[0].clone();
        let entry = CacheEntry {
            time_stamp: 0,
            line_number: 0,
            line_start: BytePos(0),
            line_end: BytePos(0),
            file: first_file,
            file_index: 0,
        };

        CachingCodemapView {
            codemap,
            line_cache: [entry.clone(), entry.clone(), entry.clone()],
            time_stamp: 0,
        }
    }

    pub fn byte_pos_to_line_and_col(&mut self,
                                    pos: BytePos)
                                    -> Option<(Rc<FileMap>, usize, BytePos)> {
        self.time_stamp += 1;

        // Check if the position is in one of the cached lines
        for cache_entry in self.line_cache.iter_mut() {
            if pos >= cache_entry.line_start && pos < cache_entry.line_end {
                cache_entry.time_stamp = self.time_stamp;

                return Some((cache_entry.file.clone(),
                             cache_entry.line_number,
                             pos - cache_entry.line_start));
            }
        }

        // No cache hit ...
        let mut oldest = 0;
        for index in 1 .. self.line_cache.len() {
            if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
                oldest = index;
            }
        }

        let cache_entry = &mut self.line_cache[oldest];

        // If the entry doesn't point to the correct file, fix it up
        if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
            let file_valid;
            if self.codemap.files().len() > 0 {
                let file_index = self.codemap.lookup_filemap_idx(pos);
                let file = self.codemap.files()[file_index].clone();

                if pos >= file.start_pos && pos < file.end_pos {
                    cache_entry.file = file;
                    cache_entry.file_index = file_index;
                    file_valid = true;
                } else {
                    file_valid = false;
                }
            } else {
                file_valid = false;
            }

            if !file_valid {
                return None;
            }
        }

        let line_index = cache_entry.file.lookup_line(pos).unwrap();
        let line_bounds = cache_entry.file.line_bounds(line_index);

        cache_entry.line_number = line_index + 1;
        cache_entry.line_start = line_bounds.0;
        cache_entry.line_end = line_bounds.1;
        cache_entry.time_stamp = self.time_stamp;

        return Some((cache_entry.file.clone(),
                     cache_entry.line_number,
                     pos - cache_entry.line_start));
    }
}
<|endoftext|>


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

use target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        linker: "cc".to_string(),
        dynamic_linking: true,
        executables: true,
        morestack: true,
        has_rpath: true,
        pre_link_args: vec!(
            "-L/usr/local/lib".to_string(),
            "-L/usr/local/lib/gcc46".to_string(),
            "-L/usr/local/lib/gcc44".to_string(),
        ),

        .. Default::default()
    }
}
<commit_msg>FreeBSD: Don't add -L/usr/local/lib{,/gcc4[46]}.<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.

use target::TargetOptions;
use std::default::Default;

pub fn opts() -> TargetOptions {
    TargetOptions {
        linker: "cc".to_string(),
        dynamic_linking: true,
        executables: true,
        morestack: true,
        has_rpath: true,

        .. Default::default()
    }
}
<|endoftext|>