<commit_before>// Dynamic arenas.

// Arenas are used to quickly allocate objects that share a
// lifetime. The arena uses ~[u8] vectors as a backing store to
// allocate objects from. For each allocated object, the arena stores
// a pointer to the type descriptor followed by the
// object. (Potentially with alignment padding after each of them.)
// When the arena is destroyed, it iterates through all of its chunks,
// and uses the tydesc information to trace through the objects,
// calling the destructors on them.
// One subtle point that needs to be addressed is how to handle
// failures while running the user provided initializer function. It
// is important to not run the destructor on uninitalized objects, but
// how to detect them is somewhat subtle. Since alloc() can be invoked
// recursively, it is not sufficient to simply exclude the most recent
// object. To solve this without requiring extra space, we use the low
// order bit of the tydesc pointer to encode whether the object it
// describes has been fully initialized.

// As an optimization, objects with destructors are stored in
// different chunks than objects without destructors. This reduces
// overhead when initializing plain-old-data and means we don't need
// to waste time running the destructors of POD.

export arena, arena_with_size;

import list;
import list::{list, cons, nil};
import unsafe::reinterpret_cast;
import sys::TypeDesc;
import libc::size_t;

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn move_val_init<T>(&dst: T, -src: T);
    fn needs_drop<T>() -> bool;
}
extern mod rustrt {
    #[rust_stack]
    fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
}
// This probably belongs somewhere else. Needs to be kept in sync with
// changes to glue...
const tydesc_drop_glue_index: size_t = 3 as size_t;

// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
// will always stay at 0.
type chunk = {data: ~[u8], mut fill: uint, is_pod: bool};

struct arena {
    // The head is seperated out from the list as a unbenchmarked
    // microoptimization, to avoid needing to case on the list to
    // access the head.
    priv mut head: @chunk;
    priv mut pod_head: @chunk;
    priv mut chunks: @list<@chunk>;
    drop {
        unsafe {
            destroy_chunk(self.head);
            for list::each(self.chunks) |chunk| {
                if !chunk.is_pod { destroy_chunk(chunk); }
            }
        }
    }
}

fn chunk(size: uint, is_pod: bool) -> @chunk {
    let mut v = ~[];
    vec::reserve(v, size);
    @{ data: v, mut fill: 0u, is_pod: is_pod }
}

fn arena_with_size(initial_size: uint) -> arena {
    return arena {mut head: chunk(initial_size, false),
                  mut pod_head: chunk(initial_size, true),
                  mut chunks: @nil};
}

fn arena() -> arena {
    arena_with_size(32u)
}

#[inline(always)]
fn round_up_to(base: uint, align: uint) -> uint {
    (base + (align - 1)) & !(align - 1)
}

// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: @chunk) {
    let mut idx = 0;
    let buf = vec::unsafe::to_ptr(chunk.data);
    let fill = chunk.fill;

    while idx < fill {
        let tydesc_data: *uint = reinterpret_cast(ptr::offset(buf, idx));
        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
        let size = (*tydesc).size, align = (*tydesc).align;

        let after_tydesc = idx + sys::size_of::<*TypeDesc>();

        let start = round_up_to(after_tydesc, align);

        //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
        //       start, size, align, is_done);
        if is_done {
            rustrt::rust_call_tydesc_glue(
                ptr::offset(buf, start), tydesc, tydesc_drop_glue_index);
        }

        // Find where the next tydesc lives
        idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
    }
}

// We encode whether the object a tydesc describes has been
// initialized in the arena in the low bit of the tydesc pointer. This
// is necessary in order to properly do cleanup if a failure occurs
// during an initializer.
#[inline(always)]
unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
    let p_bits: uint = reinterpret_cast(p);
    p_bits | (is_done as uint)
}
#[inline(always)]
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
    (reinterpret_cast(p & !1), p & 1 == 1)
}

// The duplication between the POD and non-POD functions is annoying.
impl &arena {
    // Functions for the POD part of the arena
    fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
        // Allocate a new chunk.
        let chunk_size = vec::capacity(self.pod_head.data);
        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
        self.chunks = @cons(self.pod_head, self.chunks);
        self.pod_head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);

        return self.alloc_pod_inner(n_bytes, align);
    }

    #[inline(always)]
    fn alloc_pod_inner(n_bytes: uint, align: uint) -> *u8 {
        let head = self.pod_head;

        let start = round_up_to(head.fill, align);
        let end = start + n_bytes;
        if end > vec::capacity(head.data) {
            return self.alloc_pod_grow(n_bytes, align);
        }
        head.fill = end;

        //debug!("idx = %u, size = %u, align = %u, fill = %u",
        //       start, n_bytes, align, head.fill);

        unsafe {
            ptr::offset(vec::unsafe::to_ptr(head.data), start)
        }
    }

    #[inline(always)]
    fn alloc_pod<T>(op: fn() -> T) -> &self/T {
        unsafe {
            let tydesc = sys::get_type_desc::<T>();
            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
            let ptr: *mut T = reinterpret_cast(ptr);
            rusti::move_val_init(*ptr, op());
            return reinterpret_cast(ptr);
        }
    }

    // Functions for the non-POD part of the arena
    fn alloc_nonpod_grow(n_bytes: uint, align: uint) -> (*u8, *u8) {
        // Allocate a new chunk.
        let chunk_size = vec::capacity(self.head.data);
        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
        self.chunks = @cons(self.head, self.chunks);
        self.head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);

        return self.alloc_nonpod_inner(n_bytes, align);
    }

    #[inline(always)]
    fn alloc_nonpod_inner(n_bytes: uint, align: uint) -> (*u8, *u8) {
        let head = self.head;

        let tydesc_start = head.fill;
        let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
        let start = round_up_to(after_tydesc, align);
        let end = start + n_bytes;
        if end > vec::capacity(head.data) {
            return self.alloc_nonpod_grow(n_bytes, align);
        }
        head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());

        //debug!("idx = %u, size = %u, align = %u, fill = %u",
        //       start, n_bytes, align, head.fill);

        unsafe {
            let buf = vec::unsafe::to_ptr(head.data);
            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
        }
    }

    #[inline(always)]
    fn alloc_nonpod<T>(op: fn() -> T) -> &self/T {
        unsafe {
            let tydesc = sys::get_type_desc::<T>();
            let (ty_ptr, ptr) =
                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
            let ty_ptr: *mut uint = reinterpret_cast(ty_ptr);
            let ptr: *mut T = reinterpret_cast(ptr);
            // Write in our tydesc along with a bit indicating that it
            // has *not* been initialized yet.
            *ty_ptr = reinterpret_cast(tydesc);
            // Actually initialize it
            rusti::move_val_init(*ptr, op());
            // Now that we are done, update the tydesc to indicate that
            // the object is there.
            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);

            return reinterpret_cast(ptr);
        }
    }

    // The external interface
    #[inline(always)]
    fn alloc<T>(op: fn() -> T) -> &self/T {
        if !rusti::needs_drop::<T>() {
            self.alloc_pod(op)
        } else { self.alloc_nonpod(op) }
    }
}

#[test]
fn test_arena_destructors() {
    let arena = arena::arena();
    for uint::range(0, 10) |i| {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        do arena.alloc { @i };
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        do arena.alloc { [0u8, 1u8, 2u8]/3 };
    }
}

#[test]
#[should_fail]
fn test_arena_destructors_fail() {
    let arena = arena::arena();
    // Put some stuff in the arena.
    for uint::range(0, 10) |i| {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        do arena.alloc { @i };
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        do arena.alloc { [0u8, 1u8, 2u8]/3 };
    }
    // Now, fail while allocating
    do arena.alloc::<@int> {
        // First, recursively allocate something else; that needs to
        // get freed too.
        do arena.alloc { @20 };
        // Now fail.
        fail;
    };
}
<commit_msg>Remove a level of indirection from std::arena.<commit_after>// Dynamic arenas.

