<commit_before>#[cfg(test)]
mod tests {
    use crate::*;

    fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
        let s = &format!("r{}", s);
        let mut cursor = Cursor::new(s);
        cursor.bump();
        let (n_hashes, err) = cursor.raw_double_quoted_string(0);
        assert_eq!(n_hashes, expected_hashes);
        assert_eq!(err, expected_err);
    }

    #[test]
    fn test_naked_raw_str() {
        check_raw_str(r#""abc""#, 0, None);
    }

    #[test]
    fn test_raw_no_start() {
        check_raw_str(r##""abc"#"##, 0, None);
    }

    #[test]
    fn test_too_many_terminators() {
        // this error is handled in the parser later
        check_raw_str(r###"#"abc"##"###, 1, None);
    }

    #[test]
    fn test_unterminated() {
        check_raw_str(
            r#"#"abc"#,
            1,
            Some(RawStrError::NoTerminator {
                expected: 1,
                found: 0,
                possible_terminator_offset: None,
            }),
        );
        check_raw_str(
            r###"##"abc"#"###,
            2,
            Some(RawStrError::NoTerminator {
                expected: 2,
                found: 1,
                possible_terminator_offset: Some(7),
            }),
        );
        // We're looking for "# not just any #
        check_raw_str(
            r###"##"abc#"###,
            2,
            Some(RawStrError::NoTerminator {
                expected: 2,
                found: 0,
                possible_terminator_offset: None,
            }),
        )
    }

    #[test]
    fn test_invalid_start() {
        check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
    }

    #[test]
    fn test_unterminated_no_pound() {
        // https://github.com/rust-lang/rust/issues/70677
        check_raw_str(
            r#"""#,
            0,
            Some(RawStrError::NoTerminator {
                expected: 0,
                found: 0,
                possible_terminator_offset: None,
            }),
        );
    }

    #[test]
    fn test_valid_shebang() {
        // https://github.com/rust-lang/rust/issues/70528
        let input = "#!/usr/bin/rustrun\nlet x = 5;";
        assert_eq!(strip_shebang(input), Some(18));
    }

    #[test]
    fn test_invalid_shebang_valid_rust_syntax() {
        // https://github.com/rust-lang/rust/issues/70528
        let input = "#!    [bad_attribute]";
        assert_eq!(strip_shebang(input), None);
    }

    #[test]
    fn test_shebang_second_line() {
        // Because shebangs are interpreted by the kernel, they must be on the first line
        let input = "\n#!/bin/bash";
        assert_eq!(strip_shebang(input), None);
    }

    #[test]
    fn test_shebang_space() {
        let input = "#!    /bin/bash";
        assert_eq!(strip_shebang(input), Some(input.len()));
    }

    #[test]
    fn test_shebang_empty_shebang() {
        let input = "#!    \n[attribute(foo)]";
        assert_eq!(strip_shebang(input), None);
    }

    #[test]
    fn test_invalid_shebang_comment() {
        let input = "#!//bin/ami/a/comment\n[";
        assert_eq!(strip_shebang(input), None)
    }

    #[test]
    fn test_invalid_shebang_another_comment() {
        let input = "#!/*bin/ami/a/comment*/\n[attribute";
        assert_eq!(strip_shebang(input), None)
    }

    #[test]
    fn test_shebang_valid_rust_after() {
        let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
        assert_eq!(strip_shebang(input), Some(23))
    }

    #[test]
    fn test_shebang_followed_by_attrib() {
        let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
        assert_eq!(strip_shebang(input), Some(19));
    }
}
<commit_msg>Rollup merge of #75769 - matklad:flatten, r=petrochenkov<commit_after>use super::*;

fn check_raw_str(s: &str, expected_hashes: u16, expected_err: Option<RawStrError>) {
    let s = &format!("r{}", s);
    let mut cursor = Cursor::new(s);
    cursor.bump();
    let (n_hashes, err) = cursor.raw_double_quoted_string(0);
    assert_eq!(n_hashes, expected_hashes);
    assert_eq!(err, expected_err);
}

#[test]
fn test_naked_raw_str() {
    check_raw_str(r#""abc""#, 0, None);
}

#[test]
fn test_raw_no_start() {
    check_raw_str(r##""abc"#"##, 0, None);
}

#[test]
fn test_too_many_terminators() {
    // this error is handled in the parser later
    check_raw_str(r###"#"abc"##"###, 1, None);
}

#[test]
fn test_unterminated() {
    check_raw_str(
        r#"#"abc"#,
        1,
        Some(RawStrError::NoTerminator { expected: 1, found: 0, possible_terminator_offset: None }),
    );
    check_raw_str(
        r###"##"abc"#"###,
        2,
        Some(RawStrError::NoTerminator {
            expected: 2,
            found: 1,
            possible_terminator_offset: Some(7),
        }),
    );
    // We're looking for "# not just any #
    check_raw_str(
        r###"##"abc#"###,
        2,
        Some(RawStrError::NoTerminator { expected: 2, found: 0, possible_terminator_offset: None }),
    )
}

#[test]
fn test_invalid_start() {
    check_raw_str(r##"#~"abc"#"##, 1, Some(RawStrError::InvalidStarter { bad_char: '~' }));
}

#[test]
fn test_unterminated_no_pound() {
    // https://github.com/rust-lang/rust/issues/70677
    check_raw_str(
        r#"""#,
        0,
        Some(RawStrError::NoTerminator { expected: 0, found: 0, possible_terminator_offset: None }),
    );
}

#[test]
fn test_valid_shebang() {
    // https://github.com/rust-lang/rust/issues/70528
    let input = "#!/usr/bin/rustrun\nlet x = 5;";
    assert_eq!(strip_shebang(input), Some(18));
}

#[test]
fn test_invalid_shebang_valid_rust_syntax() {
    // https://github.com/rust-lang/rust/issues/70528
    let input = "#!    [bad_attribute]";
    assert_eq!(strip_shebang(input), None);
}

#[test]
fn test_shebang_second_line() {
    // Because shebangs are interpreted by the kernel, they must be on the first line
    let input = "\n#!/bin/bash";
    assert_eq!(strip_shebang(input), None);
}

#[test]
fn test_shebang_space() {
    let input = "#!    /bin/bash";
    assert_eq!(strip_shebang(input), Some(input.len()));
}

#[test]
fn test_shebang_empty_shebang() {
    let input = "#!    \n[attribute(foo)]";
    assert_eq!(strip_shebang(input), None);
}

#[test]
fn test_invalid_shebang_comment() {
    let input = "#!//bin/ami/a/comment\n[";
    assert_eq!(strip_shebang(input), None)
}

#[test]
fn test_invalid_shebang_another_comment() {
    let input = "#!/*bin/ami/a/comment*/\n[attribute";
    assert_eq!(strip_shebang(input), None)
}

#[test]
fn test_shebang_valid_rust_after() {
    let input = "#!/*bin/ami/a/comment*/\npub fn main() {}";
    assert_eq!(strip_shebang(input), Some(23))
}

#[test]
fn test_shebang_followed_by_attrib() {
    let input = "#!/bin/rust-scripts\n#![allow_unused(true)]";
    assert_eq!(strip_shebang(input), Some(19));
}
<|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 std::fs::File;
use std::io::prelude::*;
use std::io;
use std::path::{PathBuf, Path};
use std::str;

#[derive(Clone)]
pub struct ExternalHtml{
    pub in_header: String,
    pub before_content: String,
    pub after_content: String
}

impl ExternalHtml {
    pub fn load(in_header: &[String], before_content: &[String], after_content: &[String])
            -> Option<ExternalHtml> {
        match (load_external_files(in_header),
               load_external_files(before_content),
               load_external_files(after_content)) {
            (Some(ih), Some(bc), Some(ac)) => Some(ExternalHtml {
                in_header: ih,
                before_content: bc,
                after_content: ac
            }),
            _ => None
        }
    }
}

pub fn load_string(input: &Path) -> io::Result<Option<String>> {
    let mut f = File::open(input)?;
    let mut d = Vec::new();
    f.read_to_end(&mut d)?;
    Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
}

macro_rules! load_or_return {
    ($input: expr, $cant_read: expr, $not_utf8: expr) => {
        {
            let input = PathBuf::from(&$input[..]);
            match ::externalfiles::load_string(&input) {
                Err(e) => {
                    let _ = writeln!(&mut io::stderr(),
                                     "error reading `{}`: {}", input.display(), e);
                    return $cant_read;
                }
                Ok(None) => {
                    let _ = writeln!(&mut io::stderr(),
                                     "error reading `{}`: not UTF-8", input.display());
                    return $not_utf8;
                }
                Ok(Some(s)) => s
            }
        }
    }
}

pub fn load_external_files(names: &[String]) -> Option<String> {
    let mut out = String::new();
    for name in names {
        out.push_str(&*load_or_return!(&name, None, None));
        out.push('\n');
    }
    Some(out)
}
<commit_msg>Don't construct `PathBuf` ownership if we don't need it.<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 std::fs::File;
use std::io::prelude::*;
use std::io;
use std::path::Path;
use std::str;

#[derive(Clone)]
pub struct ExternalHtml{
    pub in_header: String,
    pub before_content: String,
    pub after_content: String
}

impl ExternalHtml {
    pub fn load(in_header: &[String], before_content: &[String], after_content: &[String])
            -> Option<ExternalHtml> {
        match (load_external_files(in_header),
               load_external_files(before_content),
               load_external_files(after_content)) {
            (Some(ih), Some(bc), Some(ac)) => Some(ExternalHtml {
                in_header: ih,
                before_content: bc,
                after_content: ac
            }),
            _ => None
        }
    }
}

pub fn load_string(input: &Path) -> io::Result<Option<String>> {
    let mut f = File::open(input)?;
    let mut d = Vec::new();
    f.read_to_end(&mut d)?;
    Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
}

macro_rules! load_or_return {
    ($input: expr, $cant_read: expr, $not_utf8: expr) => {
        {
            let input = Path::new(&$input[..]);
            match ::externalfiles::load_string(input) {
                Err(e) => {
                    let _ = writeln!(&mut io::stderr(),
                                     "error reading `{}`: {}", input.display(), e);
                    return $cant_read;
                }
                Ok(None) => {
                    let _ = writeln!(&mut io::stderr(),
                                     "error reading `{}`: not UTF-8", input.display());
                    return $not_utf8;
                }
                Ok(Some(s)) => s
            }
        }
    }
}

pub fn load_external_files(names: &[String]) -> Option<String> {
    let mut out = String::new();
    for name in names {
        out.push_str(&*load_or_return!(&name, None, None));
        out.push('\n');
    }
    Some(out)
}
<|endoftext|>


<commit_before>//! Compare libc's CMSG(3) family of functions against the actual C macros, for
//! various inputs.

extern crate libc;

#[cfg(unix)]
mod t {

    use libc::{self, c_uchar, c_uint, c_void, cmsghdr, msghdr};
    use std::mem;

    extern "C" {
        pub fn cmsg_firsthdr(msgh: *const msghdr) -> *mut cmsghdr;
        pub fn cmsg_nxthdr(
            mhdr: *const msghdr,
            cmsg: *const cmsghdr,
        ) -> *mut cmsghdr;
        pub fn cmsg_space(length: c_uint) -> usize;
        pub fn cmsg_len(length: c_uint) -> usize;
        pub fn cmsg_data(cmsg: *const cmsghdr) -> *mut c_uchar;
    }

    #[test]
    fn test_cmsg_data() {
        for l in 0..128 {
            let pcmsghdr = l as *const cmsghdr;
            unsafe {
                assert_eq!(libc::CMSG_DATA(pcmsghdr), cmsg_data(pcmsghdr));
            }
        }
    }

    #[test]
    fn test_cmsg_firsthdr() {
        let mut mhdr: msghdr = unsafe { mem::zeroed() };
        mhdr.msg_control = 0xdeadbeef as *mut c_void;
        let pmhdr = &mhdr as *const msghdr;
        for l in 0..128 {
            mhdr.msg_controllen = l;
            unsafe {
                assert_eq!(libc::CMSG_FIRSTHDR(pmhdr), cmsg_firsthdr(pmhdr));
            }
        }
    }

    #[test]
    fn test_cmsg_len() {
        for l in 0..128 {
            unsafe {
                assert_eq!(libc::CMSG_LEN(l) as usize, cmsg_len(l));
            }
        }
    }

    // Skip on sparc64
    // https://github.com/rust-lang/libc/issues/1239
    #[cfg(not(target_arch = "sparc64"))]
    #[test]
    fn test_cmsg_nxthdr() {
        use std::ptr;

        let mut buffer = [0u8; 256];
        let mut mhdr: msghdr = unsafe { mem::zeroed() };
        let pmhdr = &mhdr as *const msghdr;
        for start_ofs in 0..64 {
            let pcmsghdr = &mut buffer[start_ofs] as *mut u8 as *mut cmsghdr;
            mhdr.msg_control = pcmsghdr as *mut c_void;
            mhdr.msg_controllen = (160 - start_ofs) as _;
            for cmsg_len in 0..64 {
                for next_cmsg_len in 0..32 {
                    for i in buffer[start_ofs..].iter_mut() {
                        *i = 0;
                    }
                    unsafe {
                        (*pcmsghdr).cmsg_len = cmsg_len;
                        let libc_next = libc::CMSG_NXTHDR(pmhdr, pcmsghdr);
                        let next = cmsg_nxthdr(pmhdr, pcmsghdr);
                        assert_eq!(libc_next, next);

                        if libc_next != ptr::null_mut() {
                            (*libc_next).cmsg_len = next_cmsg_len;
                            let libc_next = libc::CMSG_NXTHDR(pmhdr, pcmsghdr);
                            let next = cmsg_nxthdr(pmhdr, pcmsghdr);
                            assert_eq!(libc_next, next);
                        }
                    }
                }
            }
        }
    }

    #[test]
    fn test_cmsg_space() {
        unsafe {
            for l in 0..128 {
                assert_eq!(libc::CMSG_SPACE(l) as usize, cmsg_space(l));
            }
        }
    }

}
<commit_msg>Formatting<commit_after>//! Compare libc's CMSG(3) family of functions against the actual C macros, for
//! various inputs.

extern crate libc;

#[cfg(unix)]
mod t {

    use libc::{self, c_uchar, c_uint, c_void, cmsghdr, msghdr};
    use std::mem;

    extern "C" {
        pub fn cmsg_firsthdr(msgh: *const msghdr) -> *mut cmsghdr;
        pub fn cmsg_nxthdr(
            mhdr: *const msghdr,
            cmsg: *const cmsghdr,
        ) -> *mut cmsghdr;
        pub fn cmsg_space(length: c_uint) -> usize;
        pub fn cmsg_len(length: c_uint) -> usize;
        pub fn cmsg_data(cmsg: *const cmsghdr) -> *mut c_uchar;
    }

    #[test]
    fn test_cmsg_data() {
        for l in 0..128 {
            let pcmsghdr = l as *const cmsghdr;
            unsafe {
                assert_eq!(libc::CMSG_DATA(pcmsghdr), cmsg_data(pcmsghdr));
            }
        }
    }

    #[test]
    fn test_cmsg_firsthdr() {
        let mut mhdr: msghdr = unsafe { mem::zeroed() };
        mhdr.msg_control = 0xdeadbeef as *mut c_void;
        let pmhdr = &mhdr as *const msghdr;
        for l in 0..128 {
            mhdr.msg_controllen = l;
            unsafe {
                assert_eq!(libc::CMSG_FIRSTHDR(pmhdr), cmsg_firsthdr(pmhdr));
            }
        }
    }

    #[test]
    fn test_cmsg_len() {
        for l in 0..128 {
            unsafe {
                assert_eq!(libc::CMSG_LEN(l) as usize, cmsg_len(l));
            }
        }
    }

    // Skip on sparc64
    // https://github.com/rust-lang/libc/issues/1239
    #[cfg(not(target_arch = "sparc64"))]
    #[test]
    fn test_cmsg_nxthdr() {
        use std::ptr;

        let mut buffer = [0u8; 256];
        let mut mhdr: msghdr = unsafe { mem::zeroed() };
        let pmhdr = &mhdr as *const msghdr;
        for start_ofs in 0..64 {
            let pcmsghdr = &mut buffer[start_ofs] as *mut u8 as *mut cmsghdr;
            mhdr.msg_control = pcmsghdr as *mut c_void;
            mhdr.msg_controllen = (160 - start_ofs) as _;
            for cmsg_len in 0..64 {
                for next_cmsg_len in 0..32 {
                    for i in buffer[start_ofs..].iter_mut() {
                        *i = 0;
                    }
                    unsafe {
                        (*pcmsghdr).cmsg_len = cmsg_len;
                        let libc_next = libc::CMSG_NXTHDR(pmhdr, pcmsghdr);
                        let next = cmsg_nxthdr(pmhdr, pcmsghdr);
                        assert_eq!(libc_next, next);

                        if libc_next != ptr::null_mut() {
                            (*libc_next).cmsg_len = next_cmsg_len;
                            let libc_next = libc::CMSG_NXTHDR(pmhdr, pcmsghdr);
                            let next = cmsg_nxthdr(pmhdr, pcmsghdr);
                            assert_eq!(libc_next, next);
                        }
                    }
                }
            }
        }
    }

    #[test]
    fn test_cmsg_space() {
        unsafe {
            for l in 0..128 {
                assert_eq!(libc::CMSG_SPACE(l) as usize, cmsg_space(l));
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use super::primitive::*;
use common::Span;
use std::fmt;

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum TypeAnnotation {
    Named(Identifier),
    List(Box<ListTypeAnnotation>),
    NonNull(Box<NonNullTypeAnnotation>),
}

impl fmt::Display for TypeAnnotation {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TypeAnnotation::Named(named) => f.write_fmt(format_args!("{}", named)),
            TypeAnnotation::List(list) => f.write_fmt(format_args!("[{}]", list.type_)),
            TypeAnnotation::NonNull(non_null) => f.write_fmt(format_args!("{}!", non_null.type_)),
        }
    }
}

impl TypeAnnotation {
    pub fn inner(&self) -> &TypeAnnotation {
        match self {
            TypeAnnotation::Named(_) => self,
            TypeAnnotation::List(of) => (*of).type_.inner(),
            TypeAnnotation::NonNull(of) => (*of).type_.inner(),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ListTypeAnnotation {
    pub span: Span,
    pub open: Token,
    pub type_: TypeAnnotation,
    pub close: Token,
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct NonNullTypeAnnotation {
    pub span: Span,
    pub type_: TypeAnnotation,
    pub exclamation: Token,
}
<commit_msg>Add span to TypeAnnotation<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use super::primitive::*;
use common::Span;
use std::fmt;

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum TypeAnnotation {
    Named(Identifier),
    List(Box<ListTypeAnnotation>),
    NonNull(Box<NonNullTypeAnnotation>),
}

impl fmt::Display for TypeAnnotation {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TypeAnnotation::Named(named) => f.write_fmt(format_args!("{}", named)),
            TypeAnnotation::List(list) => f.write_fmt(format_args!("[{}]", list.type_)),
            TypeAnnotation::NonNull(non_null) => f.write_fmt(format_args!("{}!", non_null.type_)),
        }
    }
}

impl TypeAnnotation {
    pub fn inner(&self) -> &TypeAnnotation {
        match self {
            TypeAnnotation::Named(_) => self,
            TypeAnnotation::List(of) => (*of).type_.inner(),
            TypeAnnotation::NonNull(of) => (*of).type_.inner(),
        }
    }

    pub fn span(&self) -> Span {
        match self {
            TypeAnnotation::Named(x) => x.span,
            TypeAnnotation::List(of) => (*of).span,
            TypeAnnotation::NonNull(of) => (*of).span,
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ListTypeAnnotation {
    pub span: Span,
    pub open: Token,
    pub type_: TypeAnnotation,
    pub close: Token,
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct NonNullTypeAnnotation {
    pub span: Span,
    pub type_: TypeAnnotation,
    pub exclamation: Token,
}
<|endoftext|>


<commit_before>//! Verify conventional SSA form.

use dbg::DisplayList;
use dominator_tree::DominatorTree;
use flowgraph::ControlFlowGraph;
use ir::{Function, ExpandedProgramPoint};
use regalloc::liveness::Liveness;
use regalloc::virtregs::VirtRegs;
use timing;
use verifier::Result;

/// Verify conventional SSA form for `func`.
///
/// Conventional SSA form is represented in Cretonne with the help of virtual registers:
///
/// - Two values are said to be *PHI-related* if one is an EBB argument and the other is passed as
///   a branch argument in a location that matches the first value.
/// - PHI-related values must belong to the same virtual register.
/// - Two values in the same virtual register must not have overlapping live ranges.
///
/// Additionally, we verify this property of virtual registers:
///
/// - The values in a virtual register are topologically ordered w.r.t. dominance.
///
/// We don't verify that virtual registers are minimal. Minimal CSSA is not required.
pub fn verify_cssa(
    func: &Function,
    cfg: &ControlFlowGraph,
    domtree: &DominatorTree,
    liveness: &Liveness,
    virtregs: &VirtRegs,
) -> Result {
    let _tt = timing::verify_cssa();
    let verifier = CssaVerifier {
        func,
        cfg,
        domtree,
        virtregs,
        liveness,
    };
    verifier.check_virtregs()?;
    verifier.check_cssa()?;
    Ok(())
}

struct CssaVerifier<'a> {
    func: &'a Function,
    cfg: &'a ControlFlowGraph,
    domtree: &'a DominatorTree,
    virtregs: &'a VirtRegs,
    liveness: &'a Liveness,
}

impl<'a> CssaVerifier<'a> {
    fn check_virtregs(&self) -> Result {
        for vreg in self.virtregs.all_virtregs() {
            let values = self.virtregs.values(vreg);

            for (idx, &val) in values.iter().enumerate() {
                if !self.func.dfg.value_is_valid(val) {
                    return err!(val, "Invalid value in {}", vreg);
                }
                if !self.func.dfg.value_is_attached(val) {
                    return err!(val, "Detached value in {}", vreg);
                }
                if self.liveness.get(val).is_none() {
                    return err!(val, "Value in {} has no live range", vreg);
                };

                // Check topological ordering with the previous values in the virtual register.
                let def: ExpandedProgramPoint = self.func.dfg.value_def(val).into();
                let def_ebb = self.func.layout.pp_ebb(def);
                for &prev_val in &values[0..idx] {
                    let prev_def: ExpandedProgramPoint = self.func.dfg.value_def(prev_val).into();

                    if prev_def == def {
                        return err!(
                            val,
                            "Values {} and {} in {} = {} defined at the same program point",
                            prev_val,
                            val,
                            vreg,
                            DisplayList(values)
                        );
                    }

                    // Enforce topological ordering of defs in the virtual register.
                    if self.domtree.dominates(def, prev_def, &self.func.layout) {
                        return err!(
                            val,
                            "Value in {} = {} def dominates previous {}",
                            vreg,
                            DisplayList(values),
                            prev_val
                        );
                    }

                    // Knowing that values are in topo order, we can check for interference this
                    // way.
                    let ctx = self.liveness.context(&self.func.layout);
                    if self.liveness[prev_val].overlaps_def(def, def_ebb, ctx) {
                        return err!(
                            val,
                            "Value def in {} = {} interferes with {}",
                            vreg,
                            DisplayList(values),
                            prev_val
                        );
                    }
                }
            }
        }

        Ok(())
    }

    fn check_cssa(&self) -> Result {
        for ebb in self.func.layout.ebbs() {
            let ebb_params = self.func.dfg.ebb_params(ebb);
            for (_, pred) in self.cfg.pred_iter(ebb) {
                let pred_args = self.func.dfg.inst_variable_args(pred);
                // This should have been caught by an earlier verifier pass.
                assert_eq!(
                    ebb_params.len(),
                    pred_args.len(),
                    "Wrong arguments on branch."
                );

                for (&ebb_param, &pred_arg) in ebb_params.iter().zip(pred_args) {
                    if !self.virtregs.same_class(ebb_param, pred_arg) {
                        return err!(
                            pred,
                            "{} and {} must be in the same virtual register",
                            ebb_param,
                            pred_arg
                        );
                    }
                }
            }
        }

        Ok(())
    }
}
<commit_msg>Dampen quadratic behavior in check_cssa().<commit_after>//! Verify conventional SSA form.

use dbg::DisplayList;
use dominator_tree::{DominatorTree, DominatorTreePreorder};
use flowgraph::ControlFlowGraph;
use ir::{Function, ExpandedProgramPoint};
use regalloc::liveness::Liveness;
use regalloc::virtregs::VirtRegs;
use timing;
use verifier::Result;

/// Verify conventional SSA form for `func`.
///
/// Conventional SSA form is represented in Cretonne with the help of virtual registers:
///
/// - Two values are said to be *PHI-related* if one is an EBB argument and the other is passed as
///   a branch argument in a location that matches the first value.
/// - PHI-related values must belong to the same virtual register.
/// - Two values in the same virtual register must not have overlapping live ranges.
///
/// Additionally, we verify this property of virtual registers:
///
/// - The values in a virtual register are topologically ordered w.r.t. dominance.
///
/// We don't verify that virtual registers are minimal. Minimal CSSA is not required.
pub fn verify_cssa(
    func: &Function,
    cfg: &ControlFlowGraph,
    domtree: &DominatorTree,
    liveness: &Liveness,
    virtregs: &VirtRegs,
) -> Result {
    let _tt = timing::verify_cssa();

    let mut preorder = DominatorTreePreorder::new();
    preorder.compute(domtree, &func.layout);

    let verifier = CssaVerifier {
        func,
        cfg,
        domtree,
        virtregs,
        liveness,
        preorder,
    };
    verifier.check_virtregs()?;
    verifier.check_cssa()?;
    Ok(())
}

struct CssaVerifier<'a> {
    func: &'a Function,
    cfg: &'a ControlFlowGraph,
    domtree: &'a DominatorTree,
    virtregs: &'a VirtRegs,
    liveness: &'a Liveness,
    preorder: DominatorTreePreorder,
}

impl<'a> CssaVerifier<'a> {
    fn check_virtregs(&self) -> Result {
        for vreg in self.virtregs.all_virtregs() {
            let values = self.virtregs.values(vreg);

            for (idx, &val) in values.iter().enumerate() {
                if !self.func.dfg.value_is_valid(val) {
                    return err!(val, "Invalid value in {}", vreg);
                }
                if !self.func.dfg.value_is_attached(val) {
                    return err!(val, "Detached value in {}", vreg);
                }
                if self.liveness.get(val).is_none() {
                    return err!(val, "Value in {} has no live range", vreg);
                };

                // Check topological ordering with the previous values in the virtual register.
                let def: ExpandedProgramPoint = self.func.dfg.value_def(val).into();
                let def_ebb = self.func.layout.pp_ebb(def);
                for &prev_val in &values[0..idx] {
                    let prev_def: ExpandedProgramPoint = self.func.dfg.value_def(prev_val).into();
                    let prev_ebb = self.func.layout.pp_ebb(prev_def);

                    if prev_def == def {
                        return err!(
                            val,
                            "Values {} and {} in {} = {} defined at the same program point",
                            prev_val,
                            val,
                            vreg,
                            DisplayList(values)
                        );
                    }

                    // Enforce topological ordering of defs in the virtual register.
                    if self.preorder.dominates(def_ebb, prev_ebb) &&
                        self.domtree.dominates(def, prev_def, &self.func.layout)
                    {
                        return err!(
                            val,
                            "Value in {} = {} def dominates previous {}",
                            vreg,
                            DisplayList(values),
                            prev_val
                        );
                    }
                }

                // Knowing that values are in topo order, we can check for interference this
                // way.
                // We only have to check against the nearest dominating value.
                for &prev_val in values[0..idx].iter().rev() {
                    let prev_def: ExpandedProgramPoint = self.func.dfg.value_def(prev_val).into();
                    let prev_ebb = self.func.layout.pp_ebb(prev_def);

                    if self.preorder.dominates(prev_ebb, def_ebb) &&
                        self.domtree.dominates(prev_def, def, &self.func.layout)
                    {
                        let ctx = self.liveness.context(&self.func.layout);
                        if self.liveness[prev_val].overlaps_def(def, def_ebb, ctx) {
                            return err!(
                                val,
                                "Value def in {} = {} interferes with {}",
                                vreg,
                                DisplayList(values),
                                prev_val
                            );
                        } else {
                            break;
                        }
                    }
                }
            }
        }

        Ok(())
    }

    fn check_cssa(&self) -> Result {
        for ebb in self.func.layout.ebbs() {
            let ebb_params = self.func.dfg.ebb_params(ebb);
            for (_, pred) in self.cfg.pred_iter(ebb) {
                let pred_args = self.func.dfg.inst_variable_args(pred);
                // This should have been caught by an earlier verifier pass.
                assert_eq!(
                    ebb_params.len(),
                    pred_args.len(),
                    "Wrong arguments on branch."
                );

                for (&ebb_param, &pred_arg) in ebb_params.iter().zip(pred_args) {
                    if !self.virtregs.same_class(ebb_param, pred_arg) {
                        return err!(
                            pred,
                            "{} and {} must be in the same virtual register",
                            ebb_param,
                            pred_arg
                        );
                    }
                }
            }
        }

        Ok(())
    }
}
<|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.
//
// Regression test for the issue #50716: NLL ignores lifetimes bounds
// derived from `Sized` requirements

trait A {
    type X: ?Sized;
}

fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
where
    for<'b> &'b T: A,
    <&'static T as A>::X: Sized
{
    let _x = *s; //~ ERROR mismatched types [E0308]
}

fn main() {}
<commit_msg>Fix the regression test for issue 50716.<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.
//
// Regression test for the issue #50716: NLL ignores lifetimes bounds
// derived from `Sized` requirements

#![feature(nll)]

trait A {
    type X: ?Sized;
}

fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
where
    for<'b> &'b T: A,
    <&'static T as A>::X: Sized
{
    let _x = *s; //~ ERROR free region `'a` does not outlive free region `'static`
}

fn main() {}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

extern crate gurobi;
use gurobi::*;

macro_rules! add_var {
  ($model:expr, $name:ident : binary) => { {
    let $name = $model.add_var(stringify!($name), Binary, 0.0, 0.0, 1.0, &[], &[]).unwrap();
    $name
  } };

  ($model:expr, $name:ident : integer [$lb:expr, $ub:expr]) => { {
    let $name = $model.add_var(stringify!($name), Integer, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    $name
  } };

  ($model:expr, $name:ident : real [$lb:expr, $ub:expr]) => { {
    let $name = $model.add_var(stringify!($name), Continuous, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    $name
  } };
}

macro_rules! add_constr {
  { $model:expr, $name:ident : $lhs:tt <= $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Less, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  { $model:expr, $name:ident : $lhs:tt == $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Equal, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  { $model:expr, $name:ident : $lhs:tt >= $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Greater, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt <= $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Less, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt == $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Equal, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt >= $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Greater, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };
}

fn main() {
  let env = Env::new("mip.log").unwrap();
  let mut model = Model::new("mip", &env).unwrap();

  let x = add_var!(model, x: binary);
  let y = add_var!(model, y: binary);
  let z = add_var!(model, z: binary);
  let s = add_var!(model, s: integer[0, 2]);
  let t = add_var!(model, t: real[0, 10]);
  model.update().unwrap();

  add_constr!{model,
    c0: (&x + 2.0 * &y + 3.0 * &z) <= 4;
    c1: (&x + &y) <= 1;
  }

  model.set_objective(&x + &y + 2.0 * &z, Maximize).unwrap();

  model.update().unwrap();
  model.write("mip.lp").unwrap();
}
<commit_msg>update<commit_after>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

extern crate gurobi;
use gurobi::*;

macro_rules! def_var {
  ($model:expr, $name:ident : binary) => {
    let $name = $model.add_var(stringify!($name), Binary, 0.0, 0.0, 1.0, &[], &[]).unwrap();
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : integer [$lb:expr, $ub:expr]) => {
    let $name = $model.add_var(stringify!($name), Integer, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : real [$lb:expr, $ub:expr]) => {
    let $name = $model.add_var(stringify!($name), Continuous, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : binary; $($t:tt)*) => {
    let $name = $model.add_var(stringify!($name), Binary, 0.0, 0.0, 1.0, &[], &[]).unwrap();
    def_var!($model, $($t)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : integer [$lb:expr, $ub:expr]; $($t:tt)*) => {
    let $name = $model.add_var(stringify!($name), Integer, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    def_var!($model, $($t)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : real [$lb:expr, $ub:expr]; $($t:tt)*) => {
    let $name = $model.add_var(stringify!($name), Continuous, 0.0, ($lb).into(), ($ub).into(), &[], &[]).unwrap();
    def_var!($model, $($t)*);
    $model.update().unwrap();
  };
}

macro_rules! add_constr {
  { $model:expr, $name:ident : $lhs:tt <= $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Less, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  { $model:expr, $name:ident : $lhs:tt == $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Equal, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  { $model:expr, $name:ident : $lhs:tt >= $rhs:tt; } => {
    $model.add_constr(stringify!($name), $lhs, Greater, ($rhs).into()).unwrap();
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt <= $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Less, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt == $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Equal, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };

  ($model:expr, $name:ident : $lhs:tt >= $rhs:tt; $($s:tt)*) => {
    $model.add_constr(stringify!($name), $lhs, Greater, ($rhs).into()).unwrap();
    add_constr!($model, $($s)*);
    $model.update().unwrap();
  };
}

fn main() {
  let env = Env::new("mip.log").unwrap();
  let mut model = Model::new("mip", &env).unwrap();

  def_var!(model, x:binary; y:binary; z:binary; s:integer[0,2]; t:real[0,10]);

  model.set_objective(&x + &y + 2.0 * &z, Maximize).unwrap();

  add_constr! { model,
    c0: (&x + 2.0 * &y + 3.0 * &z) <= 4;
    c1: (&x + &y) <= 1;
  }

  model.update().unwrap();
  model.write("mip.lp").unwrap();
}
<|endoftext|>


<commit_before>// compile-flags: -C no-prepopulate-passes
// Regression test for #29988

#[repr(C)]
struct S {
    f1: i32,
    f2: i32,
    f3: i32,
}

extern {
    fn foo(s: S);
}

fn main() {
    let s = S { f1: 1, f2: 2, f3: 3 };
    unsafe {
        // CHECK: load { i64, i32 }, { i64, i32 }* {{.*}}, align 4
        // CHECK: call void @foo({ i64, i32 } {{.*}})
        foo(s);
    }
}
<commit_msg>Add some skip flags<commit_after>// Regression test for #29988

// compile-flags: -C no-prepopulate-passes
// only-x86_64
// ignore-windows

#[repr(C)]
struct S {
    f1: i32,
    f2: i32,
    f3: i32,
}

extern {
    fn foo(s: S);
}

fn main() {
    let s = S { f1: 1, f2: 2, f3: 3 };
    unsafe {
        // CHECK: load { i64, i32 }, { i64, i32 }* {{.*}}, align 4
        // CHECK: call void @foo({ i64, i32 } {{.*}})
        foo(s);
    }
}
<|endoftext|>


<commit_before>use crate::gen::builtin::Builtins;
use crate::gen::include::Includes;
use crate::syntax::Types;
use std::cell::RefCell;
use std::fmt::{self, Arguments, Write};

pub(crate) struct OutFile<'a> {
    pub header: bool,
    pub types: &'a Types<'a>,
    pub include: Includes,
    pub builtin: Builtins,
    pub front: Content,
    content: RefCell<Content>,
}

pub struct Content {
    bytes: String,
    section_pending: bool,
    blocks_pending: Vec<&'static str>,
}

impl<'a> OutFile<'a> {
    pub fn new(header: bool, types: &'a Types) -> Self {
        OutFile {
            header,
            types,
            include: Includes::new(),
            builtin: Builtins::new(),
            front: Content::new(),
            content: RefCell::new(Content::new()),
        }
    }

    // Write a blank line if the preceding section had any contents.
    pub fn next_section(&mut self) {
        let content = self.content.get_mut();
        content.section_pending = true;
    }

    pub fn begin_block(&mut self, block: &'static str) {
        let content = self.content.get_mut();
        content.blocks_pending.push(block);
    }

    pub fn end_block(&mut self, block: &'static str) {
        let content = self.content.get_mut();
        if content.blocks_pending.pop().is_none() {
            content.bytes.push_str("} // ");
            content.bytes.push_str(block);
            content.bytes.push('\n');
            content.section_pending = true;
        }
    }

    pub fn write_fmt(&self, args: Arguments) {
        let content = &mut *self.content.borrow_mut();
        Write::write_fmt(content, args).unwrap();
    }

    pub fn content(&self) -> Vec<u8> {
        let front = &self.front.bytes;
        let content = &self.content.borrow().bytes;
        let len = front.len() + content.len() + 1;
        let mut out = String::with_capacity(len);
        out.push_str(front);
        if !front.is_empty() && !content.is_empty() {
            out.push('\n');
        }
        out.push_str(content);
        if out.is_empty() {
            out.push_str("// empty\n");
        }
        out.into_bytes()
    }
}

impl Write for Content {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.write(s);
        Ok(())
    }
}

impl Content {
    pub fn write_fmt(&mut self, args: Arguments) {
        Write::write_fmt(self, args).unwrap();
    }

    fn new() -> Self {
        Content {
            bytes: String::new(),
            section_pending: false,
            blocks_pending: Vec::new(),
        }
    }

    fn write(&mut self, b: &str) {
        if !b.is_empty() {
            if !self.blocks_pending.is_empty() {
                if !self.bytes.is_empty() {
                    self.bytes.push('\n');
                }
                for block in self.blocks_pending.drain(..) {
                    self.bytes.push_str(block);
                    self.bytes.push_str(" {\n");
                }
                self.section_pending = false;
            } else if self.section_pending {
                if !self.bytes.is_empty() {
                    self.bytes.push('\n');
                }
                self.section_pending = false;
            }
            self.bytes.push_str(b);
        }
    }
}
<commit_msg>Make section and block methods available on Content<commit_after>use crate::gen::builtin::Builtins;
use crate::gen::include::Includes;
use crate::syntax::Types;
use std::cell::RefCell;
use std::fmt::{self, Arguments, Write};

pub(crate) struct OutFile<'a> {
    pub header: bool,
    pub types: &'a Types<'a>,
    pub include: Includes,
    pub builtin: Builtins,
    pub front: Content,
    content: RefCell<Content>,
}

pub struct Content {
    bytes: String,
    section_pending: bool,
    blocks_pending: Vec<&'static str>,
}

impl<'a> OutFile<'a> {
    pub fn new(header: bool, types: &'a Types) -> Self {
        OutFile {
            header,
            types,
            include: Includes::new(),
            builtin: Builtins::new(),
            front: Content::new(),
            content: RefCell::new(Content::new()),
        }
    }

    // Write a blank line if the preceding section had any contents.
    pub fn next_section(&mut self) {
        self.content.get_mut().next_section();
    }

    pub fn begin_block(&mut self, block: &'static str) {
        self.content.get_mut().begin_block(block);
    }

    pub fn end_block(&mut self, block: &'static str) {
        self.content.get_mut().end_block(block);
    }

    pub fn write_fmt(&self, args: Arguments) {
        let content = &mut *self.content.borrow_mut();
        Write::write_fmt(content, args).unwrap();
    }

    pub fn content(&self) -> Vec<u8> {
        let front = &self.front.bytes;
        let content = &self.content.borrow().bytes;
        let len = front.len() + content.len() + 1;
        let mut out = String::with_capacity(len);
        out.push_str(front);
        if !front.is_empty() && !content.is_empty() {
            out.push('\n');
        }
        out.push_str(content);
        if out.is_empty() {
            out.push_str("// empty\n");
        }
        out.into_bytes()
    }
}

impl Write for Content {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.write(s);
        Ok(())
    }
}

impl Content {
    fn new() -> Self {
        Content {
            bytes: String::new(),
            section_pending: false,
            blocks_pending: Vec::new(),
        }
    }

    pub fn next_section(&mut self) {
        self.section_pending = true;
    }

    pub fn begin_block(&mut self, block: &'static str) {
        self.blocks_pending.push(block);
    }

    pub fn end_block(&mut self, block: &'static str) {
        if self.blocks_pending.pop().is_none() {
            self.bytes.push_str("} // ");
            self.bytes.push_str(block);
            self.bytes.push('\n');
            self.section_pending = true;
        }
    }

    pub fn write_fmt(&mut self, args: Arguments) {
        Write::write_fmt(self, args).unwrap();
    }

    fn write(&mut self, b: &str) {
        if !b.is_empty() {
            if !self.blocks_pending.is_empty() {
                if !self.bytes.is_empty() {
                    self.bytes.push('\n');
                }
                for block in self.blocks_pending.drain(..) {
                    self.bytes.push_str(block);
                    self.bytes.push_str(" {\n");
                }
                self.section_pending = false;
            } else if self.section_pending {
                if !self.bytes.is_empty() {
                    self.bytes.push('\n');
                }
                self.section_pending = false;
            }
            self.bytes.push_str(b);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_attrs, rustc_private, step_trait)]

#[macro_use] extern crate rustc_data_structures;
extern crate rustc_serialize;

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<commit_msg>Adjust a rustc test to the safety changes<commit_after>#![feature(rustc_attrs, rustc_private, step_trait, min_const_unsafe_fn)]

#[macro_use] extern crate rustc_data_structures;
extern crate rustc_serialize;
use rustc_serialize::{Decodable, Decoder};

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<|endoftext|>


<commit_before>#[cfg(bogus)]
const b: bool = false;

const b: bool = true;

#[cfg(bogus)]
#[abi = "cdecl"]
native mod rustrt {
    // This symbol doesn't exist and would be a link error if this
    // module was translated
    fn bogus();
}

#[abi = "cdecl"]
native mod rustrt { }

#[cfg(bogus)]
type t = int;

type t = bool;

#[cfg(bogus)]
enum tg { foo, }

enum tg { bar, }

#[cfg(bogus)]
class r {
  new(i:int) {}
}

class r {
  new(i:int) {}
}

#[cfg(bogus)]
mod m {
    // This needs to parse but would fail in typeck. Since it's not in
    // the current config it should not be typechecked.
    fn bogus() { ret 0; }
}

mod m {

    // Submodules have slightly different code paths than the top-level
    // module, so let's make sure this jazz works here as well
    #[cfg(bogus)]
    fn f() { }

    fn f() { }
}

// Since the bogus configuration isn't defined main will just be
// parsed, but nothing further will be done with it
#[cfg(bogus)]
fn main() { fail }

fn main() {
    // Exercise some of the configured items in ways that wouldn't be possible
    // if they had the bogus definition
    assert (b);
    let x: t = true;
    let y: tg = bar;

    test_in_fn_ctxt();
}

fn test_in_fn_ctxt() {
    #[cfg(bogus)]
    fn f() { fail }
    fn f() { }
    f();

    #[cfg(bogus)]
    const i: int = 0;
    const i: int = 1;
    assert (i == 1);
}

mod test_native_items {
    #[abi = "cdecl"]
    native mod rustrt {
        #[cfg(bogus)]
        fn vec_from_buf_shared();
        fn vec_from_buf_shared();
    }
}
<commit_msg>Fix test case so the class in it is non-empty<commit_after>#[cfg(bogus)]
const b: bool = false;

const b: bool = true;

#[cfg(bogus)]
#[abi = "cdecl"]
native mod rustrt {
    // This symbol doesn't exist and would be a link error if this
    // module was translated
    fn bogus();
}

#[abi = "cdecl"]
native mod rustrt { }

#[cfg(bogus)]
type t = int;

type t = bool;

#[cfg(bogus)]
enum tg { foo, }

enum tg { bar, }

#[cfg(bogus)]
class r {
  let i: int;
  new(i:int) { self.i = i; }
}

class r {
  let i: int;
  new(i:int) { self.i = i; }
}

#[cfg(bogus)]
mod m {
    // This needs to parse but would fail in typeck. Since it's not in
    // the current config it should not be typechecked.
    fn bogus() { ret 0; }
}

mod m {

    // Submodules have slightly different code paths than the top-level
    // module, so let's make sure this jazz works here as well
    #[cfg(bogus)]
    fn f() { }

    fn f() { }
}

// Since the bogus configuration isn't defined main will just be
// parsed, but nothing further will be done with it
#[cfg(bogus)]
fn main() { fail }

fn main() {
    // Exercise some of the configured items in ways that wouldn't be possible
    // if they had the bogus definition
    assert (b);
    let x: t = true;
    let y: tg = bar;

    test_in_fn_ctxt();
}

fn test_in_fn_ctxt() {
    #[cfg(bogus)]
    fn f() { fail }
    fn f() { }
    f();

    #[cfg(bogus)]
    const i: int = 0;
    const i: int = 1;
    assert (i == 1);
}

mod test_native_items {
    #[abi = "cdecl"]
    native mod rustrt {
        #[cfg(bogus)]
        fn vec_from_buf_shared();
        fn vec_from_buf_shared();
    }
}
<|endoftext|>


<commit_before>use libc;

use std::ffi::CStr;
use std::slice;
use std::str;

use markup5ever::LocalName;

pub struct PropertyBag<'a>(Vec<(LocalName, &'a CStr)>);

pub struct PropertyBagIter<'a>(slice::Iter<'a, (LocalName, &'a CStr)>);

trait Utf8CStrToStr {
    fn to_str_utf8(&self) -> &str;
}

impl Utf8CStrToStr for CStr {
    fn to_str_utf8(&self) -> &str {
        // We can *only* do this when the CStr comes from a C string that was validated
        // as UTF-8 on the C side of things.  In our case, the C strings from libxml2 and
        // are valid UTF-8.
        unsafe { str::from_utf8_unchecked(self.to_bytes()) }
    }
}

impl<'a> PropertyBag<'a> {
    /// Creates an iterable `PropertyBag` from a C array of borrowed C strings.
    ///
    /// With libxml2's SAX parser, the caller's callback for "element start"
    /// gets passed a `xmlChar **` of attribute/value pairs.  Even indices
    /// in the array are pointers to attribute names; odd indices are
    /// pointers to attribute values.  The array terminates with a NULL
    /// element in an even index.
    ///
    /// This function is unsafe because the caller must guarantee the following:
    ///
    /// * `pairs` is a valid pointer, or NULL for an empty array
    ///
    /// * `pairs` has key/value pairs and is NULL terminated
    ///
    /// * Both keys and values are valid UTF-8, nul-terminated C strings
    ///
    /// The lifetime of the `PropertyBag` should be considered the same as the lifetime of the
    /// `pairs` array, as the property bag does not copy the strings - it directly stores pointers
    /// into that array's strings.
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut array = Vec::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    let attr = LocalName::from(key_str.to_str_utf8());
                    array.push((attr, val_str));
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(array)
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn iter(&self) -> PropertyBagIter<'_> {
        PropertyBagIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (LocalName, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(a, v)| (a.clone(), v.to_str_utf8()))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use markup5ever::local_name;
    use std::ffi::CString;
    use std::ptr;

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_iters() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        for (a, v) in pbag.iter() {
            match a {
                local_name!("rx") => {
                    assert!(v == "1");
                    had_rx = true;
                }
                local_name!("ry") => {
                    assert!(v == "2");
                    had_ry = true;
                }
                _ => unreachable!(),
            }
        }

        assert!(had_rx);
        assert!(had_ry);
    }
}
<commit_msg>PropertyBag: allow storing two kinds of data internally<commit_after>use libc;

use std::ffi::CStr;
use std::slice;
use std::str;

use markup5ever::LocalName;

enum Attribute<'a> {
    CStr(&'a CStr),
    Unterminated(&'a str),
}

pub struct PropertyBag<'a>(Vec<(LocalName, Attribute<'a>)>);

pub struct PropertyBagIter<'a>(slice::Iter<'a, (LocalName, Attribute<'a>)>);

trait Utf8CStrToStr {
    fn to_str_utf8(&self) -> &str;
}

impl Utf8CStrToStr for CStr {
    fn to_str_utf8(&self) -> &str {
        // We can *only* do this when the CStr comes from a C string that was validated
        // as UTF-8 on the C side of things.  In our case, the C strings from libxml2 and
        // are valid UTF-8.
        unsafe { str::from_utf8_unchecked(self.to_bytes()) }
    }
}

impl<'a> PropertyBag<'a> {
    /// Creates an iterable `PropertyBag` from a C array of borrowed C strings.
    ///
    /// With libxml2's SAX parser, the caller's callback for "element start"
    /// gets passed a `xmlChar **` of attribute/value pairs.  Even indices
    /// in the array are pointers to attribute names; odd indices are
    /// pointers to attribute values.  The array terminates with a NULL
    /// element in an even index.
    ///
    /// This function is unsafe because the caller must guarantee the following:
    ///
    /// * `pairs` is a valid pointer, or NULL for an empty array
    ///
    /// * `pairs` has key/value pairs and is NULL terminated
    ///
    /// * Both keys and values are valid UTF-8, nul-terminated C strings
    ///
    /// The lifetime of the `PropertyBag` should be considered the same as the lifetime of the
    /// `pairs` array, as the property bag does not copy the strings - it directly stores pointers
    /// into that array's strings.
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut array = Vec::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    let attr = LocalName::from(key_str.to_str_utf8());
                    array.push((attr, Attribute::CStr(val_str)));
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(array)
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn iter(&self) -> PropertyBagIter<'_> {
        PropertyBagIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (LocalName, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(a, v)| {
            match *v {
                Attribute::CStr(ref v) => (a.clone(), v.to_str_utf8()),
                Attribute::Unterminated(v) => (a.clone(), v),
            }
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use markup5ever::local_name;
    use std::ffi::CString;
    use std::ptr;

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_iters() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        for (a, v) in pbag.iter() {
            match a {
                local_name!("rx") => {
                    assert!(v == "1");
                    had_rx = true;
                }
                local_name!("ry") => {
                    assert!(v == "2");
                    had_ry = true;
                }
                _ => unreachable!(),
            }
        }

        assert!(had_rx);
        assert!(had_ry);
    }
}
<|endoftext|>


<commit_before>pub fn pathmatch(pattern: &str, pathstring: &str) -> bool
{
    use std::str::Chars;
    let pattern_chars = pattern.chars();
    let path_chars = pathstring.chars();
    return pathmatch_impl(pattern_chars, path_chars);

    fn pathmatch_impl(mut pattern_chars: Chars, mut path_chars: Chars) -> bool
    {
        if char_iter_equals(pattern_chars, "**/", true) {
            // How can I convert Skip<Chars> to Chars to make use of .skip(3) ?
            let mut pattern_chars_copy = pattern_chars;
            pattern_chars_copy.next();
            pattern_chars_copy.next();
            pattern_chars_copy.next();
            if pathmatch_impl(pattern_chars_copy, path_chars) {
                return true;
            }
        }
        loop {
            if char_iter_equals(pattern_chars, "/**", false) && path_chars.peekable().is_empty() {
                return true;
            }
            match pattern_chars.next() {
                None => return path_chars.next().is_none(),
                Some('?') => match path_chars.next() {
                    None | Some('/') => return false,
                    _ => (),
                },
                Some('*') => match pattern_chars.peekable().peek() {
                    Some(&'*') => {
                        pattern_chars.next();
                        loop {
                            if pathmatch_impl(pattern_chars, path_chars) {
                                return true;
                            }
                            match path_chars.next() {
                                None => break,
                                _ => (),
                            }
                        }
                    },
                    _ => loop {
                        if pathmatch_impl(pattern_chars, path_chars) {
                            return true;
                        }
                        match path_chars.next() {
                            None => break,
                            Some('/') => return false,
                            _ => (),
                        }
                    },
                },
                Some('/') => {
                    match path_chars.next() {
                        None => return false,
                        Some(sc) => if sc != '/' { return false },
                    }
                    if char_iter_equals(pattern_chars, "**/", true) && pathmatch_impl(pattern_chars, path_chars) {
                        return true;
                    }
                },
                Some(pc) => {
                    match path_chars.next() {
                        None => return false,
                        Some(sc) => if pc != sc { return false },
                    }
                }
            }
        }
    }

    fn char_iter_equals(mut char_iter: Chars, needle: &str, startswith: bool) -> bool
    {
        for needle_char in needle.chars() {
            match char_iter.next() {
                Some(x) if x == needle_char => (),
                _ => return false,
            }
        }
        return if startswith { true } else { char_iter.next().is_none() };
    }
}

#[test]
fn pathmatch_test_collapse()
{
    // `/**/` may match a single slash.
    assert!(pathmatch("foo/**/bar", "foo/bar"));
    assert!(pathmatch("foo/**/", "foo/"));
    assert!(!pathmatch("foo/**/", "foo"));
    assert!(pathmatch("/**/bar", "/bar"));
    assert!(!pathmatch("/**/bar", "bar"));
    // to prevent this behavior, you would use this
    assert!(!pathmatch("foo/*/**/bar", "foo/bar"));
    assert!(!pathmatch("foo/**/*/bar", "foo/bar"));
    assert!(pathmatch("foo/**/bar", "foo//bar"));
    assert!(pathmatch("foo/*/**/bar", "foo//bar"));
}

#[test]
fn pathmatch_test_anypath_leading()
{
    // `**/` at the beginning of pattern may match nothing.
    assert!(pathmatch("**/bar", "bar"));
    assert!(pathmatch("**/bar", "/bar"));
    assert!(!pathmatch("a**/bar", "abar"));
    assert!(!pathmatch("*/bar", "bar"));
}

#[test]
fn pathmatch_test_anypath_trailing()
{
    // `/**` at the end of pattern may match nothing.
    assert!(pathmatch("foo/**", "foo"));
    assert!(pathmatch("foo/**", "foo/"));
    assert!(!pathmatch("foo/**g", "foog"));
    assert!(!pathmatch("foo/*", "foo"));
}

#[test]
fn pathmatch_test_anypath()
{
    assert!(pathmatch("**", ""));
    assert!(pathmatch("a**", "a/b/c"));
    assert!(pathmatch("**c", "a/b/c"));
    assert!(pathmatch("a**c", "a/b/c"));
    assert!(pathmatch("a/**/c", "a/b/c"));
    assert!(pathmatch("**/c", "a/b/c"));
    assert!(!pathmatch("**/g", "e/fg"));
    assert!(pathmatch("a/**", "a/b/c"));
    assert!(!pathmatch("e/**", "ef/g"));
}

#[test]
fn pathmatch_test_pathsep()
{
    assert!(!pathmatch("a?b", "a/b"));
    assert!(!pathmatch("a*b", "a/b"));
    assert!(pathmatch("a*/b", "a/b"));
    assert!(pathmatch("a/*b", "a/b"));
}

#[test]
fn pathmatch_test_anyname()
{
    assert!(pathmatch("*", ""));
    assert!(pathmatch("*", "?"));
    assert!(pathmatch("*", "d?F"));
    assert!(pathmatch("a*", "a"));
    assert!(pathmatch("a*", "abcdef"));
    assert!(pathmatch("*f", "abcdef"));
    assert!(pathmatch("a*f", "abcdef"));
    assert!(pathmatch("*cd*", "abcdef"));
    assert!(pathmatch("a*cd*f", "abcdef"));
    assert!(pathmatch("acdf", "acdf"));
    assert!(!pathmatch("*a", "abc"));
    assert!(!pathmatch("c*", "abc"));
}

#[test]
fn pathmatch_test_anychar()
{
    assert!(pathmatch("?", "?"));
    assert!(pathmatch("?", "a"));
    assert!(pathmatch("??", "BC"));
    assert!(pathmatch("B?", "BC"));
    assert!(pathmatch("?C", "BC"));
    assert!(!pathmatch("?", ""));
    assert!(!pathmatch("D?", "BC"));
    assert!(!pathmatch("?E", "BC"));
}

#[test]
fn pathmatch_test_exact_equality()
{
    assert!(pathmatch("", ""));
    assert!(pathmatch("a", "a"));
    assert!(pathmatch("BC", "BC"));
    assert!(!pathmatch("a", ""));
    assert!(!pathmatch("", "BC"));
}

<commit_msg>use a macro to flatten and deduplicate a bit<commit_after>#![feature(macro_rules)]

macro_rules! return_if_some(
    ($arg:expr) => (
        match $arg {
            Some(val) => return val,
            None => {},
        }
    );
)

pub fn pathmatch(pattern: &str, pathstring: &str) -> bool
{
    use std::str::Chars;
    let pattern_chars = pattern.chars();
    let path_chars = pathstring.chars();
    return pathmatch_impl(pattern_chars, path_chars);

    fn pathmatch_impl(mut pattern_chars: Chars, mut path_chars: Chars) -> bool
    {
        if char_iter_equals(pattern_chars, "**/", true) {
            // How can I convert Skip<Chars> to Chars to make use of .skip(3) ?
            let mut pattern_chars_copy = pattern_chars;
            pattern_chars_copy.next();
            pattern_chars_copy.next();
            pattern_chars_copy.next();
            if pathmatch_impl(pattern_chars_copy, path_chars) {
                return true;
            }
        }
        loop {
            if char_iter_equals(pattern_chars, "/**", false) && path_chars.peekable().is_empty() {
                return true;
            }
            match pattern_chars.next() {
                None => return path_chars.next().is_none(),
                Some('?') => match path_chars.next() {
                    None | Some('/') => return false,
                    _ => (),
                },
                Some('*') => match pattern_chars.peekable().peek() {
                    Some(&'*') => {
                        pattern_chars.next();
                        return_if_some!(match_any(pattern_chars, &mut path_chars, true));
                    },
                    _ => return_if_some!(match_any(pattern_chars, &mut path_chars, false)),
                },
                Some('/') => {
                    return_if_some!(match_exact('/', path_chars.next()));
                    if char_iter_equals(pattern_chars, "**/", true) && pathmatch_impl(pattern_chars, path_chars) {
                        return true;
                    }
                },
                Some(pc) => return_if_some!(match_exact(pc, path_chars.next())),
            }
        }
    }

    fn match_any(pattern_chars: Chars, path_chars: &mut Chars, allow_pathsep: bool) -> Option<bool>
    {
        loop {
            if pathmatch_impl(pattern_chars, path_chars.clone()) {
                return Some(true);
            }
            match path_chars.next() {
                None => return None,
                Some('/') if !allow_pathsep => return Some(false),
                _ => {},
            }
        }
    }

    fn match_exact(pattern_char: char, path_char: Option<char>) -> Option<bool>
    {
        match path_char {
            None => return Some(false),
            Some(x) if x != pattern_char => return Some(false),
            _ => return None,
        }
    }

    fn char_iter_equals(mut char_iter: Chars, needle: &str, startswith: bool) -> bool
    {
        for needle_char in needle.chars() {
            match char_iter.next() {
                Some(x) if x == needle_char => (),
                _ => return false,
            }
        }
        return if startswith { true } else { char_iter.next().is_none() };
    }
}

#[test]
fn pathmatch_test_collapse()
{
    // `/**/` may match a single slash.
    assert!(pathmatch("foo/**/bar", "foo/bar"));
    assert!(pathmatch("foo/**/", "foo/"));
    assert!(!pathmatch("foo/**/", "foo"));
    assert!(pathmatch("/**/bar", "/bar"));
    assert!(!pathmatch("/**/bar", "bar"));
    // to prevent this behavior, you would use this
    assert!(!pathmatch("foo/*/**/bar", "foo/bar"));
    assert!(!pathmatch("foo/**/*/bar", "foo/bar"));
    assert!(pathmatch("foo/**/bar", "foo//bar"));
    assert!(pathmatch("foo/*/**/bar", "foo//bar"));
}

#[test]
fn pathmatch_test_anypath_leading()
{
    // `**/` at the beginning of pattern may match nothing.
    assert!(pathmatch("**/bar", "bar"));
    assert!(pathmatch("**/bar", "/bar"));
    assert!(!pathmatch("a**/bar", "abar"));
    assert!(!pathmatch("*/bar", "bar"));
}

#[test]
fn pathmatch_test_anypath_trailing()
{
    // `/**` at the end of pattern may match nothing.
    assert!(pathmatch("foo/**", "foo"));
    assert!(pathmatch("foo/**", "foo/"));
    assert!(!pathmatch("foo/**g", "foog"));
    assert!(!pathmatch("foo/*", "foo"));
}

#[test]
fn pathmatch_test_anypath()
{
    assert!(pathmatch("**", ""));
    assert!(pathmatch("a**", "a/b/c"));
    assert!(pathmatch("**c", "a/b/c"));
    assert!(pathmatch("a**c", "a/b/c"));
    assert!(pathmatch("a/**/c", "a/b/c"));
    assert!(pathmatch("**/c", "a/b/c"));
    assert!(!pathmatch("**/g", "e/fg"));
    assert!(pathmatch("a/**", "a/b/c"));
    assert!(!pathmatch("e/**", "ef/g"));
}

#[test]
fn pathmatch_test_pathsep()
{
    assert!(!pathmatch("a?b", "a/b"));
    assert!(!pathmatch("a*b", "a/b"));
    assert!(pathmatch("a*/b", "a/b"));
    assert!(pathmatch("a/*b", "a/b"));
}

#[test]
fn pathmatch_test_anyname()
{
    assert!(pathmatch("*", ""));
    assert!(pathmatch("*", "?"));
    assert!(pathmatch("*", "d?F"));
    assert!(pathmatch("a*", "a"));
    assert!(pathmatch("a*", "abcdef"));
    assert!(pathmatch("*f", "abcdef"));
    assert!(pathmatch("a*f", "abcdef"));
    assert!(pathmatch("*cd*", "abcdef"));
    assert!(pathmatch("a*cd*f", "abcdef"));
    assert!(pathmatch("acdf", "acdf"));
    assert!(!pathmatch("*a", "abc"));
    assert!(!pathmatch("c*", "abc"));
}

#[test]
fn pathmatch_test_anychar()
{
    assert!(pathmatch("?", "?"));
    assert!(pathmatch("?", "a"));
    assert!(pathmatch("??", "BC"));
    assert!(pathmatch("B?", "BC"));
    assert!(pathmatch("?C", "BC"));
    assert!(!pathmatch("?", ""));
    assert!(!pathmatch("D?", "BC"));
    assert!(!pathmatch("?E", "BC"));
}

#[test]
fn pathmatch_test_exact_equality()
{
    assert!(pathmatch("", ""));
    assert!(pathmatch("a", "a"));
    assert!(pathmatch("BC", "BC"));
    assert!(!pathmatch("a", ""));
    assert!(!pathmatch("", "BC"));
}

<|endoftext|>


<commit_before>// run-pass

#![feature(generators)]

#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]

#![recursion_limit = "256"]

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

fn punch_card() -> impl std::fmt::Debug {
    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
}

fn r#match() {
    let val = match match match match match () {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    };
    assert_eq!(val, ());
}

fn i_yield() {
    static || {
        yield yield yield yield yield yield yield yield yield;
    };
}

fn match_nested_if() {
    let val = match () {
        () if if if if true {true} else {false} {true} else {false} {true} else {false} => true,
        _ => false,
    };
    assert!(val);
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
    punch_card();
    r#match();
    i_yield();
    match_nested_if();
}
<commit_msg>Rollup merge of #78948 - slanterns:master, r=varkor<commit_after>// run-pass

#![feature(generators)]
#![feature(destructuring_assignment)]

#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]

#![recursion_limit = "256"]

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

fn punch_card() -> impl std::fmt::Debug {
    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
}

fn r#match() {
    let val = match match match match match () {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    };
    assert_eq!(val, ());
}

fn i_yield() {
    static || {
        yield yield yield yield yield yield yield yield yield;
    };
}

fn match_nested_if() {
    let val = match () {
        () if if if if true {true} else {false} {true} else {false} {true} else {false} => true,
        _ => false,
    };
    assert!(val);
}

fn monkey_barrel() {
    let val = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=();
    assert_eq!(val, ());
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
    punch_card();
    r#match();
    i_yield();
    match_nested_if();
    monkey_barrel();
}
<|endoftext|>


<commit_before>extern crate cairo;

extern crate gstreamer as gst;
use gstreamer::{ElementExtManual, QueryView};

extern crate gtk;
use gtk::{Inhibit, WidgetExt};

#[cfg(feature = "profiling-audio-draw")]
use chrono::Utc;

use std::boxed::Box;

use std::rc::Rc;
use std::cell::RefCell;

use std::sync::{Arc, Mutex};

use ::media::{Context, SamplesExtractor};

use super::WaveformBuffer;

pub struct AudioController {
    container: gtk::Container,
    pub drawingarea: gtk::DrawingArea,

    audio_sink: Option<gst::Element>,
    position_query: gst::Query,

    is_active: bool,
    position: u64,
    samples_extractor_mtx: Arc<Mutex<Box<SamplesExtractor>>>,
}

impl AudioController {
    pub fn new(builder: &gtk::Builder) -> Rc<RefCell<Self>> {
        let this = Rc::new(RefCell::new(AudioController {
            container: builder.get_object("audio-container").unwrap(),
            drawingarea: builder.get_object("audio-drawingarea").unwrap(),

            audio_sink: None,
            position_query: gst::Query::new_position(gst::Format::Time),

            is_active: false,
            position: 0,
            samples_extractor_mtx: Arc::new(Mutex::new(Box::new(WaveformBuffer::new()))),
        }));

        {
            let this_ref = this.borrow();
            let this_rc = this.clone();
            this_ref.drawingarea.connect_draw(move |drawing_area, cairo_ctx| {
                this_rc.borrow_mut()
                    .draw(drawing_area, cairo_ctx).into()
            });
        }

        this
    }

    pub fn cleanup(&mut self) {
        self.is_active = false;
        // force redraw to purge the double buffer
        self.drawingarea.queue_draw();
    }

    pub fn new_media(&mut self, context: &Context) {
        let has_audio = context.info.lock()
                .expect("Failed to lock media info while initializing audio controller")
                .audio_best
                .is_some();

        if has_audio {
            self.audio_sink = context.get_audio_sink();

            self.is_active = true;
            self.position = 0;
            self.samples_extractor_mtx = context.samples_extractor_mtx.clone();

            self.container.show();
        } else {
            self.container.hide();
        }
    }

    fn draw(&mut self, drawing_area: &gtk::DrawingArea, cr: &cairo::Context) -> Inhibit {
        if !self.is_active {
            return Inhibit(false);
        }

        #[cfg(feature = "profiling-audio-draw")]
        let before_init = Utc::now();

        let allocation = drawing_area.get_allocation();
        if allocation.width.is_negative() {
            return Inhibit(false);
        }

        let requested_duration = 2_000_000_000u64; // 2s

        self.audio_sink.as_ref()
            .expect("No audio ref in AudioController::draw")
            .query(self.position_query.get_mut().unwrap());
        let position = match self.position_query.view() {
            QueryView::Position(ref position) => position.get().1 as u64,
            _ => unreachable!(),
        };

        #[cfg(feature = "profiling-audio-draw")]
        let before_lock = Utc::now();
        #[cfg(feature = "profiling-audio-draw")]
        let mut _before_cndt = Utc::now();
        #[cfg(feature = "profiling-audio-draw")]
        let mut _before_image = Utc::now();

        let current_x = {
            let waveform_buffer_grd = &mut *self.samples_extractor_mtx.lock()
                .expect("Couldn't lock waveform buffer in audio controller draw");
            let waveform_buffer = waveform_buffer_grd
                .as_mut_any().downcast_mut::<WaveformBuffer>()
                .expect("SamplesExtratctor is not a waveform buffer in audio controller draw");

            #[cfg(feature = "profiling-audio-draw")]
            let _before_cndt = Utc::now();

            waveform_buffer.update_conditions(
                    position,
                    requested_duration,
                    allocation.width,
                    allocation.height,
                );

            #[cfg(feature = "profiling-audio-draw")]
            let _before_image = Utc::now();

            let image = match waveform_buffer.image_surface.as_ref() {
                Some(image) => image,
                None => return Inhibit(false),
            };

            cr.set_source_surface(image, -(waveform_buffer.x_offset as f64), 0f64);
            cr.paint();

            waveform_buffer.current_x
        };

        #[cfg(feature = "profiling-audio-draw")]
        let before_pos = Utc::now();

        // draw current pos
        cr.scale(1f64, allocation.height as f64);
        cr.set_source_rgb(1f64, 1f64, 0f64);
        cr.set_line_width(1f64);
        let current_pos = current_x as f64;
        cr.move_to(current_pos, 0f64);
        cr.line_to(current_pos, 1f64);
        cr.stroke();

        #[cfg(feature = "profiling-audio-draw")]
        let end = Utc::now();

        #[cfg(feature = "profiling-audio-draw")]
        println!("audio-draw,{},{},{},{},{},{}",
            before_init.time().format("%H:%M:%S%.6f"),
            before_lock.time().format("%H:%M:%S%.6f"),
            _before_cndt.time().format("%H:%M:%S%.6f"),
            _before_image.time().format("%H:%M:%S%.6f"),
            before_pos.time().format("%H:%M:%S%.6f"),
            end.time().format("%H:%M:%S%.6f"),
        );

       Inhibit(true)
    }
}
<commit_msg>AudioController: add position to draw profiling (#25)<commit_after>extern crate cairo;

extern crate gstreamer as gst;
use gstreamer::{ElementExtManual, QueryView};

extern crate gtk;
use gtk::{Inhibit, WidgetExt};

#[cfg(feature = "profiling-audio-draw")]
use chrono::Utc;

use std::boxed::Box;

use std::rc::Rc;
use std::cell::RefCell;

use std::sync::{Arc, Mutex};

use ::media::{Context, SamplesExtractor};

use super::WaveformBuffer;

pub struct AudioController {
    container: gtk::Container,
    pub drawingarea: gtk::DrawingArea,

    audio_sink: Option<gst::Element>,
    position_query: gst::Query,

    is_active: bool,
    position: u64,
    samples_extractor_mtx: Arc<Mutex<Box<SamplesExtractor>>>,
}

impl AudioController {
    pub fn new(builder: &gtk::Builder) -> Rc<RefCell<Self>> {
        let this = Rc::new(RefCell::new(AudioController {
            container: builder.get_object("audio-container").unwrap(),
            drawingarea: builder.get_object("audio-drawingarea").unwrap(),

            audio_sink: None,
            position_query: gst::Query::new_position(gst::Format::Time),

            is_active: false,
            position: 0,
            samples_extractor_mtx: Arc::new(Mutex::new(Box::new(WaveformBuffer::new()))),
        }));

        {
            let this_ref = this.borrow();
            let this_rc = this.clone();
            this_ref.drawingarea.connect_draw(move |drawing_area, cairo_ctx| {
                this_rc.borrow_mut()
                    .draw(drawing_area, cairo_ctx).into()
            });
        }

        this
    }

    pub fn cleanup(&mut self) {
        self.is_active = false;
        // force redraw to purge the double buffer
        self.drawingarea.queue_draw();
    }

    pub fn new_media(&mut self, context: &Context) {
        let has_audio = context.info.lock()
                .expect("Failed to lock media info while initializing audio controller")
                .audio_best
                .is_some();

        if has_audio {
            self.audio_sink = context.get_audio_sink();

            self.is_active = true;
            self.position = 0;
            self.samples_extractor_mtx = context.samples_extractor_mtx.clone();

            self.container.show();
        } else {
            self.container.hide();
        }
    }

    fn draw(&mut self, drawing_area: &gtk::DrawingArea, cr: &cairo::Context) -> Inhibit {
        if !self.is_active {
            return Inhibit(false);
        }

        #[cfg(feature = "profiling-audio-draw")]
        let before_init = Utc::now();

        let allocation = drawing_area.get_allocation();
        if allocation.width.is_negative() {
            return Inhibit(false);
        }

        let requested_duration = 2_000_000_000u64; // 2s

        self.audio_sink.as_ref()
            .expect("No audio ref in AudioController::draw")
            .query(self.position_query.get_mut().unwrap());
        let position = match self.position_query.view() {
            QueryView::Position(ref position) => position.get().1 as u64,
            _ => unreachable!(),
        };

        #[cfg(feature = "profiling-audio-draw")]
        let before_lock = Utc::now();
        #[cfg(feature = "profiling-audio-draw")]
        let mut _before_cndt = Utc::now();
        #[cfg(feature = "profiling-audio-draw")]
        let mut _before_image = Utc::now();

        let current_x = {
            let waveform_buffer_grd = &mut *self.samples_extractor_mtx.lock()
                .expect("Couldn't lock waveform buffer in audio controller draw");
            let waveform_buffer = waveform_buffer_grd
                .as_mut_any().downcast_mut::<WaveformBuffer>()
                .expect("SamplesExtratctor is not a waveform buffer in audio controller draw");

            #[cfg(feature = "profiling-audio-draw")]
            let _before_cndt = Utc::now();

            waveform_buffer.update_conditions(
                    position,
                    requested_duration,
                    allocation.width,
                    allocation.height,
                );

            #[cfg(feature = "profiling-audio-draw")]
            let _before_image = Utc::now();

            let image = match waveform_buffer.image_surface.as_ref() {
                Some(image) => image,
                None => return Inhibit(false),
            };

            cr.set_source_surface(image, -(waveform_buffer.x_offset as f64), 0f64);
            cr.paint();

            waveform_buffer.current_x
        };

        #[cfg(feature = "profiling-audio-draw")]
        let before_pos = Utc::now();

        // draw current pos
        cr.scale(1f64, allocation.height as f64);
        cr.set_source_rgb(1f64, 1f64, 0f64);
        cr.set_line_width(1f64);
        let current_pos = current_x as f64;
        cr.move_to(current_pos, 0f64);
        cr.line_to(current_pos, 1f64);
        cr.stroke();

        #[cfg(feature = "profiling-audio-draw")]
        let end = Utc::now();

        #[cfg(feature = "profiling-audio-draw")]
        println!("audio-draw,{},{},{},{},{},{},{}",
            before_init.time().format("%H:%M:%S%.6f"),
            before_lock.time().format("%H:%M:%S%.6f"),
            _before_cndt.time().format("%H:%M:%S%.6f"),
            _before_image.time().format("%H:%M:%S%.6f"),
            before_pos.time().format("%H:%M:%S%.6f"),
            end.time().format("%H:%M:%S%.6f"),
            position,
        );

       Inhibit(true)
    }
}
<|endoftext|>


<commit_before>use crate::cmdline::CmdOpt;

pub fn print_usage_time(cmd_opt: &CmdOpt) {
    let before_exec = cmd_opt.start_time.elapsed().as_micros();
    if cmd_opt.usage {
        println!("{}", before_exec);
    } else {
        log::debug!("usage time: {} μs", before_exec);
    }
}
<commit_msg>show usage time in milliseconds<commit_after>use crate::cmdline::CmdOpt;

pub fn print_usage_time(cmd_opt: &CmdOpt) {
    let elapsed = cmd_opt.start_time.elapsed().as_millis();
    if cmd_opt.usage {
        println!("{}", elapsed);
    } else {
        log::debug!("usage time: {} ms", elapsed);
    }
}
<|endoftext|>