// Arenas are used to quickly allocate objects that share a
// lifetime. The arena uses ~[u8] vectors as a backing store to
// allocate objects from. For each allocated object, the arena stores
// a pointer to the type descriptor followed by the
// object. (Potentially with alignment padding after each of them.)
// When the arena is destroyed, it iterates through all of its chunks,
// and uses the tydesc information to trace through the objects,
// calling the destructors on them.
// One subtle point that needs to be addressed is how to handle
// failures while running the user provided initializer function. It
// is important to not run the destructor on uninitalized objects, but
// how to detect them is somewhat subtle. Since alloc() can be invoked
// recursively, it is not sufficient to simply exclude the most recent
// object. To solve this without requiring extra space, we use the low
// order bit of the tydesc pointer to encode whether the object it
// describes has been fully initialized.

// As an optimization, objects with destructors are stored in
// different chunks than objects without destructors. This reduces
// overhead when initializing plain-old-data and means we don't need
// to waste time running the destructors of POD.

export arena, arena_with_size;

import list;
import list::{list, cons, nil};
import unsafe::reinterpret_cast;
import sys::TypeDesc;
import libc::size_t;

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn move_val_init<T>(&dst: T, -src: T);
    fn needs_drop<T>() -> bool;
}
extern mod rustrt {
    #[rust_stack]
    fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
}
// This probably belongs somewhere else. Needs to be kept in sync with
// changes to glue...
const tydesc_drop_glue_index: size_t = 3 as size_t;

// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
// will always stay at 0.
type chunk = {data: @[u8], mut fill: uint, is_pod: bool};

struct arena {
    // The head is seperated out from the list as a unbenchmarked
    // microoptimization, to avoid needing to case on the list to
    // access the head.
    priv mut head: chunk;
    priv mut pod_head: chunk;
    priv mut chunks: @list<chunk>;
    drop {
        unsafe {
            destroy_chunk(self.head);
            for list::each(self.chunks) |chunk| {
                if !chunk.is_pod { destroy_chunk(chunk); }
            }
        }
    }
}

fn chunk(size: uint, is_pod: bool) -> chunk {
    let mut v = @[];
    unsafe { at_vec::unsafe::reserve(v, size); }
    { data: v, mut fill: 0u, is_pod: is_pod }
}

fn arena_with_size(initial_size: uint) -> arena {
    return arena {mut head: chunk(initial_size, false),
                  mut pod_head: chunk(initial_size, true),
                  mut chunks: @nil};
}

fn arena() -> arena {
    arena_with_size(32u)
}

#[inline(always)]
fn round_up_to(base: uint, align: uint) -> uint {
    (base + (align - 1)) & !(align - 1)
}

// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: chunk) {
    let mut idx = 0;
    let buf = vec::unsafe::to_ptr_slice(chunk.data);
    let fill = chunk.fill;

    while idx < fill {
        let tydesc_data: *uint = reinterpret_cast(ptr::offset(buf, idx));
        let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
        let size = (*tydesc).size, align = (*tydesc).align;

        let after_tydesc = idx + sys::size_of::<*TypeDesc>();

        let start = round_up_to(after_tydesc, align);

        //debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
        //       start, size, align, is_done);
        if is_done {
            rustrt::rust_call_tydesc_glue(
                ptr::offset(buf, start), tydesc, tydesc_drop_glue_index);
        }

        // Find where the next tydesc lives
        idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
    }
}

// We encode whether the object a tydesc describes has been
// initialized in the arena in the low bit of the tydesc pointer. This
// is necessary in order to properly do cleanup if a failure occurs
// during an initializer.
#[inline(always)]
unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
    let p_bits: uint = reinterpret_cast(p);
    p_bits | (is_done as uint)
}
#[inline(always)]
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
    (reinterpret_cast(p & !1), p & 1 == 1)
}

// The duplication between the POD and non-POD functions is annoying.
impl &arena {
    // Functions for the POD part of the arena
    fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.pod_head.data);
        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
        self.chunks = @cons(copy self.pod_head, self.chunks);
        self.pod_head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);

        return self.alloc_pod_inner(n_bytes, align);
    }

    #[inline(always)]
    fn alloc_pod_inner(n_bytes: uint, align: uint) -> *u8 {
        let head = &mut self.pod_head;

        let start = round_up_to(head.fill, align);
        let end = start + n_bytes;
        if end > at_vec::capacity(head.data) {
            return self.alloc_pod_grow(n_bytes, align);
        }
        head.fill = end;

        //debug!("idx = %u, size = %u, align = %u, fill = %u",
        //       start, n_bytes, align, head.fill);

        unsafe {
            ptr::offset(vec::unsafe::to_ptr_slice(head.data), start)
        }
    }

    #[inline(always)]
    fn alloc_pod<T>(op: fn() -> T) -> &self/T {
        unsafe {
            let tydesc = sys::get_type_desc::<T>();
            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
            let ptr: *mut T = reinterpret_cast(ptr);
            rusti::move_val_init(*ptr, op());
            return reinterpret_cast(ptr);
        }
    }

    // Functions for the non-POD part of the arena
    fn alloc_nonpod_grow(n_bytes: uint, align: uint) -> (*u8, *u8) {
        // Allocate a new chunk.
        let chunk_size = at_vec::capacity(self.head.data);
        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
        self.chunks = @cons(copy self.head, self.chunks);
        self.head =
            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);

        return self.alloc_nonpod_inner(n_bytes, align);
    }

    #[inline(always)]
    fn alloc_nonpod_inner(n_bytes: uint, align: uint) -> (*u8, *u8) {
        let head = &mut self.head;

        let tydesc_start = head.fill;
        let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
        let start = round_up_to(after_tydesc, align);
        let end = start + n_bytes;
        if end > at_vec::capacity(head.data) {
            return self.alloc_nonpod_grow(n_bytes, align);
        }
        head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());

        //debug!("idx = %u, size = %u, align = %u, fill = %u",
        //       start, n_bytes, align, head.fill);

        unsafe {
            let buf = vec::unsafe::to_ptr_slice(head.data);
            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
        }
    }

    #[inline(always)]
    fn alloc_nonpod<T>(op: fn() -> T) -> &self/T {
        unsafe {
            let tydesc = sys::get_type_desc::<T>();
            let (ty_ptr, ptr) =
                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
            let ty_ptr: *mut uint = reinterpret_cast(ty_ptr);
            let ptr: *mut T = reinterpret_cast(ptr);
            // Write in our tydesc along with a bit indicating that it
            // has *not* been initialized yet.
            *ty_ptr = reinterpret_cast(tydesc);
            // Actually initialize it
            rusti::move_val_init(*ptr, op());
            // Now that we are done, update the tydesc to indicate that
            // the object is there.
            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);

            return reinterpret_cast(ptr);
        }
    }

    // The external interface
    #[inline(always)]
    fn alloc<T>(op: fn() -> T) -> &self/T {
        if !rusti::needs_drop::<T>() {
            self.alloc_pod(op)
        } else { self.alloc_nonpod(op) }
    }
}

#[test]
fn test_arena_destructors() {
    let arena = arena::arena();
    for uint::range(0, 10) |i| {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        do arena.alloc { @i };
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        do arena.alloc { [0u8, 1u8, 2u8]/3 };
    }
}

#[test]
#[should_fail]
fn test_arena_destructors_fail() {
    let arena = arena::arena();
    // Put some stuff in the arena.
    for uint::range(0, 10) |i| {
        // Arena allocate something with drop glue to make sure it
        // doesn't leak.
        do arena.alloc { @i };
        // Allocate something with funny size and alignment, to keep
        // things interesting.
        do arena.alloc { [0u8, 1u8, 2u8]/3 };
    }
    // Now, fail while allocating
    do arena.alloc::<@int> {
        // First, recursively allocate something else; that needs to
        // get freed too.
        do arena.alloc { @20 };
        // Now fail.
        fail;
    };
}
<|endoftext|>


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

// This test case tests the incremental compilation hash (ICH) implementation
// for struct definitions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// We also test the ICH for struct definitions exported in metadata. Same as
// above, we want to make sure that the change between rev1 and rev2 also
// results in a change of the ICH for the struct's metadata, and that it stays
// the same between rev2 and rev3.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![crate_type="rlib"]

// Change enum visibility -----------------------------------------------------
#[cfg(cfail1)]
enum EnumVisibility { A }

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail3")]
pub enum EnumVisibility { A }

// Change name of a c-style variant -------------------------------------------
#[cfg(cfail1)]
enum EnumChangeNameCStyleVariant {
    Variant1,
    Variant2,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeNameCStyleVariant {
    Variant1,
    Variant2Changed,
}

// Change name of a tuple-style variant ---------------------------------------
#[cfg(cfail1)]
enum EnumChangeNameTupleStyleVariant {
    Variant1,
    Variant2(u32, f32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeNameTupleStyleVariant {
    Variant1,
    Variant2Changed(u32, f32),
}

// Change name of a struct-style variant --------------------------------------
#[cfg(cfail1)]
enum EnumChangeNameStructStyleVariant {
    Variant1,
    Variant2 { a: u32, b: f32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeNameStructStyleVariant {
    Variant1,
    Variant2Changed { a: u32, b: f32 },
}

// Change the value of a c-style variant --------------------------------------
#[cfg(cfail1)]
enum EnumChangeValueCStyleVariant0 {
    Variant1,
    Variant2 = 11,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeValueCStyleVariant0 {
    Variant1,
    Variant2 = 22,
}

#[cfg(cfail1)]
enum EnumChangeValueCStyleVariant1 {
    Variant1,
    Variant2,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeValueCStyleVariant1 {
    Variant1,
    Variant2 = 11,
}

// Add a c-style variant ------------------------------------------------------
#[cfg(cfail1)]
enum EnumAddCStyleVariant {
    Variant1,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumAddCStyleVariant {
    Variant1,
    Variant2,
}

// Remove a c-style variant ---------------------------------------------------
#[cfg(cfail1)]
enum EnumRemoveCStyleVariant {
    Variant1,
    Variant2,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumRemoveCStyleVariant {
    Variant1,
}

// Add a tuple-style variant --------------------------------------------------
#[cfg(cfail1)]
enum EnumAddTupleStyleVariant {
    Variant1,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumAddTupleStyleVariant {
    Variant1,
    Variant2(u32, f32),
}

// Remove a tuple-style variant -----------------------------------------------
#[cfg(cfail1)]
enum EnumRemoveTupleStyleVariant {
    Variant1,
    Variant2(u32, f32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumRemoveTupleStyleVariant {
    Variant1,
}

// Add a struct-style variant -------------------------------------------------
#[cfg(cfail1)]
enum EnumAddStructStyleVariant {
    Variant1,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumAddStructStyleVariant {
    Variant1,
    Variant2 { a: u32, b: f32 },
}

// Remove a struct-style variant ----------------------------------------------
#[cfg(cfail1)]
enum EnumRemoveStructStyleVariant {
    Variant1,
    Variant2 { a: u32, b: f32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumRemoveStructStyleVariant {
    Variant1,
}

// Change the type of a field in a tuple-style variant ------------------------
#[cfg(cfail1)]
enum EnumChangeFieldTypeTupleStyleVariant {
    Variant1(u32, u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeFieldTypeTupleStyleVariant {
    Variant1(u32, u64),
}

// Change the type of a field in a struct-style variant -----------------------
#[cfg(cfail1)]
enum EnumChangeFieldTypeStructStyleVariant {
    Variant1,
    Variant2 { a: u32, b: u32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeFieldTypeStructStyleVariant {
    Variant1,
    Variant2 { a: u32, b: u64 },
}

// Change the name of a field in a struct-style variant -----------------------
#[cfg(cfail1)]
enum EnumChangeFieldNameStructStyleVariant {
    Variant1 { a: u32, b: u32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeFieldNameStructStyleVariant {
    Variant1 { a: u32, c: u32 },
}

// Change order of fields in a tuple-style variant ----------------------------
#[cfg(cfail1)]
enum EnumChangeOrderTupleStyleVariant {
    Variant1(u32, u64),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeOrderTupleStyleVariant {
    Variant1(u64, u32),
}

// Change order of fields in a struct-style variant ---------------------------
#[cfg(cfail1)]
enum EnumChangeFieldOrderStructStyleVariant {
    Variant1 { a: u32, b: f32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumChangeFieldOrderStructStyleVariant {
    Variant1 { b: u32, a: u32 },
}

// Add a field to a tuple-style variant ---------------------------------------
#[cfg(cfail1)]
enum EnumAddFieldTupleStyleVariant {
    Variant1(u32, u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumAddFieldTupleStyleVariant {
    Variant1(u32, u32, u32),
}

// Add a field to a struct-style variant --------------------------------------
#[cfg(cfail1)]
enum EnumAddFieldStructStyleVariant {
    Variant1 { a: u32, b: u32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumAddFieldStructStyleVariant {
    Variant1 { a: u32, b: u32, c: u32 },
}

// Add #[must_use] to the enum ------------------------------------------------
#[cfg(cfail1)]
enum EnumAddMustUse {
    Variant1,
    Variant2,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[must_use]
enum EnumAddMustUse {
    Variant1,
    Variant2,
}

// Add #[repr(C)] to the enum -------------------------------------------------
#[cfg(cfail1)]
enum EnumAddReprC {
    Variant1,
    Variant2,
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddReprC {
    Variant1,
    Variant2,
}

// Change the name of a type parameter ----------------------------------------
#[cfg(cfail1)]
enum EnumChangeNameOfTypeParameter<S> {
    Variant1(S),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumChangeNameOfTypeParameter<T> {
    Variant1(T),
}

// Add a type parameter ------------------------------------------------------
#[cfg(cfail1)]
enum EnumAddTypeParameter<S> {
    Variant1(S),
    Variant2(S),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddTypeParameter<S, T> {
    Variant1(S),
    Variant2(T),
}

// Change the name of a lifetime parameter ------------------------------------
#[cfg(cfail1)]
enum EnumChangeNameOfLifetimeParameter<'a> {
    Variant1(&'a u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumChangeNameOfLifetimeParameter<'b> {
    Variant1(&'b u32),
}

// Add a lifetime parameter ---------------------------------------------------
#[cfg(cfail1)]
enum EnumAddLifetimeParameter<'a> {
    Variant1(&'a u32),
    Variant2(&'a u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddLifetimeParameter<'a, 'b> {
    Variant1(&'a u32),
    Variant2(&'b u32),
}

// Add a lifetime bound to a lifetime parameter -------------------------------
#[cfg(cfail1)]
enum EnumAddLifetimeParameterBound<'a, 'b> {
    Variant1(&'a u32),
    Variant2(&'b u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddLifetimeParameterBound<'a, 'b: 'a> {
    Variant1(&'a u32),
    Variant2(&'b u32),
}

// Add a lifetime bound to a type parameter -----------------------------------
#[cfg(cfail1)]
enum EnumAddLifetimeBoundToParameter<'a, T> {
    Variant1(T),
    Variant2(&'a u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddLifetimeBoundToParameter<'a, T: 'a> {
    Variant1(T),
    Variant2(&'a u32),
}

// Add a trait bound to a type parameter --------------------------------------
#[cfg(cfail1)]
enum EnumAddTraitBound<S> {
    Variant1(S),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddTraitBound<T: Sync> {
    Variant1(T),
}

// Add a lifetime bound to a lifetime parameter in where clause ---------------
#[cfg(cfail1)]
enum EnumAddLifetimeParameterBoundWhere<'a, 'b> {
    Variant1(&'a u32),
    Variant2(&'b u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddLifetimeParameterBoundWhere<'a, 'b> where 'b: 'a {
    Variant1(&'a u32),
    Variant2(&'b u32),
}

// Add a lifetime bound to a type parameter in where clause -------------------
#[cfg(cfail1)]
enum EnumAddLifetimeBoundToParameterWhere<'a, T> {
    Variant1(T),
    Variant2(&'a u32),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddLifetimeBoundToParameterWhere<'a, T> where T: 'a {
    Variant1(T),
    Variant2(&'a u32),
}

// Add a trait bound to a type parameter in where clause ----------------------
#[cfg(cfail1)]
enum EnumAddTraitBoundWhere<S> {
    Variant1(S),
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[repr(C)]
enum EnumAddTraitBoundWhere<T> where T: Sync {
    Variant1(T),
}

// In an enum with two variants, swap usage of type parameters ----------------
#[cfg(cfail1)]
enum EnumSwapUsageTypeParameters<A, B> {
    Variant1 { a: A },
    Variant2 { a: B },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumSwapUsageTypeParameters<A, B> {
    Variant1 { a: B },
    Variant2 { a: A },
}

// In an enum with two variants, swap usage of lifetime parameters ------------
#[cfg(cfail1)]
enum EnumSwapUsageLifetimeParameters<'a, 'b> {
    Variant1 { a: &'a u32 },
    Variant2 { b: &'b u32 },
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
enum EnumSwapUsageLifetimeParameters<'a, 'b> {
    Variant1 { a: &'b u32 },
    Variant2 { b: &'a u32 },
}

struct ReferencedType1;
struct ReferencedType2;

// Change field type in tuple-style variant indirectly by modifying a use statement
mod change_field_type_indirectly_tuple_style {
    #[cfg(cfail1)]
    use super::ReferencedType1 as FieldType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as FieldType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    enum TupleStyle {
        Variant1(FieldType)
    }
}

// Change field type in record-style variant indirectly by modifying a use statement
mod change_field_type_indirectly_struct_style {
    #[cfg(cfail1)]
    use super::ReferencedType1 as FieldType;
    #[cfg(not(cfail1))]
    use super::ReferencedType2 as FieldType;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    enum StructStyle {
        Variant1 { a: FieldType }
    }
}

trait ReferencedTrait1 {}
trait ReferencedTrait2 {}

// Change trait bound of type parameter indirectly by modifying a use statement
mod change_trait_bound_indirectly {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    enum Enum<T: Trait> {
        Variant1(T)
    }
}

// Change trait bound of type parameter in where clause indirectly by modifying a use statement
mod change_trait_bound_indirectly_where {
    #[cfg(cfail1)]
    use super::ReferencedTrait1 as Trait;
    #[cfg(not(cfail1))]
    use super::ReferencedTrait2 as Trait;

    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    enum Enum<T> where T: Trait {
        Variant1(T)
    }
}

<|endoftext|>


<commit_before><commit_msg>Add test.<commit_after>// Copyright 2017 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.

// ignore-pretty pretty-printing is unhygienic

#![feature(decl_macro)]
#![allow(unused)]

mod foo {
    pub macro m($s:tt, $i:tt) {
        $s.$i
    }
}

mod bar {
    struct S(i32);
    fn f() {
        let s = S(0);
        ::foo::m!(s, 0);
    }
}

fn main() {}
<|endoftext|>


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

// Check that object-safe methods are identified as such.  Also
// acts as a regression test for #18490

trait Tr {
    // Static methods are always safe regardless of other rules
    fn new() -> Self;
}

struct St;

impl Tr for St {
    fn new() -> St { St }
}

fn main() {
    &St as &Tr;
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #49125 - NovemberZulu:master, r=alexcrichton<commit_after><|endoftext|>


<commit_before><commit_msg>(fix) Ensure we actually write a full response.<commit_after><|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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}
use foo::MyTrait::do_something;
```

It's illegal to directly import methods belonging to a trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0403: r##"
Some type parameters have the same name. Example of erroneous code:

```
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
                            //        parameter in this type parameter list
```

Please verify that none of the type parameterss are misspelled, and rename any
clashing parameters. Example:

```
fn foo<T, Y>(s: T, u: Y) {} // ok!
```
"##,

E0404: r##"
You tried to implement something which was not a trait on an object. Example of
erroneous code:

```
struct Foo;
struct Bar;

impl Foo for Bar {} // error: `Foo` is not a trait
```

Please verify that you didn't misspell the trait's name or otherwise use the
wrong identifier. Example:

```
trait Foo {
    // some functions
}
struct Bar;

impl Foo for Bar { // ok!
    // functions implementation
}
```
"##,

E0405: r##"
An unknown trait was implemented. Example of erroneous code:

```
struct Foo;

impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
```

Please verify that the name of the trait wasn't misspelled and ensure that it
was imported. Example:

```
// solution 1:
use some_file::SomeTrait;

// solution 2:
trait SomeTrait {
    // some functions
}

struct Foo;

impl SomeTrait for Foo { // ok!
    // implements functions
}
```
"##,

E0407: r##"
A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // error: method `b` is not a member of trait `Foo`
}
```

Please verify you didn't misspell the method name and you used the correct
trait. First example:

```
trait Foo {
    fn a();
    fn b();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // ok!
}
```

Second example:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
}

impl Bar {
    fn b() {}
}
```
"##,

E0428: r##"
A type or module has been defined more than once. Example of erroneous
code:

```
struct Bar;
struct Bar; // error: duplicate definition of value `Bar`
```

Please verify you didn't misspell the type/module's name or remove/rename the
duplicated one. Example:

```
struct Bar;
struct Bar2; // ok!
```
"##,

E0433: r##"
Invalid import. Example of erroneous code:

```
use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist`
```

Please verify you didn't misspell the import's name.
"##,

E0437: r##"
Trait impls can only implement associated types that are members of the trait in
question. This error indicates that you attempted to implement an associated
type whose name does not match the name of any associated type in the trait.

Here is an example that demonstrates the error:

```
trait Foo {}

impl Foo for i32 {
    type Bar = bool;
}
```

The solution to this problem is to remove the extraneous associated type:

```
trait Foo {}

impl Foo for i32 {}
```
"##,

E0438: r##"
Trait impls can only implement associated constants that are members of the
trait in question. This error indicates that you attempted to implement an
associated constant whose name does not match the name of any associated
constant in the trait.

Here is an example that demonstrates the error:

```
#![feature(associated_consts)]

trait Foo {}

impl Foo for i32 {
    const BAR: bool = true;
}
```

The solution to this problem is to remove the extraneous associated constant:

```
trait Foo {}

impl Foo for i32 {}
```
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0406, // undeclared associated type
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0417, // static variables cannot be referenced in a pattern, use a
           // `const` instead
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0424, // `self` is not available in a static method.
    E0425, // unresolved name
    E0426, // use of undeclared label
    E0427, // cannot use `ref` binding mode with ...
    E0429, // `self` imports are only allowed within a { } list
    E0430, // `self` import can only appear once in the list
    E0431, // `self` import can only appear in an import list with a non-empty
           // prefix
    E0432, // unresolved import
    E0434, // can't capture dynamic environment in a fn item
    E0435, // attempt to use a non-constant value in a constant
}
<commit_msg>Auto merge of #27230 - GuillaumeGomez:patch-1, r=brson<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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:

```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:

```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0251: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0252: r##"
Two items of the same name cannot be imported without rebinding one of the
items under a new local name.

An example of this error:

```
use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead

fn main() {}

mod foo {
    pub struct baz;
}

mod bar {
    pub mod baz {}
}
```
"##,

E0253: r##"
Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error:

```
mod foo {
    pub trait MyTrait {
        fn do_something();
    }
}
use foo::MyTrait::do_something;
```

It's illegal to directly import methods belonging to a trait or concrete type.
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.

An example of this error:

```
use bar::foo; // error, do `use bar::foo as baz` instead

fn foo() {}

mod bar {
     pub fn foo() {}
}

fn main() {}
```
"##,

E0256: r##"
You can't import a type or module when the name of the item being imported is
the same as another type or submodule defined in the module.

An example of this error:

```
use foo::Bar; // error

type Bar = u32;

mod foo {
    pub mod Bar { }
}

fn main() {}
```
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:

```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:

```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,

```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##,

E0364: r##"
Private items cannot be publicly re-exported.  This error indicates that
you attempted to `pub use` a type or value that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    const X: u32 = 1;
}
pub use foo::X;
```

The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo::X;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0365: r##"
Private modules cannot be publicly re-exported.  This error indicates
that you attempted to `pub use` a module that was not itself public.

Here is an example that demonstrates the error:

```
mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;

```
The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`:

```
pub mod foo {
    pub const X: u32 = 1;
}
pub use foo as foo2;
```

See the 'Use Declarations' section of the reference for more information
on this topic:

http://doc.rust-lang.org/reference.html#use-declarations
"##,

E0403: r##"
Some type parameters have the same name. Example of erroneous code:

```
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
                            //        parameter in this type parameter list
```

Please verify that none of the type parameterss are misspelled, and rename any
clashing parameters. Example:

```
fn foo<T, Y>(s: T, u: Y) {} // ok!
```
"##,

E0404: r##"
You tried to implement something which was not a trait on an object. Example of
erroneous code:

```
struct Foo;
struct Bar;

impl Foo for Bar {} // error: `Foo` is not a trait
```

Please verify that you didn't misspell the trait's name or otherwise use the
wrong identifier. Example:

```
trait Foo {
    // some functions
}
struct Bar;

impl Foo for Bar { // ok!
    // functions implementation
}
```
"##,

E0405: r##"
An unknown trait was implemented. Example of erroneous code:

```
struct Foo;

impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
```

Please verify that the name of the trait wasn't misspelled and ensure that it
was imported. Example:

```
// solution 1:
use some_file::SomeTrait;

// solution 2:
trait SomeTrait {
    // some functions
}

struct Foo;

impl SomeTrait for Foo { // ok!
    // implements functions
}
```
"##,

E0407: r##"
A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // error: method `b` is not a member of trait `Foo`
}
```

Please verify you didn't misspell the method name and you used the correct
trait. First example:

```
trait Foo {
    fn a();
    fn b();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
    fn b() {} // ok!
}
```

Second example:

```
trait Foo {
    fn a();
}

struct Bar;

impl Foo for Bar {
    fn a() {}
}

impl Bar {
    fn b() {}
}
```
"##,

E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code:

```
static FOO : i32 = 0;

match 0 {
    FOO => {} // error: static variables cannot be referenced in a
              //        pattern, use a `const` instead
    _ => {}
}
```

The compiler needs to know the value of the pattern at compile time;
compile-time patterns can defined via const or enum items. Please verify
that the identifier is spelled correctly, and if so, use a const instead
of static to define it. Example:

```
const FOO : i32 = 0;

match 0 {
    FOO => {} // ok!
    _ => {}
}
```
"##,

E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo() {
        self.bar(); // error: `self` is not available in a static method.
    }
}
```

Please check if the method's argument list should have contained `self`,
`&self`, or `&mut self` (in case you didn't want to create a static
method), and add it if so. Example:

```
struct Foo;

impl Foo {
    fn bar(self) {}

    fn foo(self) {
        self.bar(); // ok!
    }
}
```
"##,

E0425: r##"
An unresolved name was used. Example of erroneous codes:

```
something_that_doesnt_exist::foo;
// error: unresolved name `something_that_doesnt_exist::foo`

// or:
trait Foo {
    fn bar() {
        Self; // error: unresolved name `Self`
    }
}
```

Please verify you didn't misspell the name or that you're not using an
invalid object. Example:

```
enum something_that_does_exist {
    foo
}
// or:
mod something_that_does_exist {
    pub static foo : i32 = 0i32;
}

something_that_does_exist::foo; // ok!
```
"##,

E0426: r##"
An undeclared label was used. Example of erroneous code:

```
loop {
    break 'a; // error: use of undeclared label `'a`
}
```

Please verify you spelt or declare the label correctly. Example:

```
'a: loop {
    break 'a; // ok!
}
```
"##,

E0428: r##"
A type or module has been defined more than once. Example of erroneous
code:

```
struct Bar;
struct Bar; // error: duplicate definition of value `Bar`
```

Please verify you didn't misspell the type/module's name or remove/rename the
duplicated one. Example:

```
struct Bar;
struct Bar2; // ok!
```
"##,

E0430: r##"
The `self` import appears more than once in the list. Erroneous code example:

```
use something::{self, self}; // error: `self` import can only appear once in
                             //        the list
```

Please verify you didn't misspell the import name or remove the duplicated
`self` import. Example:

```
use something::self; // ok!
```
"##,

E0431: r##"
`self` import was made. Erroneous code example:

```
use {self}; // error: `self` import can only appear in an import list with a
            //        non-empty prefix
```

You cannot import the current module into itself, please remove this import
or verify you didn't misspell it.
"##,

E0432: r##"
An import was unresolved. Erroneous code example:

```
use something::Foo; // error: unresolved import `something::Foo`.
```

Please verify you didn't misspell the import name or the import does exist
in the module from where you tried to import it. Example:

```
use something::Foo; // ok!

mod something {
    pub struct Foo;
}
```
"##,

E0433: r##"
Invalid import. Example of erroneous code:

```
use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist`
```

Please verify you didn't misspell the import's name.
"##,

E0437: r##"
Trait impls can only implement associated types that are members of the trait in
question. This error indicates that you attempted to implement an associated
type whose name does not match the name of any associated type in the trait.

Here is an example that demonstrates the error:

```
trait Foo {}

impl Foo for i32 {
    type Bar = bool;
}
```

The solution to this problem is to remove the extraneous associated type:

```
trait Foo {}

impl Foo for i32 {}
```
"##,

E0438: r##"
Trait impls can only implement associated constants that are members of the
trait in question. This error indicates that you attempted to implement an
associated constant whose name does not match the name of any associated
constant in the trait.

Here is an example that demonstrates the error:

```
#![feature(associated_consts)]

trait Foo {}

impl Foo for i32 {
    const BAR: bool = true;
}
```

The solution to this problem is to remove the extraneous associated constant:

```
trait Foo {}

impl Foo for i32 {}
```
"##

}

register_diagnostics! {
    E0153, // called no where
    E0157, // called from no where
    E0254, // import conflicts with imported crate in this module
    E0257,
    E0258,
    E0401, // can't use type parameters from outer function
    E0402, // cannot use an outer type parameter in this context
    E0406, // undeclared associated type
    E0408, // variable from pattern #1 is not bound in pattern #
    E0409, // variable is bound with different mode in pattern # than in
           // pattern #1
    E0410, // variable from pattern is not bound in pattern 1
    E0411, // use of `Self` outside of an impl or trait
    E0412, // use of undeclared
    E0413, // declaration of shadows an enum variant or unit-like struct in
           // scope
    E0414, // only irrefutable patterns allowed here
    E0415, // identifier is bound more than once in this parameter list
    E0416, // identifier is bound more than once in the same pattern
    E0418, // is not an enum variant, struct or const
    E0419, // unresolved enum variant, struct or const
    E0420, // is not an associated const
    E0421, // unresolved associated const
    E0422, // does not name a structure
    E0423, // is a struct variant name, but this expression uses it like a
           // function name
    E0427, // cannot use `ref` binding mode with ...
    E0429, // `self` imports are only allowed within a { } list
    E0434, // can't capture dynamic environment in a fn item
    E0435, // attempt to use a non-constant value in a constant
}
<|endoftext|>


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

//! Implementation of Rust stack unwinding
//!
//! For background on exception handling and stack unwinding please see
//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
//! documents linked from it.
//! These are also good reads:
//!     http://mentorembedded.github.io/cxx-abi/abi-eh.html
//!     http://monoinfinito.wordpress.com/series/exception-handling-in-c/
//!     http://www.airs.com/blog/index.php?s=exception+frames
//!
//! ## A brief summary
//!
//! Exception handling happens in two phases: a search phase and a cleanup phase.
//!
//! In both phases the unwinder walks stack frames from top to bottom using
//! information from the stack frame unwind sections of the current process's
//! modules ("module" here refers to an OS module, i.e. an executable or a
//! dynamic library).
//!
//! For each stack frame, it invokes the associated "personality routine", whose
//! address is also stored in the unwind info section.
//!
//! In the search phase, the job of a personality routine is to examine exception
//! object being thrown, and to decide whether it should be caught at that stack
//! frame.  Once the handler frame has been identified, cleanup phase begins.
//!
//! In the cleanup phase, personality routines invoke cleanup code associated
//! with their stack frames (i.e. destructors).  Once stack has been unwound down
//! to the handler frame level, unwinding stops and the last personality routine
//! transfers control to its catch block.
//!
//! ## Frame unwind info registration
//!
//! Each module has its own frame unwind info section (usually ".eh_frame"), and
//! unwinder needs to know about all of them in order for unwinding to be able to
//! cross module boundaries.
//!
//! On some platforms, like Linux, this is achieved by dynamically enumerating
//! currently loaded modules via the dl_iterate_phdr() API and finding all
//! .eh_frame sections.
//!
//! Others, like Windows, require modules to actively register their unwind info
//! sections by calling __register_frame_info() API at startup.  In the latter
//! case it is essential that there is only one copy of the unwinder runtime in
//! the process.  This is usually achieved by linking to the dynamic version of
//! the unwind runtime.
//!
//! Currently Rust uses unwind runtime provided by libgcc.

#![allow(dead_code)]
#![allow(unused_imports)]

use prelude::v1::*;

use any::Any;
use boxed;
use cell::Cell;
use cmp;
use panicking;
use fmt;
use intrinsics;
use mem;
use sync::atomic::{self, Ordering};
use sys_common::mutex::Mutex;

// The actual unwinding implementation is cfg'd here, and we've got two current
// implementations. One goes through SEH on Windows and the other goes through
// libgcc via the libunwind-like API.

// i686-pc-windows-msvc
#[cfg(all(windows, target_arch = "x86", target_env = "msvc"))]
#[path = "seh.rs"] #[doc(hidden)]
pub mod imp;

// x86_64-pc-windows-*
#[cfg(all(windows, target_arch = "x86_64"))]
#[path = "seh64_gnu.rs"] #[doc(hidden)]
pub mod imp;

// i686-pc-windows-gnu and all others
#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
#[path = "gcc.rs"] #[doc(hidden)]
pub mod imp;

pub type Callback = fn(msg: &(Any + Send), file: &'static str, line: u32);

// Variables used for invoking callbacks when a thread starts to unwind.
//
// For more information, see below.
const MAX_CALLBACKS: usize = 16;
static CALLBACKS: [atomic::AtomicUsize; MAX_CALLBACKS] =
        [atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0),
         atomic::AtomicUsize::new(0), atomic::AtomicUsize::new(0)];
static CALLBACK_CNT: atomic::AtomicUsize = atomic::AtomicUsize::new(0);

thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }

/// Invoke a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok(())` if the closure did not panic, and will
/// return `Err(cause)` if the closure panics. The `cause` returned is the
/// object with which panic was originally invoked.
///
/// This function also is unsafe for a variety of reasons:
///
/// * This is not safe to call in a nested fashion. The unwinding
///   interface for Rust is designed to have at most one try/catch block per
///   thread, not multiple. No runtime checking is currently performed to uphold
///   this invariant, so this function is not safe. A nested try/catch block
///   may result in corruption of the outer try/catch block's state, especially
///   if this is used within a thread itself.
///
/// * It is not sound to trigger unwinding while already unwinding. Rust threads
///   have runtime checks in place to ensure this invariant, but it is not
///   guaranteed that a rust thread is in place when invoking this function.
///   Unwinding twice can lead to resource leaks where some destructors are not
///   run.
pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
    let mut f = Some(f);
    return inner_try(try_fn::<F>, &mut f as *mut _ as *mut u8);

    // If an inner function were not used here, then this generic function `try`
    // uses the native symbol `rust_try`, for which the code is statically
    // linked into the standard library. This means that the DLL for the
    // standard library must have `rust_try` as an exposed symbol that
    // downstream crates can link against (because monomorphizations of `try` in
    // downstream crates will have a reference to the `rust_try` symbol).
    //
    // On MSVC this requires the symbol `rust_try` to be tagged with
    // `dllexport`, but it's easier to not have conditional `src/rt/rust_try.ll`
    // files and instead just have this non-generic shim the compiler can take
    // care of exposing correctly.
    unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
                        -> Result<(), Box<Any + Send>> {
        let prev = PANICKING.with(|s| s.get());
        PANICKING.with(|s| s.set(false));
        let ep = intrinsics::try(f, data);
        PANICKING.with(|s| s.set(prev));
        if ep.is_null() {
            Ok(())
        } else {
            Err(imp::cleanup(ep))
        }
    }

    fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
        let opt_closure = opt_closure as *mut Option<F>;
        unsafe { (*opt_closure).take().unwrap()(); }
    }

    extern {
        // Rust's try-catch
        // When f(...) returns normally, the return value is null.
        // When f(...) throws, the return value is a pointer to the caught
        // exception object.
        fn rust_try(f: extern fn(*mut u8),
                    data: *mut u8) -> *mut u8;
    }
}

/// Determines whether the current thread is unwinding because of panic.
pub fn panicking() -> bool {
    PANICKING.with(|s| s.get())
}

// An uninlined, unmangled function upon which to slap yer breakpoints
#[inline(never)]
#[no_mangle]
#[allow(private_no_mangle_fns)]
fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
    unsafe {
        imp::panic(cause)
    }
}

#[cfg(not(test))]
/// Entry point of panic from the libcore crate.
#[lang = "panic_fmt"]
#[unwind]
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
                                file: &'static str, line: u32) -> ! {
    begin_unwind_fmt(msg, &(file, line))
}

/// The entry point for unwinding with a formatted message.
///
/// This is designed to reduce the amount of code required at the call
/// site as much as possible (so that `panic!()` has as low an impact
/// on (e.g.) the inlining of other functions as possible), by moving
/// the actual formatting into this shared place.
#[inline(never)] #[cold]
pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
    use fmt::Write;

    // We do two allocations here, unfortunately. But (a) they're
    // required with the current scheme, and (b) we don't handle
    // panic + OOM properly anyway (see comment in begin_unwind
    // below).

    let mut s = String::new();
    let _ = s.write_fmt(msg);
    begin_unwind_inner(Box::new(s), file_line)
}

/// This is the entry point of unwinding for panic!() and assert!().
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
    // Note that this should be the only allocation performed in this code path.
    // Currently this means that panic!() on OOM will invoke this code path,
    // but then again we're not really ready for panic on OOM anyway. If
    // we do start doing this, then we should propagate this allocation to
    // be performed in the parent of this thread instead of the thread that's
    // panicking.

    // see below for why we do the `Any` coercion here.
    begin_unwind_inner(Box::new(msg), file_line)
}

/// The core of the unwinding.
///
/// This is non-generic to avoid instantiation bloat in other crates
/// (which makes compilation of small crates noticeably slower). (Note:
/// we need the `Any` object anyway, we're not just creating it to
/// avoid being generic.)
///
/// Doing this split took the LLVM IR line counts of `fn main() { panic!()
/// }` from ~1900/3700 (-O/no opts) to 180/590.
#[inline(never)] #[cold] // this is the slow path, please never inline this
fn begin_unwind_inner(msg: Box<Any + Send>,
                      file_line: &(&'static str, u32)) -> ! {
    let (file, line) = *file_line;

    // First, invoke the default panic handler.
    panicking::on_panic(&*msg, file, line);

    // Then, invoke call the user-defined callbacks triggered on thread panic.
    //
    // By the time that we see a callback has been registered (by reading
    // MAX_CALLBACKS), the actual callback itself may have not been stored yet,
    // so we just chalk it up to a race condition and move on to the next
    // callback. Additionally, CALLBACK_CNT may briefly be higher than
    // MAX_CALLBACKS, so we're sure to clamp it as necessary.
    let callbacks = {
        let amt = CALLBACK_CNT.load(Ordering::SeqCst);
        &CALLBACKS[..cmp::min(amt, MAX_CALLBACKS)]
    };
    for cb in callbacks {
        match cb.load(Ordering::SeqCst) {
            0 => {}
            n => {
                let f: Callback = unsafe { mem::transmute(n) };
                f(&*msg, file, line);
            }
        }
    };

    // Now that we've run all the necessary unwind callbacks, we actually
    // perform the unwinding.
    if panicking() {
        // If a thread panics while it's already unwinding then we
        // have limited options. Currently our preference is to
        // just abort. In the future we may consider resuming
        // unwinding or otherwise exiting the thread cleanly.
        super::util::dumb_print(format_args!("thread panicked while panicking. \
                                              aborting."));
        unsafe { intrinsics::abort() }
    }
    PANICKING.with(|s| s.set(true));
    rust_panic(msg);
}

/// Register a callback to be invoked when a thread unwinds.
///
/// This is an unsafe and experimental API which allows for an arbitrary
/// callback to be invoked when a thread panics. This callback is invoked on both
/// the initial unwinding and a double unwinding if one occurs. Additionally,
/// the local `Thread` will be in place for the duration of the callback, and
/// the callback must ensure that it remains in place once the callback returns.
///
/// Only a limited number of callbacks can be registered, and this function
/// returns whether the callback was successfully registered or not. It is not
/// currently possible to unregister a callback once it has been registered.
pub unsafe fn register(f: Callback) -> bool {
    match CALLBACK_CNT.fetch_add(1, Ordering::SeqCst) {
        // The invocation code has knowledge of this window where the count has
        // been incremented, but the callback has not been stored. We're
        // guaranteed that the slot we're storing into is 0.
        n if n < MAX_CALLBACKS => {
            let prev = CALLBACKS[n].swap(mem::transmute(f), Ordering::SeqCst);
            rtassert!(prev == 0);
            true
        }
        // If we accidentally bumped the count too high, pull it back.
        _ => {
            CALLBACK_CNT.store(MAX_CALLBACKS, Ordering::SeqCst);
            false
        }
    }
}
<commit_msg>Remove unwind::register<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of Rust stack unwinding
//!
//! For background on exception handling and stack unwinding please see
//! "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
//! documents linked from it.
//! These are also good reads:
//!     http://mentorembedded.github.io/cxx-abi/abi-eh.html
//!     http://monoinfinito.wordpress.com/series/exception-handling-in-c/
//!     http://www.airs.com/blog/index.php?s=exception+frames
//!
//! ## A brief summary
//!
//! Exception handling happens in two phases: a search phase and a cleanup phase.
//!
//! In both phases the unwinder walks stack frames from top to bottom using
//! information from the stack frame unwind sections of the current process's
//! modules ("module" here refers to an OS module, i.e. an executable or a
//! dynamic library).
//!
//! For each stack frame, it invokes the associated "personality routine", whose
//! address is also stored in the unwind info section.
//!
//! In the search phase, the job of a personality routine is to examine exception
//! object being thrown, and to decide whether it should be caught at that stack
//! frame.  Once the handler frame has been identified, cleanup phase begins.
//!
//! In the cleanup phase, personality routines invoke cleanup code associated
//! with their stack frames (i.e. destructors).  Once stack has been unwound down
//! to the handler frame level, unwinding stops and the last personality routine
//! transfers control to its catch block.
//!
//! ## Frame unwind info registration
//!
//! Each module has its own frame unwind info section (usually ".eh_frame"), and
//! unwinder needs to know about all of them in order for unwinding to be able to
//! cross module boundaries.
//!
//! On some platforms, like Linux, this is achieved by dynamically enumerating
//! currently loaded modules via the dl_iterate_phdr() API and finding all
//! .eh_frame sections.
//!
//! Others, like Windows, require modules to actively register their unwind info
//! sections by calling __register_frame_info() API at startup.  In the latter
//! case it is essential that there is only one copy of the unwinder runtime in
//! the process.  This is usually achieved by linking to the dynamic version of
//! the unwind runtime.
//!
//! Currently Rust uses unwind runtime provided by libgcc.

#![allow(dead_code)]
#![allow(unused_imports)]

use prelude::v1::*;

use any::Any;
use boxed;
use cell::Cell;
use cmp;
use panicking;
use fmt;
use intrinsics;
use mem;
use sync::atomic::{self, Ordering};
use sys_common::mutex::Mutex;

// The actual unwinding implementation is cfg'd here, and we've got two current
// implementations. One goes through SEH on Windows and the other goes through
// libgcc via the libunwind-like API.

// i686-pc-windows-msvc
#[cfg(all(windows, target_arch = "x86", target_env = "msvc"))]
#[path = "seh.rs"] #[doc(hidden)]
pub mod imp;

// x86_64-pc-windows-*
#[cfg(all(windows, target_arch = "x86_64"))]
#[path = "seh64_gnu.rs"] #[doc(hidden)]
pub mod imp;

// i686-pc-windows-gnu and all others
#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
#[path = "gcc.rs"] #[doc(hidden)]
pub mod imp;

thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }

/// Invoke a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok(())` if the closure did not panic, and will
/// return `Err(cause)` if the closure panics. The `cause` returned is the
/// object with which panic was originally invoked.
///
/// This function also is unsafe for a variety of reasons:
///
/// * This is not safe to call in a nested fashion. The unwinding
///   interface for Rust is designed to have at most one try/catch block per
///   thread, not multiple. No runtime checking is currently performed to uphold
///   this invariant, so this function is not safe. A nested try/catch block
///   may result in corruption of the outer try/catch block's state, especially
///   if this is used within a thread itself.
///
/// * It is not sound to trigger unwinding while already unwinding. Rust threads
///   have runtime checks in place to ensure this invariant, but it is not
///   guaranteed that a rust thread is in place when invoking this function.
///   Unwinding twice can lead to resource leaks where some destructors are not
///   run.
pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
    let mut f = Some(f);
    return inner_try(try_fn::<F>, &mut f as *mut _ as *mut u8);

    // If an inner function were not used here, then this generic function `try`
    // uses the native symbol `rust_try`, for which the code is statically
    // linked into the standard library. This means that the DLL for the
    // standard library must have `rust_try` as an exposed symbol that
    // downstream crates can link against (because monomorphizations of `try` in
    // downstream crates will have a reference to the `rust_try` symbol).
    //
    // On MSVC this requires the symbol `rust_try` to be tagged with
    // `dllexport`, but it's easier to not have conditional `src/rt/rust_try.ll`
    // files and instead just have this non-generic shim the compiler can take
    // care of exposing correctly.
    unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
                        -> Result<(), Box<Any + Send>> {
        let prev = PANICKING.with(|s| s.get());
        PANICKING.with(|s| s.set(false));
        let ep = intrinsics::try(f, data);
        PANICKING.with(|s| s.set(prev));
        if ep.is_null() {
            Ok(())
        } else {
            Err(imp::cleanup(ep))
        }
    }

    fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
        let opt_closure = opt_closure as *mut Option<F>;
        unsafe { (*opt_closure).take().unwrap()(); }
    }

    extern {
        // Rust's try-catch
        // When f(...) returns normally, the return value is null.
        // When f(...) throws, the return value is a pointer to the caught
        // exception object.
        fn rust_try(f: extern fn(*mut u8),
                    data: *mut u8) -> *mut u8;
    }
}

/// Determines whether the current thread is unwinding because of panic.
pub fn panicking() -> bool {
    PANICKING.with(|s| s.get())
}

// An uninlined, unmangled function upon which to slap yer breakpoints
#[inline(never)]
#[no_mangle]
#[allow(private_no_mangle_fns)]
fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
    unsafe {
        imp::panic(cause)
    }
}

#[cfg(not(test))]
/// Entry point of panic from the libcore crate.
#[lang = "panic_fmt"]
#[unwind]
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
                                file: &'static str, line: u32) -> ! {
    begin_unwind_fmt(msg, &(file, line))
}

/// The entry point for unwinding with a formatted message.
///
/// This is designed to reduce the amount of code required at the call
/// site as much as possible (so that `panic!()` has as low an impact
/// on (e.g.) the inlining of other functions as possible), by moving
/// the actual formatting into this shared place.
#[inline(never)] #[cold]
pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
    use fmt::Write;

    // We do two allocations here, unfortunately. But (a) they're
    // required with the current scheme, and (b) we don't handle
    // panic + OOM properly anyway (see comment in begin_unwind
    // below).

    let mut s = String::new();
    let _ = s.write_fmt(msg);
    begin_unwind_inner(Box::new(s), file_line)
}

/// This is the entry point of unwinding for panic!() and assert!().
#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
    // Note that this should be the only allocation performed in this code path.
    // Currently this means that panic!() on OOM will invoke this code path,
    // but then again we're not really ready for panic on OOM anyway. If
    // we do start doing this, then we should propagate this allocation to
    // be performed in the parent of this thread instead of the thread that's
    // panicking.

    // see below for why we do the `Any` coercion here.
    begin_unwind_inner(Box::new(msg), file_line)
}

/// The core of the unwinding.
///
/// This is non-generic to avoid instantiation bloat in other crates
/// (which makes compilation of small crates noticeably slower). (Note:
/// we need the `Any` object anyway, we're not just creating it to
/// avoid being generic.)
///
/// Doing this split took the LLVM IR line counts of `fn main() { panic!()
/// }` from ~1900/3700 (-O/no opts) to 180/590.
#[inline(never)] #[cold] // this is the slow path, please never inline this
fn begin_unwind_inner(msg: Box<Any + Send>,
                      file_line: &(&'static str, u32)) -> ! {
    let (file, line) = *file_line;

    // First, invoke the default panic handler.
    panicking::on_panic(&*msg, file, line);

    if panicking() {
        // If a thread panics while it's already unwinding then we
        // have limited options. Currently our preference is to
        // just abort. In the future we may consider resuming
        // unwinding or otherwise exiting the thread cleanly.
        super::util::dumb_print(format_args!("thread panicked while panicking. \
                                              aborting."));
        unsafe { intrinsics::abort() }
    }
    PANICKING.with(|s| s.set(true));

    // Finally, perform the unwinding.
    rust_panic(msg);
}
<|endoftext|>


<commit_before><commit_msg>Closes #9243 Test case<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.

// Regresion test for issue 9243

struct Test {
    mem: int,
}

pub static g_test: Test = Test {mem: 0}; //~ ERROR static items are not allowed to have destructors

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

fn main() {}
<|endoftext|>


<commit_before>use conn::Conn;
use conn::futures::query_result::BinQueryResult;
use conn::futures::Prepare;
use conn::stmt::futures::Execute;
use conn::stmt::Stmt;
use errors::*;
use lib_futures::Async;
use lib_futures::Async::Ready;
use lib_futures::Future;
use lib_futures::Poll;
use value::Params;

enum Step {
    Prepare(Prepare),
    Execute(Execute),
}

enum Out {
    Prepare(Stmt),
    Execute(BinQueryResult),
}

pub struct PrepExec {
    step: Step,
    params: Option<Params>,
}

pub fn new<Q, P>(conn: Conn, query: Q, params: P) -> PrepExec
    where Q: AsRef<str>,
          P: Into<Params>,
{
    PrepExec {
        step: Step::Prepare(conn.prepare(query)),
        params: Some(params.into()),
    }
}

impl PrepExec {
    fn either_poll(&mut self) -> Result<Async<Out>> {
        match self.step {
            Step::Prepare(ref mut fut) => Ok(Ready(Out::Prepare(try_ready!(fut.poll())))),
            Step::Execute(ref mut fut) => Ok(Ready(Out::Execute(try_ready!(fut.poll())))),
        }
    }
}

impl Future for PrepExec {
    type Item = BinQueryResult;
    type Error = Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match try_ready!(self.either_poll()) {
            Out::Prepare(stmt) => {
                let params = self.params.take().unwrap();
                self.step = Step::Execute(stmt.execute(params));
                self.poll()
            },
            Out::Execute(query_result) => Ok(Ready(query_result)),
        }
    }
}
<commit_msg>Use steps! for PrepExec future<commit_after>use conn::Conn;
use conn::futures::query_result::BinQueryResult;
use conn::futures::Prepare;
use conn::stmt::futures::Execute;
use errors::*;
use lib_futures::Async;
use lib_futures::Async::Ready;
use lib_futures::Future;
use lib_futures::Poll;
use std::mem;
use value::Params;

steps! {
    PrepExec {
        Prepare(Prepare),
        Execute(Execute),
    }
}

pub struct PrepExec {
    step: Step,
    params: Params,
}

pub fn new<Q, P>(conn: Conn, query: Q, params: P) -> PrepExec
    where Q: AsRef<str>,
          P: Into<Params>,
{
    PrepExec {
        step: Step::Prepare(conn.prepare(query)),
        params: params.into(),
    }
}

impl Future for PrepExec {
    type Item = BinQueryResult;
    type Error = Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match try_ready!(self.either_poll()) {
            Out::Prepare(stmt) => {
                let params = mem::replace(&mut self.params, Params::Empty);
                self.step = Step::Execute(stmt.execute(params));
                self.poll()
            },
            Out::Execute(query_result) => Ok(Ready(query_result)),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add code for computing the obligatory factorials<commit_after>fn main() {
    let mut prod = 1u;
    let mut count = 1u;

    println!("Computing factorial!");
    loop {
        count += 1;
        if count == 11 {
            println!("We are done here");
            break;
        }

        prod *= count;
    }

    println!("Computed the factorial for 10: {}", prod);
}
<|endoftext|>


<commit_before><commit_msg>Add CLI interface for listing dead refs<commit_after><|endoftext|>


<commit_before>import std._vec;

/* A codemap is a thing that maps uints to file/line/column positions
 * in a crate. This to make it possible to represent the positions
 * with single-word things, rather than passing records all over the
 * compiler.
 */

type filemap = @rec(str name,
                    uint start_pos,
                    mutable vec[uint] lines);
type codemap = @rec(mutable vec[filemap] files);
type loc = rec(str filename, uint line, uint col);

fn new_codemap() -> codemap {
    let vec[filemap] files = vec();
    ret @rec(mutable files=files);
}

fn new_filemap(str filename, uint start_pos) -> filemap {
    let vec[uint] lines = vec();
    ret @rec(name=filename,
             start_pos=start_pos,
             mutable lines=lines);
}

fn next_line(filemap file, uint pos) {
    _vec.push[uint](file.lines, pos);
}

fn lookup_pos(codemap map, uint pos) -> loc {
    for (filemap f in map.files) {
        if (f.start_pos < pos) {
            auto line_num = 1u;
            auto line_start = 0u;
            // FIXME this can be a binary search if we need to be faster
            for (uint line_start_ in f.lines) {
                // FIXME duplicate code due to lack of working break
                if (line_start_ > pos) {
                    ret rec(filename=f.name,
                            line=line_num,
                            col=pos-line_start);
                }
                line_start = line_start_;
                line_num += 1u;
            }
            ret rec(filename=f.name,
                    line=line_num,
                    col=pos-line_start);
        }
    }
    log #fmt("Failed to find a location for character %u", pos);
    fail;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Fix codemap.lookup_pos<commit_after>import std._vec;

/* A codemap is a thing that maps uints to file/line/column positions
 * in a crate. This to make it possible to represent the positions
 * with single-word things, rather than passing records all over the
 * compiler.
 */

type filemap = @rec(str name,
                    uint start_pos,
                    mutable vec[uint] lines);
type codemap = @rec(mutable vec[filemap] files);
type loc = rec(str filename, uint line, uint col);

fn new_codemap() -> codemap {
    let vec[filemap] files = vec();
    ret @rec(mutable files=files);
}

fn new_filemap(str filename, uint start_pos) -> filemap {
    ret @rec(name=filename,
             start_pos=start_pos,
             mutable lines=vec(0u));
}

fn next_line(filemap file, uint pos) {
    _vec.push[uint](file.lines, pos);
}

fn lookup_pos(codemap map, uint pos) -> loc {
    auto i = _vec.len[filemap](map.files);
    while (i > 0u) {
        i -= 1u;
        auto f = map.files.(i);
        if (f.start_pos <= pos) {
            // FIXME this can be a binary search if we need to be faster
            auto line = _vec.len[uint](f.lines);
            while (line > 0u) {
                line -= 1u;
                auto line_start = f.lines.(line);
                if (line_start <= pos) {
                    ret rec(filename=f.name,
                            line=line + 1u,
                            col=pos-line_start);
                }
            }
        }
    }
    log #fmt("Failed to find a location for character %u", pos);
    fail;
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>