<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! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0003: r##"
Not-a-Number (NaN) values can not be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler can not guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##

}

register_diagnostics! {
    E0002,
    E0007,
    E0008,
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0152,
    E0158,
    E0161,
    E0162,
    E0165,
    E0170,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0297, // refutable pattern in for loop binding
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0301, // cannot mutable borrow in a pattern guard
    E0302, // cannot assign in a pattern guard
    E0303, // pattern bindings are not allowed after an `@`
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0306, // expected positive integer for repeat count
    E0307, // expected constant integer for repeat count
    E0308,
    E0309, // thing may not live long enough
    E0310, // thing may not live long enough
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<commit_msg>Add more extended error messages for match exprs.<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! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0152,
    E0158,
    E0161,
    E0162,
    E0165,
    E0170,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0297, // refutable pattern in for loop binding
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0301, // cannot mutable borrow in a pattern guard
    E0302, // cannot assign in a pattern guard
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0306, // expected positive integer for repeat count
    E0307, // expected constant integer for repeat count
    E0308,
    E0309, // thing may not live long enough
    E0310, // thing may not live long enough
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<|endoftext|>


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

use syntax::ast;
use syntax::codemap::{Span};
use syntax::visit;
use syntax::visit::Visitor;

use std::hashmap::HashSet;
use extra;

pub fn time<T>(do_it: bool, what: ~str, thunk: &fn() -> T) -> T {
    if !do_it { return thunk(); }
    let start = extra::time::precise_time_s();
    let rv = thunk();
    let end = extra::time::precise_time_s();
    printfln!("time: %3.3f s\t%s", end - start, what);
    rv
}

pub fn indent<R>(op: &fn() -> R) -> R {
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = %?)", r);
    r
}

pub struct _indenter {
    _i: (),
}

impl Drop for _indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn _indenter(_i: ()) -> _indenter {
    _indenter {
        _i: ()
    }
}

pub fn indenter() -> _indenter {
    debug!(">>");
    _indenter(())
}

pub fn field_expr(f: ast::Field) -> @ast::Expr { return f.expr; }

pub fn field_exprs(fields: ~[ast::Field]) -> ~[@ast::Expr] {
    fields.map(|f| f.expr)
}

struct LoopQueryVisitor {
    p: @fn(&ast::Expr_) -> bool
}

impl Visitor<@mut bool> for LoopQueryVisitor {
    fn visit_expr(&mut self, e:@ast::Expr, flag:@mut bool) {
        *flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(*) | ast::ExprWhile(*) => {}
          _ => visit::walk_expr(self, e, flag)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query(b: &ast::Block, p: @fn(&ast::Expr_) -> bool) -> bool {
    let rs = @mut false;
    let mut v = LoopQueryVisitor { p: p };
    visit::walk_block(&mut v, b, rs);
    return *rs;
}

struct BlockQueryVisitor {
    p: @fn(@ast::Expr) -> bool
}

impl Visitor<@mut bool> for BlockQueryVisitor {
    fn visit_expr(&mut self, e:@ast::Expr, flag:@mut bool) {
        *flag |= (self.p)(e);
        visit::walk_expr(self, e, flag)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query(b: &ast::Block, p: @fn(@ast::Expr) -> bool) -> bool {
    let rs = @mut false;
    let mut v = BlockQueryVisitor { p: p };
    visit::walk_block(&mut v, b, rs);
    return *rs;
}

pub fn local_rhs_span(l: @ast::Local, def: Span) -> Span {
    match l.init {
      Some(i) => return i.span,
      _ => return def
    }
}

pub fn pluralize(n: uint, s: ~str) -> ~str {
    if n == 1 { s }
    else { fmt!("%ss", s) }
}

// A set of node IDs (used to keep track of which node IDs are for statements)
pub type stmt_set = @mut HashSet<ast::NodeId>;
<commit_msg>librustc: Remove garbage-collected functions from util/common.<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax::ast;
use syntax::codemap::{Span};
use syntax::visit;
use syntax::visit::Visitor;

use std::hashmap::HashSet;
use extra;

pub fn time<T>(do_it: bool, what: ~str, thunk: &fn() -> T) -> T {
    if !do_it { return thunk(); }
    let start = extra::time::precise_time_s();
    let rv = thunk();
    let end = extra::time::precise_time_s();
    printfln!("time: %3.3f s\t%s", end - start, what);
    rv
}

pub fn indent<R>(op: &fn() -> R) -> R {
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = %?)", r);
    r
}

pub struct _indenter {
    _i: (),
}

impl Drop for _indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn _indenter(_i: ()) -> _indenter {
    _indenter {
        _i: ()
    }
}

pub fn indenter() -> _indenter {
    debug!(">>");
    _indenter(())
}

pub fn field_expr(f: ast::Field) -> @ast::Expr { return f.expr; }

pub fn field_exprs(fields: ~[ast::Field]) -> ~[@ast::Expr] {
    fields.map(|f| f.expr)
}

struct LoopQueryVisitor<'self> {
    p: &'self fn(&ast::Expr_) -> bool
}

impl<'self> Visitor<@mut bool> for LoopQueryVisitor<'self> {
    fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) {
        *flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(*) | ast::ExprWhile(*) => {}
          _ => visit::walk_expr(self, e, flag)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query(b: &ast::Block, p: &fn(&ast::Expr_) -> bool) -> bool {
    let rs = @mut false;
    let mut v = LoopQueryVisitor {
        p: p,
    };
    visit::walk_block(&mut v, b, rs);
    return *rs;
}

struct BlockQueryVisitor<'self> {
    p: &'self fn(@ast::Expr) -> bool
}

impl<'self> Visitor<@mut bool> for BlockQueryVisitor<'self> {
    fn visit_expr(&mut self, e: @ast::Expr, flag: @mut bool) {
        *flag |= (self.p)(e);
        visit::walk_expr(self, e, flag)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query(b: &ast::Block, p: &fn(@ast::Expr) -> bool) -> bool {
    let rs = @mut false;
    let mut v = BlockQueryVisitor {
        p: p,
    };
    visit::walk_block(&mut v, b, rs);
    return *rs;
}

pub fn local_rhs_span(l: @ast::Local, def: Span) -> Span {
    match l.init {
      Some(i) => return i.span,
      _ => return def
    }
}

pub fn pluralize(n: uint, s: ~str) -> ~str {
    if n == 1 { s }
    else { fmt!("%ss", s) }
}

// A set of node IDs (used to keep track of which node IDs are for statements)
pub type stmt_set = @mut HashSet<ast::NodeId>;
<|endoftext|>


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

use core::prelude::*;

use ast::{crate, expr_, expr_mac, mac_invoc_tt};
use ast::{tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
use ast;
use codemap::{span, ExpandedFrom};
use ext::base::*;
use fold::*;
use parse::{parser, parse_expr_from_source_str, new_parser_from_tts};

use core::option;
use core::vec;
use std::map::HashMap;

fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
               e: expr_, s: span, fld: ast_fold,
               orig: fn@(expr_, span, ast_fold) -> (expr_, span))
    -> (expr_, span)
{
    return match e {
      // expr_mac should really be expr_ext or something; it's the
      // entry-point for all syntax extensions.
          expr_mac(ref mac) => {

            match (*mac).node {

              // Token-tree macros, these will be the only case when we're
              // finished transitioning.
              mac_invoc_tt(pth, ref tts) => {
                assert (vec::len(pth.idents) == 1u);
                /* using idents and token::special_idents would make the
                the macro names be hygienic */
                let extname = cx.parse_sess().interner.get(pth.idents[0]);
                match exts.find(*extname) {
                  None => {
                    cx.span_fatal(pth.span,
                                  fmt!("macro undefined: '%s'", *extname))
                  }
                  Some(NormalTT(SyntaxExpanderTT{expander: exp, span: exp_sp})) => {
                    cx.bt_push(ExpandedFrom({call_site: s,
                                callie: {name: *extname, span: exp_sp}}));

                    let expanded = match exp(cx, (*mac).span, (*tts)) {
                      MRExpr(e) => e,
                      MRAny(expr_maker,_,_) => expr_maker(),
                      _ => cx.span_fatal(
                          pth.span, fmt!("non-expr macro in expr pos: %s",
                                         *extname))
                    };

                    //keep going, outside-in
                    let fully_expanded = fld.fold_expr(expanded).node;
                    cx.bt_pop();

                    (fully_expanded, s)
                  }
                  _ => {
                    cx.span_fatal(pth.span,
                                  fmt!("'%s' is not a tt-style macro",
                                       *extname))
                  }

                }
              }
            }
          }
          _ => orig(e, s, fld)
        };
}

// This is a secondary mechanism for invoking syntax extensions on items:
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
// attribute prefixing an item, and are interpreted by feeding the item
// through the named attribute _as a syntax extension_ and splicing in the
// resulting item vec into place in favour of the decorator. Note that
// these do _not_ work for macro extensions, just ItemDecorator ones.
//
// NB: there is some redundancy between this and expand_item, below, and
// they might benefit from some amount of semantic and language-UI merger.
fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
                    module_: ast::_mod, fld: ast_fold,
                    orig: fn@(ast::_mod, ast_fold) -> ast::_mod)
    -> ast::_mod
{
    // Fold the contents first:
    let module_ = orig(module_, fld);

    // For each item, look through the attributes.  If any of them are
    // decorated with "item decorators", then use that function to transform
    // the item into a new set of items.
    let new_items = do vec::flat_map(module_.items) |item| {
        do vec::foldr(item.attrs, ~[*item]) |attr, items| {
            let mname = match attr.node.value.node {
              ast::meta_word(ref n) => (*n),
              ast::meta_name_value(ref n, _) => (*n),
              ast::meta_list(ref n, _) => (*n)
            };
            match exts.find(mname) {
              None | Some(NormalTT(_)) | Some(ItemTT(*)) => items,
              Some(ItemDecorator(dec_fn)) => {
                  cx.bt_push(ExpandedFrom({call_site: attr.span,
                                           callie: {name: copy mname,
                                                    span: None}}));
                  let r = dec_fn(cx, attr.span, attr.node.value, items);
                  cx.bt_pop();
                  r
              }
            }
        }
    };

    ast::_mod { items: new_items, ..module_ }
}

// When we enter a module, record it, for the sake of `module!`
fn expand_item(exts: HashMap<~str, SyntaxExtension>,
               cx: ext_ctxt, &&it: @ast::item, fld: ast_fold,
               orig: fn@(&&v: @ast::item, ast_fold) -> Option<@ast::item>)
    -> Option<@ast::item>
{
    let is_mod = match it.node {
      ast::item_mod(_) | ast::item_foreign_mod(_) => true,
      _ => false
    };
    let maybe_it = match it.node {
      ast::item_mac(*) => expand_item_mac(exts, cx, it, fld),
      _ => Some(it)
    };

    match maybe_it {
      Some(it) => {
        if is_mod { cx.mod_push(it.ident); }
        let ret_val = orig(it, fld);
        if is_mod { cx.mod_pop(); }
        return ret_val;
      }
      None => return None
    }
}

// Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations.
fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
                   cx: ext_ctxt, &&it: @ast::item,
                   fld: ast_fold) -> Option<@ast::item> {

    let (pth, tts) = match it.node {
        item_mac(ast::spanned { node: mac_invoc_tt(pth, ref tts), _}) => {
            (pth, (*tts))
        }
        _ => cx.span_bug(it.span, ~"invalid item macro invocation")
    };

    let extname = cx.parse_sess().interner.get(pth.idents[0]);
    let expanded = match exts.find(*extname) {
        None => cx.span_fatal(pth.span,
                              fmt!("macro undefined: '%s!'", *extname)),

        Some(NormalTT(ref expand)) => {
            if it.ident != parse::token::special_idents::invalid {
                cx.span_fatal(pth.span,
                              fmt!("macro %s! expects no ident argument, \
                                    given '%s'", *extname,
                                   *cx.parse_sess().interner.get(it.ident)));
            }
            cx.bt_push(ExpandedFrom({call_site: it.span,
                                     callie: {name: *extname,
                                              span: (*expand).span}}));
            ((*expand).expander)(cx, it.span, tts)
        }
        Some(ItemTT(ref expand)) => {
            if it.ident == parse::token::special_idents::invalid {
                cx.span_fatal(pth.span,
                              fmt!("macro %s! expects an ident argument",
                                   *extname));
            }
            cx.bt_push(ExpandedFrom({call_site: it.span,
                                     callie: {name: *extname,
                                              span: (*expand).span}}));
            ((*expand).expander)(cx, it.span, it.ident, tts)
        }
        _ => cx.span_fatal(
            it.span, fmt!("%s! is not legal in item position", *extname))
    };

    let maybe_it = match expanded {
        MRItem(it) => fld.fold_item(it),
        MRExpr(_) => cx.span_fatal(pth.span,
                                    ~"expr macro in item position: "
                                    + *extname),
        MRAny(_, item_maker, _) =>
            option::chain(item_maker(), |i| {fld.fold_item(i)}),
        MRDef(ref mdef) => {
            exts.insert((*mdef).name, (*mdef).ext);
            None
        }
    };
    cx.bt_pop();
    return maybe_it;
}

fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
               && s: stmt_, sp: span, fld: ast_fold,
               orig: fn@(&&s: stmt_, span, ast_fold) -> (stmt_, span))
    -> (stmt_, span)
{

    let (mac, pth, tts, semi) = match s {
        stmt_mac(ref mac, semi) => {
            match (*mac).node {
                mac_invoc_tt(pth, ref tts) => ((*mac), pth, (*tts), semi)
            }
        }
        _ => return orig(s, sp, fld)
    };

    assert(vec::len(pth.idents) == 1u);
    let extname = cx.parse_sess().interner.get(pth.idents[0]);
    let (fully_expanded, sp) = match exts.find(*extname) {
        None =>
            cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)),

        Some(NormalTT(
            SyntaxExpanderTT{expander: exp, span: exp_sp})) => {
            cx.bt_push(ExpandedFrom(
                {call_site: sp, callie: {name: *extname, span: exp_sp}}));
            let expanded = match exp(cx, mac.span, tts) {
                MRExpr(e) =>
                    @ast::spanned { node: stmt_expr(e, cx.next_id()),
                                    span: e.span},
                MRAny(_,_,stmt_mkr) => stmt_mkr(),
                _ => cx.span_fatal(
                    pth.span,
                    fmt!("non-stmt macro in stmt pos: %s", *extname))
            };

            //keep going, outside-in
            let fully_expanded = fld.fold_stmt(expanded).node;
            cx.bt_pop();

            (fully_expanded, sp)
        }

        _ => {
            cx.span_fatal(pth.span,
                          fmt!("'%s' is not a tt-style macro", *extname))
        }
    };

    return (match fully_expanded {
        stmt_expr(e, stmt_id) if semi => stmt_semi(e, stmt_id),
        _ => { fully_expanded } /* might already have a semi */
    }, sp)

}

fn new_span(cx: ext_ctxt, sp: span) -> span {
    /* this discards information in the case of macro-defining macros */
    return span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
}

// FIXME (#2247): this is a terrible kludge to inject some macros into
// the default compilation environment. When the macro-definition system
// is substantially more mature, these should move from here, into a
// compiled part of libcore at very least.

fn core_macros() -> ~str {
    return
~"{
    macro_rules! ignore (($($x:tt)*) => (()))

    macro_rules! error ( ($( $arg:expr ),+) => (
        log(::core::error, fmt!( $($arg),+ )) ))
    macro_rules! warn ( ($( $arg:expr ),+) => (
        log(::core::warn, fmt!( $($arg),+ )) ))
    macro_rules! info ( ($( $arg:expr ),+) => (
        log(::core::info, fmt!( $($arg),+ )) ))
    macro_rules! debug ( ($( $arg:expr ),+) => (
        log(::core::debug, fmt!( $($arg),+ )) ))

    macro_rules! die(
        ($msg: expr) => (
            ::core::sys::begin_unwind($msg, file!().to_owned(), line!())
        );
        () => (
            die!(~\"explicit failure\")
        )
    )

    macro_rules! condition (

        { $c:ident: $in:ty -> $out:ty; } => {

            mod $c {
                fn key(_x: @::core::condition::Handler<$in,$out>) { }

                pub const cond : ::core::condition::Condition<$in,$out> =
                    ::core::condition::Condition {
                    name: stringify!($c),
                    key: key
                };
            }
        }
    )

}";
}

fn expand_crate(parse_sess: parse::parse_sess,
                cfg: ast::crate_cfg, c: @crate) -> @crate {
    let exts = syntax_expander_table();
    let afp = default_ast_fold();
    let cx: ext_ctxt = mk_ctxt(parse_sess, cfg);
    let f_pre = @AstFoldFns {
        fold_expr: |a,b,c| expand_expr(exts, cx, a, b, c, afp.fold_expr),
        fold_mod: |a,b| expand_mod_items(exts, cx, a, b, afp.fold_mod),
        fold_item: |a,b| expand_item(exts, cx, a, b, afp.fold_item),
        fold_stmt: |a,b,c| expand_stmt(exts, cx, a, b, c, afp.fold_stmt),
        new_span: |a| new_span(cx, a),
        .. *afp};
    let f = make_fold(f_pre);
    let cm = parse_expr_from_source_str(~"<core-macros>",
                                        @core_macros(),
                                        cfg,
                                        parse_sess);

    // This is run for its side-effects on the expander env,
    // as it registers all the core macros as expanders.
    f.fold_expr(cm);

    let res = @f.fold_crate(*c);
    return res;
}
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Long lines<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use ast::{crate, expr_, expr_mac, mac_invoc_tt};
use ast::{tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi};
use ast;
use codemap::{span, ExpandedFrom};
use ext::base::*;
use fold::*;
use parse::{parser, parse_expr_from_source_str, new_parser_from_tts};

use core::option;
use core::vec;
use std::map::HashMap;

fn expand_expr(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
               e: expr_, s: span, fld: ast_fold,
               orig: fn@(expr_, span, ast_fold) -> (expr_, span))
    -> (expr_, span)
{
    return match e {
      // expr_mac should really be expr_ext or something; it's the
      // entry-point for all syntax extensions.
          expr_mac(ref mac) => {

            match (*mac).node {

              // Token-tree macros, these will be the only case when we're
              // finished transitioning.
              mac_invoc_tt(pth, ref tts) => {
                assert (vec::len(pth.idents) == 1u);
                /* using idents and token::special_idents would make the
                the macro names be hygienic */
                let extname = cx.parse_sess().interner.get(pth.idents[0]);
                match exts.find(*extname) {
                  None => {
                    cx.span_fatal(pth.span,
                                  fmt!("macro undefined: '%s'", *extname))
                  }
                  Some(NormalTT(SyntaxExpanderTT{expander: exp,
                                                 span: exp_sp})) => {
                    cx.bt_push(ExpandedFrom({call_site: s,
                                callie: {name: *extname, span: exp_sp}}));

                    let expanded = match exp(cx, (*mac).span, (*tts)) {
                      MRExpr(e) => e,
                      MRAny(expr_maker,_,_) => expr_maker(),
                      _ => cx.span_fatal(
                          pth.span, fmt!("non-expr macro in expr pos: %s",
                                         *extname))
                    };

                    //keep going, outside-in
                    let fully_expanded = fld.fold_expr(expanded).node;
                    cx.bt_pop();

                    (fully_expanded, s)
                  }
                  _ => {
                    cx.span_fatal(pth.span,
                                  fmt!("'%s' is not a tt-style macro",
                                       *extname))
                  }

                }
              }
            }
          }
          _ => orig(e, s, fld)
        };
}

// This is a secondary mechanism for invoking syntax extensions on items:
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
// attribute prefixing an item, and are interpreted by feeding the item
// through the named attribute _as a syntax extension_ and splicing in the
// resulting item vec into place in favour of the decorator. Note that
// these do _not_ work for macro extensions, just ItemDecorator ones.
//
// NB: there is some redundancy between this and expand_item, below, and
// they might benefit from some amount of semantic and language-UI merger.
fn expand_mod_items(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
                    module_: ast::_mod, fld: ast_fold,
                    orig: fn@(ast::_mod, ast_fold) -> ast::_mod)
    -> ast::_mod
{
    // Fold the contents first:
    let module_ = orig(module_, fld);

    // For each item, look through the attributes.  If any of them are
    // decorated with "item decorators", then use that function to transform
    // the item into a new set of items.
    let new_items = do vec::flat_map(module_.items) |item| {
        do vec::foldr(item.attrs, ~[*item]) |attr, items| {
            let mname = match attr.node.value.node {
              ast::meta_word(ref n) => (*n),
              ast::meta_name_value(ref n, _) => (*n),
              ast::meta_list(ref n, _) => (*n)
            };
            match exts.find(mname) {
              None | Some(NormalTT(_)) | Some(ItemTT(*)) => items,
              Some(ItemDecorator(dec_fn)) => {
                  cx.bt_push(ExpandedFrom({call_site: attr.span,
                                           callie: {name: copy mname,
                                                    span: None}}));
                  let r = dec_fn(cx, attr.span, attr.node.value, items);
                  cx.bt_pop();
                  r
              }
            }
        }
    };

    ast::_mod { items: new_items, ..module_ }
}

// When we enter a module, record it, for the sake of `module!`
fn expand_item(exts: HashMap<~str, SyntaxExtension>,
               cx: ext_ctxt, &&it: @ast::item, fld: ast_fold,
               orig: fn@(&&v: @ast::item, ast_fold) -> Option<@ast::item>)
    -> Option<@ast::item>
{
    let is_mod = match it.node {
      ast::item_mod(_) | ast::item_foreign_mod(_) => true,
      _ => false
    };
    let maybe_it = match it.node {
      ast::item_mac(*) => expand_item_mac(exts, cx, it, fld),
      _ => Some(it)
    };

    match maybe_it {
      Some(it) => {
        if is_mod { cx.mod_push(it.ident); }
        let ret_val = orig(it, fld);
        if is_mod { cx.mod_pop(); }
        return ret_val;
      }
      None => return None
    }
}

// Support for item-position macro invocations, exactly the same
// logic as for expression-position macro invocations.
fn expand_item_mac(exts: HashMap<~str, SyntaxExtension>,
                   cx: ext_ctxt, &&it: @ast::item,
                   fld: ast_fold) -> Option<@ast::item> {

    let (pth, tts) = match it.node {
        item_mac(ast::spanned { node: mac_invoc_tt(pth, ref tts), _}) => {
            (pth, (*tts))
        }
        _ => cx.span_bug(it.span, ~"invalid item macro invocation")
    };

    let extname = cx.parse_sess().interner.get(pth.idents[0]);
    let expanded = match exts.find(*extname) {
        None => cx.span_fatal(pth.span,
                              fmt!("macro undefined: '%s!'", *extname)),

        Some(NormalTT(ref expand)) => {
            if it.ident != parse::token::special_idents::invalid {
                cx.span_fatal(pth.span,
                              fmt!("macro %s! expects no ident argument, \
                                    given '%s'", *extname,
                                   *cx.parse_sess().interner.get(it.ident)));
            }
            cx.bt_push(ExpandedFrom({call_site: it.span,
                                     callie: {name: *extname,
                                              span: (*expand).span}}));
            ((*expand).expander)(cx, it.span, tts)
        }
        Some(ItemTT(ref expand)) => {
            if it.ident == parse::token::special_idents::invalid {
                cx.span_fatal(pth.span,
                              fmt!("macro %s! expects an ident argument",
                                   *extname));
            }
            cx.bt_push(ExpandedFrom({call_site: it.span,
                                     callie: {name: *extname,
                                              span: (*expand).span}}));
            ((*expand).expander)(cx, it.span, it.ident, tts)
        }
        _ => cx.span_fatal(
            it.span, fmt!("%s! is not legal in item position", *extname))
    };

    let maybe_it = match expanded {
        MRItem(it) => fld.fold_item(it),
        MRExpr(_) => cx.span_fatal(pth.span,
                                    ~"expr macro in item position: "
                                    + *extname),
        MRAny(_, item_maker, _) =>
            option::chain(item_maker(), |i| {fld.fold_item(i)}),
        MRDef(ref mdef) => {
            exts.insert((*mdef).name, (*mdef).ext);
            None
        }
    };
    cx.bt_pop();
    return maybe_it;
}

fn expand_stmt(exts: HashMap<~str, SyntaxExtension>, cx: ext_ctxt,
               && s: stmt_, sp: span, fld: ast_fold,
               orig: fn@(&&s: stmt_, span, ast_fold) -> (stmt_, span))
    -> (stmt_, span)
{

    let (mac, pth, tts, semi) = match s {
        stmt_mac(ref mac, semi) => {
            match (*mac).node {
                mac_invoc_tt(pth, ref tts) => ((*mac), pth, (*tts), semi)
            }
        }
        _ => return orig(s, sp, fld)
    };

    assert(vec::len(pth.idents) == 1u);
    let extname = cx.parse_sess().interner.get(pth.idents[0]);
    let (fully_expanded, sp) = match exts.find(*extname) {
        None =>
            cx.span_fatal(pth.span, fmt!("macro undefined: '%s'", *extname)),

        Some(NormalTT(
            SyntaxExpanderTT{expander: exp, span: exp_sp})) => {
            cx.bt_push(ExpandedFrom(
                {call_site: sp, callie: {name: *extname, span: exp_sp}}));
            let expanded = match exp(cx, mac.span, tts) {
                MRExpr(e) =>
                    @ast::spanned { node: stmt_expr(e, cx.next_id()),
                                    span: e.span},
                MRAny(_,_,stmt_mkr) => stmt_mkr(),
                _ => cx.span_fatal(
                    pth.span,
                    fmt!("non-stmt macro in stmt pos: %s", *extname))
            };

            //keep going, outside-in
            let fully_expanded = fld.fold_stmt(expanded).node;
            cx.bt_pop();

            (fully_expanded, sp)
        }

        _ => {
            cx.span_fatal(pth.span,
                          fmt!("'%s' is not a tt-style macro", *extname))
        }
    };

    return (match fully_expanded {
        stmt_expr(e, stmt_id) if semi => stmt_semi(e, stmt_id),
        _ => { fully_expanded } /* might already have a semi */
    }, sp)

}

fn new_span(cx: ext_ctxt, sp: span) -> span {
    /* this discards information in the case of macro-defining macros */
    return span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()};
}

// FIXME (#2247): this is a terrible kludge to inject some macros into
// the default compilation environment. When the macro-definition system
// is substantially more mature, these should move from here, into a
// compiled part of libcore at very least.

fn core_macros() -> ~str {
    return
~"{
    macro_rules! ignore (($($x:tt)*) => (()))

    macro_rules! error ( ($( $arg:expr ),+) => (
        log(::core::error, fmt!( $($arg),+ )) ))
    macro_rules! warn ( ($( $arg:expr ),+) => (
        log(::core::warn, fmt!( $($arg),+ )) ))
    macro_rules! info ( ($( $arg:expr ),+) => (
        log(::core::info, fmt!( $($arg),+ )) ))
    macro_rules! debug ( ($( $arg:expr ),+) => (
        log(::core::debug, fmt!( $($arg),+ )) ))

    macro_rules! die(
        ($msg: expr) => (
            ::core::sys::begin_unwind($msg, file!().to_owned(), line!())
        );
        () => (
            die!(~\"explicit failure\")
        )
    )

    macro_rules! condition (

        { $c:ident: $in:ty -> $out:ty; } => {

            mod $c {
                fn key(_x: @::core::condition::Handler<$in,$out>) { }

                pub const cond : ::core::condition::Condition<$in,$out> =
                    ::core::condition::Condition {
                    name: stringify!($c),
                    key: key
                };
            }
        }
    )

}";
}

fn expand_crate(parse_sess: parse::parse_sess,
                cfg: ast::crate_cfg, c: @crate) -> @crate {
    let exts = syntax_expander_table();
    let afp = default_ast_fold();
    let cx: ext_ctxt = mk_ctxt(parse_sess, cfg);
    let f_pre = @AstFoldFns {
        fold_expr: |a,b,c| expand_expr(exts, cx, a, b, c, afp.fold_expr),
        fold_mod: |a,b| expand_mod_items(exts, cx, a, b, afp.fold_mod),
        fold_item: |a,b| expand_item(exts, cx, a, b, afp.fold_item),
        fold_stmt: |a,b,c| expand_stmt(exts, cx, a, b, c, afp.fold_stmt),
        new_span: |a| new_span(cx, a),
        .. *afp};
    let f = make_fold(f_pre);
    let cm = parse_expr_from_source_str(~"<core-macros>",
                                        @core_macros(),
                                        cfg,
                                        parse_sess);

    // This is run for its side-effects on the expander env,
    // as it registers all the core macros as expanders.
    f.fold_expr(cm);

    let res = @f.fold_crate(*c);
    return res;
}
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>refactor(Pane): Define types for PID and Process<commit_after><|endoftext|>


<commit_before><commit_msg>Add render trait<commit_after><|endoftext|>


<commit_before><commit_msg>Ignore state pointer when reindexing.<commit_after><|endoftext|>


<commit_before><commit_msg>first test of sendable fns (passes)<commit_after>use std;

import std::comm;
import std::comm::chan;
import std::comm::send;

fn main() { test05(); }

fn test05_start(&&f: sendfn(int)) {
    f(22);
}

fn test05() {
    let three = ~3;
    let fn_to_send = sendfn(n: int) {
        log_err *three + n; // will copy x into the closure
        assert(*three == 3);
    };
    task::spawn(fn_to_send, test05_start);
}
<|endoftext|>


<commit_before>//! Tests for future-incompat-report messages

use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, is_nightly, project, Project};

// An arbitrary lint (array_into_iter) that triggers a report.
const FUTURE_EXAMPLE: &'static str = "fn main() { [true].into_iter(); }";
// Some text that will be displayed when the lint fires.
const FUTURE_OUTPUT: &'static str = "[..]array_into_iter[..]";

fn simple_project() -> Project {
    project()
        .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
        .file("src/main.rs", FUTURE_EXAMPLE)
        .build()
}

#[cargo_test]
fn no_output_on_stable() {
    let p = simple_project();

    p.cargo("build")
        .with_stderr_contains(FUTURE_OUTPUT)
        .with_stderr_does_not_contain("[..]cargo report[..]")
        .run();
}

#[cargo_test]
fn gate_future_incompat_report() {
    let p = simple_project();

    p.cargo("build --future-incompat-report")
        .with_stderr_contains("error: the `--future-incompat-report` flag is unstable[..]")
        .with_status(101)
        .run();

    // Both `-Z future-incompat-report` and `-Z unstable-opts` are required
    p.cargo("build --future-incompat-report -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stderr_contains("error: the `--future-incompat-report` flag is unstable[..]")
        .with_status(101)
        .run();

    p.cargo("build --future-incompat-report -Z unstable-options")
        .masquerade_as_nightly_cargo()
        .with_stderr_contains(
            "error: Usage of `--future-incompat-report` requires `-Z future-incompat-report`",
        )
        .with_status(101)
        .run();

    p.cargo("report future-incompatibilities --id foo")
        .with_stderr_contains("error: `cargo report` can only be used on the nightly channel")
        .with_status(101)
        .run();
}

#[cargo_test]
fn test_zero_future_incompat() {
    if !is_nightly() {
        return;
    }

    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    // No note if --future-incompat-report is not specified.
    p.cargo("build -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stderr(
            "\
[COMPILING] foo v0.0.0 [..]
[FINISHED] [..]
",
        )
        .run();

    p.cargo("build --future-incompat-report -Z unstable-options -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stderr(
            "\
[FINISHED] [..]
note: 0 dependencies had future-incompatible warnings
",
        )
        .run();
}

#[cargo_test]
#[ignore] // Waiting on https://github.com/rust-lang/rust/pull/86478
fn test_single_crate() {
    if !is_nightly() {
        return;
    }

    let p = simple_project();

    for command in &["build", "check", "rustc", "test"] {
        p.cargo(command).arg("-Zfuture-incompat-report")
            .masquerade_as_nightly_cargo()
            .with_stderr_contains(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
            .with_stderr_does_not_contain("[..]incompatibility[..]")
            .run();

        p.cargo(command).arg("-Zfuture-incompat-report").arg("-Zunstable-options").arg("--future-incompat-report")
            .masquerade_as_nightly_cargo()
            .with_stderr_contains(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
            .with_stderr_contains("The package `foo v0.0.0 ([..])` currently triggers the following future incompatibility lints:")
            .run();
    }
}

#[cargo_test]
#[ignore] // Waiting on https://github.com/rust-lang/rust/pull/86478
fn test_multi_crate() {
    if !is_nightly() {
        return;
    }

    Package::new("first-dep", "0.0.1")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("second-dep", "0.0.2")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.0"

                [dependencies]
                first-dep = "*"
                second-dep = "*"
              "#,
        )
        .file("src/main.rs", "fn main() {}")
        .build();

    for command in &["build", "check", "rustc", "test"] {
        p.cargo(command).arg("-Zfuture-incompat-report")
            .masquerade_as_nightly_cargo()
            .with_stderr_does_not_contain(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: first-dep v0.0.1, second-dep v0.0.2")
            // Check that we don't have the 'triggers' message shown at the bottom of this loop
            .with_stderr_does_not_contain("[..]triggers[..]")
            .run();

        p.cargo(command).arg("-Zunstable-options").arg("-Zfuture-incompat-report").arg("--future-incompat-report")
            .masquerade_as_nightly_cargo()
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: first-dep v0.0.1, second-dep v0.0.2")
            .with_stderr_contains("The package `first-dep v0.0.1` currently triggers the following future incompatibility lints:")
            .with_stderr_contains("The package `second-dep v0.0.2` currently triggers the following future incompatibility lints:")
            .run();
    }

    // Test that passing the correct id via '--id' doesn't generate a warning message
    let output = p
        .cargo("build -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .exec_with_output()
        .unwrap();

    // Extract the 'id' from the stdout. We are looking
    // for the id in a line of the form "run `cargo report future-incompatibilities --id yZ7S`"
    // which is generated by Cargo to tell the user what command to run
    // This is just to test that passing the id suppresses the warning mesasge. Any users needing
    // access to the report from a shell script should use the `--future-incompat-report` flag
    let stderr = std::str::from_utf8(&output.stderr).unwrap();

    // Find '--id <ID>' in the output
    let mut iter = stderr.split(' ');
    iter.find(|w| *w == "--id").unwrap();
    let id = iter
        .next()
        .unwrap_or_else(|| panic!("Unexpected output:\n{}", stderr));
    // Strip off the trailing '`' included in the output
    let id: String = id.chars().take_while(|c| *c != '`').collect();

    p.cargo(&format!("report future-incompatibilities -Z future-incompat-report --id {}", id))
        .masquerade_as_nightly_cargo()
        .with_stdout_contains("The package `first-dep v0.0.1` currently triggers the following future incompatibility lints:")
        .with_stdout_contains("The package `second-dep v0.0.2` currently triggers the following future incompatibility lints:")
        .run();

    // Test without --id, and also the full output of the report.
    let output = p
        .cargo("report future-incompat -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .exec_with_output()
        .unwrap();
    let output = std::str::from_utf8(&output.stdout).unwrap();
    assert!(output.starts_with("The following warnings were discovered"));
    let mut lines = output
        .lines()
        // Skip the beginning of the per-package information.
        .skip_while(|line| !line.starts_with("The package"));
    for expected in &["first-dep v0.0.1", "second-dep v0.0.2"] {
        assert_eq!(
            &format!(
                "The package `{}` currently triggers the following future incompatibility lints:",
                expected
            ),
            lines.next().unwrap()
        );
        let mut count = 0;
        while let Some(line) = lines.next() {
            if line.is_empty() {
                break;
            }
            count += 1;
        }
        assert!(count > 0);
    }
    assert_eq!(lines.next(), None);
}

#[cargo_test]
#[ignore] // Waiting on https://github.com/rust-lang/rust/pull/86478
fn color() {
    if !is_nightly() {
        return;
    }

    let p = simple_project();

    p.cargo("check -Zfuture-incompat-report")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stdout_does_not_contain("[..]\x1b[[..]")
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .env("CARGO_TERM_COLOR", "always")
        .with_stdout_contains("[..]\x1b[[..]")
        .run();
}

#[cargo_test]
#[ignore] // Waiting on https://github.com/rust-lang/rust/pull/86478
fn bad_ids() {
    if !is_nightly() {
        return;
    }

    let p = simple_project();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id 1")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr("error: no reports are currently available")
        .run();

    p.cargo("check -Zfuture-incompat-report")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id foo")
        .masquerade_as_nightly_cargo()
        .with_status(1)
        .with_stderr("error: Invalid value: could not parse `foo` as a number")
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id 7")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
error: could not find report with ID 7
Available IDs are: 1
",
        )
        .run();
}

#[cargo_test]
#[ignore] // Waiting on https://github.com/rust-lang/rust/pull/86478
fn suggestions_for_updates() {
    if !is_nightly() {
        return;
    }

    Package::new("with_updates", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("big_update", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("without_updates", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.1.0"

                [dependencies]
                with_updates = "1"
                big_update = "1"
                without_updates = "1"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("generate-lockfile").run();

    Package::new("with_updates", "1.0.1")
        .file("src/lib.rs", "")
        .publish();
    Package::new("with_updates", "1.0.2")
        .file("src/lib.rs", "")
        .publish();
    Package::new("big_update", "2.0.0")
        .file("src/lib.rs", "")
        .publish();

    // This is a hack to force cargo to update the index. Cargo can't do this
    // automatically because doing a network update on every build would be a
    // bad idea. Under normal circumstances, we'll hope the user has done
    // something else along the way to trigger an update (building some other
    // project or something). This could use some more consideration of how to
    // handle this better (maybe only trigger an update if it hasn't updated
    // in a long while?).
    p.cargo("update -p without_updates").run();

    p.cargo("check -Zfuture-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stderr_contains("[..]cargo report future-incompatibilities --id 1[..]")
        .run();

    p.cargo("report future-incompatibilities")
        .masquerade_as_nightly_cargo()
        .with_stdout_contains(
            "\
The following packages appear to have newer versions available.
You may want to consider updating them to a newer version to see if the issue has been fixed.

big_update v1.0.0 has the following newer versions available: 2.0.0
with_updates v1.0.0 has the following newer versions available: 1.0.1, 1.0.2
",
        )
        .run();
}
<commit_msg>Auto merge of #9698 - ehuss:enable-future-incompat, r=alexcrichton<commit_after>//! Tests for future-incompat-report messages
//!
//! Note that these tests use the -Zfuture-incompat-test for rustc.
//! This causes rustc to treat *every* lint as future-incompatible.
//! This is done because future-incompatible lints are inherently
//! ephemeral, but we don't want to continually update these tests.
//! So we pick some random lint that will likely always be the same
//! over time.

use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, is_nightly, project, Project};

// An arbitrary lint (unused_variables) that triggers a lint.
// We use a special flag to force it to generate a report.
const FUTURE_EXAMPLE: &'static str = "fn main() { let x = 1; }";
// Some text that will be displayed when the lint fires.
const FUTURE_OUTPUT: &'static str = "[..]unused_variables[..]";

fn simple_project() -> Project {
    project()
        .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
        .file("src/main.rs", FUTURE_EXAMPLE)
        .build()
}

#[cargo_test]
fn no_output_on_stable() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }
    let p = simple_project();

    p.cargo("check")
        // Even though rustc emits the report, cargo ignores it without -Z.
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .with_stderr_contains(FUTURE_OUTPUT)
        .with_stderr_does_not_contain("[..]cargo report[..]")
        .run();
}

#[cargo_test]
fn gate_future_incompat_report() {
    let p = simple_project();

    p.cargo("build --future-incompat-report")
        .with_stderr_contains("error: the `--future-incompat-report` flag is unstable[..]")
        .with_status(101)
        .run();

    // Both `-Z future-incompat-report` and `-Z unstable-opts` are required
    p.cargo("build --future-incompat-report -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stderr_contains("error: the `--future-incompat-report` flag is unstable[..]")
        .with_status(101)
        .run();

    p.cargo("build --future-incompat-report -Z unstable-options")
        .masquerade_as_nightly_cargo()
        .with_stderr_contains(
            "error: Usage of `--future-incompat-report` requires `-Z future-incompat-report`",
        )
        .with_status(101)
        .run();

    p.cargo("report future-incompatibilities --id foo")
        .with_stderr_contains("error: `cargo report` can only be used on the nightly channel")
        .with_status(101)
        .run();
}

#[cargo_test]
fn test_zero_future_incompat() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    let p = project()
        .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
        .file("src/main.rs", "fn main() {}")
        .build();

    // No note if --future-incompat-report is not specified.
    p.cargo("build -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .with_stderr(
            "\
[COMPILING] foo v0.0.0 [..]
[FINISHED] [..]
",
        )
        .run();

    p.cargo("build --future-incompat-report -Z unstable-options -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .with_stderr(
            "\
[FINISHED] [..]
note: 0 dependencies had future-incompatible warnings
",
        )
        .run();
}

#[cargo_test]
fn test_single_crate() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    let p = simple_project();

    for command in &["build", "check", "rustc", "test"] {
        p.cargo(command).arg("-Zfuture-incompat-report")
            .masquerade_as_nightly_cargo()
            .env("RUSTFLAGS", "-Zfuture-incompat-test")
            .with_stderr_contains(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
            .with_stderr_does_not_contain("[..]incompatibility[..]")
            .run();

        p.cargo(command).arg("-Zfuture-incompat-report").arg("-Zunstable-options").arg("--future-incompat-report")
            .masquerade_as_nightly_cargo()
            .env("RUSTFLAGS", "-Zfuture-incompat-test")
            .with_stderr_contains(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: foo v0.0.0 [..]")
            .with_stderr_contains("The package `foo v0.0.0 ([..])` currently triggers the following future incompatibility lints:")
            .run();
    }
}

#[cargo_test]
fn test_multi_crate() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    Package::new("first-dep", "0.0.1")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("second-dep", "0.0.2")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.0.0"

                [dependencies]
                first-dep = "*"
                second-dep = "*"
              "#,
        )
        .file("src/main.rs", "fn main() {}")
        .build();

    for command in &["build", "check", "rustc", "test"] {
        p.cargo(command).arg("-Zfuture-incompat-report")
            .masquerade_as_nightly_cargo()
            .env("RUSTFLAGS", "-Zfuture-incompat-test")
            .with_stderr_does_not_contain(FUTURE_OUTPUT)
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: first-dep v0.0.1, second-dep v0.0.2")
            // Check that we don't have the 'triggers' message shown at the bottom of this loop
            .with_stderr_does_not_contain("[..]triggers[..]")
            .run();

        p.cargo(command).arg("-Zunstable-options").arg("-Zfuture-incompat-report").arg("--future-incompat-report")
            .masquerade_as_nightly_cargo()
            .env("RUSTFLAGS", "-Zfuture-incompat-test")
            .with_stderr_contains("warning: the following packages contain code that will be rejected by a future version of Rust: first-dep v0.0.1, second-dep v0.0.2")
            .with_stderr_contains("The package `first-dep v0.0.1` currently triggers the following future incompatibility lints:")
            .with_stderr_contains("The package `second-dep v0.0.2` currently triggers the following future incompatibility lints:")
            .run();
    }

    // Test that passing the correct id via '--id' doesn't generate a warning message
    let output = p
        .cargo("build -Z future-incompat-report")
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .masquerade_as_nightly_cargo()
        .exec_with_output()
        .unwrap();

    // Extract the 'id' from the stdout. We are looking
    // for the id in a line of the form "run `cargo report future-incompatibilities --id yZ7S`"
    // which is generated by Cargo to tell the user what command to run
    // This is just to test that passing the id suppresses the warning mesasge. Any users needing
    // access to the report from a shell script should use the `--future-incompat-report` flag
    let stderr = std::str::from_utf8(&output.stderr).unwrap();

    // Find '--id <ID>' in the output
    let mut iter = stderr.split(' ');
    iter.find(|w| *w == "--id").unwrap();
    let id = iter
        .next()
        .unwrap_or_else(|| panic!("Unexpected output:\n{}", stderr));
    // Strip off the trailing '`' included in the output
    let id: String = id.chars().take_while(|c| *c != '`').collect();

    p.cargo(&format!("report future-incompatibilities -Z future-incompat-report --id {}", id))
        .masquerade_as_nightly_cargo()
        .with_stdout_contains("The package `first-dep v0.0.1` currently triggers the following future incompatibility lints:")
        .with_stdout_contains("The package `second-dep v0.0.2` currently triggers the following future incompatibility lints:")
        .run();

    // Test without --id, and also the full output of the report.
    let output = p
        .cargo("report future-incompat -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .exec_with_output()
        .unwrap();
    let output = std::str::from_utf8(&output.stdout).unwrap();
    assert!(output.starts_with("The following warnings were discovered"));
    let mut lines = output
        .lines()
        // Skip the beginning of the per-package information.
        .skip_while(|line| !line.starts_with("The package"));
    for expected in &["first-dep v0.0.1", "second-dep v0.0.2"] {
        assert_eq!(
            &format!(
                "The package `{}` currently triggers the following future incompatibility lints:",
                expected
            ),
            lines.next().unwrap()
        );
        let mut count = 0;
        while let Some(line) = lines.next() {
            if line.is_empty() {
                break;
            }
            count += 1;
        }
        assert!(count > 0);
    }
    assert_eq!(lines.next(), None);
}

#[cargo_test]
fn color() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    let p = simple_project();

    p.cargo("check -Zfuture-incompat-report")
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .with_stdout_does_not_contain("[..]\x1b[[..]")
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report")
        .masquerade_as_nightly_cargo()
        .env("CARGO_TERM_COLOR", "always")
        .with_stdout_contains("[..]\x1b[[..]")
        .run();
}

#[cargo_test]
fn bad_ids() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    let p = simple_project();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id 1")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr("error: no reports are currently available")
        .run();

    p.cargo("check -Zfuture-incompat-report")
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id foo")
        .masquerade_as_nightly_cargo()
        .with_status(1)
        .with_stderr("error: Invalid value: could not parse `foo` as a number")
        .run();

    p.cargo("report future-incompatibilities -Z future-incompat-report --id 7")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
error: could not find report with ID 7
Available IDs are: 1
",
        )
        .run();
}

#[cargo_test]
fn suggestions_for_updates() {
    if !is_nightly() {
        // -Zfuture-incompat-test requires nightly (permanently)
        return;
    }

    Package::new("with_updates", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("big_update", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();
    Package::new("without_updates", "1.0.0")
        .file("src/lib.rs", FUTURE_EXAMPLE)
        .publish();

    let p = project()
        .file(
            "Cargo.toml",
            r#"
                [package]
                name = "foo"
                version = "0.1.0"

                [dependencies]
                with_updates = "1"
                big_update = "1"
                without_updates = "1"
            "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("generate-lockfile").run();

    Package::new("with_updates", "1.0.1")
        .file("src/lib.rs", "")
        .publish();
    Package::new("with_updates", "1.0.2")
        .file("src/lib.rs", "")
        .publish();
    Package::new("big_update", "2.0.0")
        .file("src/lib.rs", "")
        .publish();

    // This is a hack to force cargo to update the index. Cargo can't do this
    // automatically because doing a network update on every build would be a
    // bad idea. Under normal circumstances, we'll hope the user has done
    // something else along the way to trigger an update (building some other
    // project or something). This could use some more consideration of how to
    // handle this better (maybe only trigger an update if it hasn't updated
    // in a long while?).
    p.cargo("update -p without_updates").run();

    p.cargo("check -Zfuture-incompat-report")
        .masquerade_as_nightly_cargo()
        .env("RUSTFLAGS", "-Zfuture-incompat-test")
        .with_stderr_contains("[..]cargo report future-incompatibilities --id 1[..]")
        .run();

    p.cargo("report future-incompatibilities")
        .masquerade_as_nightly_cargo()
        .with_stdout_contains(
            "\
The following packages appear to have newer versions available.
You may want to consider updating them to a newer version to see if the issue has been fixed.

big_update v1.0.0 has the following newer versions available: 2.0.0
with_updates v1.0.0 has the following newer versions available: 1.0.1, 1.0.2
",
        )
        .run();
}
<|endoftext|>


<commit_before><commit_msg>Add a minimal single-threaded example.<commit_after>extern crate ralloc;

#[test]
fn minimal() {
    let mut a = Box::new(1);
    let mut b = Box::new(2);
    let mut c = Box::new(3);

    assert_eq!(*a, 1);
    assert_eq!(*b, 2);
    assert_eq!(*c, 3);
}
<|endoftext|>


<commit_before><commit_msg>Added visibility example<commit_after>fn function() {
    println!("called `function()`");
}

mod my {
    // A public function
    pub fn function() {
        println!("called `my::function()`");
    }

    // A private function
    fn private_function() {
        println!("called `my::private_function()`");
    }

    // Items can access other items in the same module
    pub fn indirect_access() {
        print!("called `my::indirect_access()`, that\n> ");

        // regardless of their visibility
        private_function();
    }

    // A public module
    pub mod nested {
        pub fn function() {
            println!("called `my::nested::function()`");
        }

        #[allow(dead_code)]
        fn private_function() {
            println!("called `my::nested::private_function()`");
        }
    }

    // A private module
    mod inaccessible {
        #[allow(dead_code)]
        pub fn public_function() {
            println!("called `my::inaccessible::public_function()`");
        }
    }
}

fn main() {
    // The public items of a module can be accessed
    my::function();

    // modules allow disambiguation between items that have the same name
    function();

    // The private items of a module can't be directly accessed
    // Error! `private_function` is private
    //my::private_function();
    // TODO ^ Try uncommenting this line

    my::indirect_access();

    // Public items inside public nested modules can be accessed from outside
    // the parent module
    my::nested::function();

    // but private items inside public nested modules can't be accessed
    // Error! `private_function` is private
    //my::nested::private_function();
    // TODO ^ Try uncommenting this line

    // Items inside private nested modules can't be accessed, regardless of
    // their visibility
    // Error! `inaccessible` is a private module
    //my::inaccessible::public_function();
    // TODO ^ Try uncommenting this line
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

impl Editor {
    pub fn exec(&mut self, Inst(n, cmd): Inst) {
        use super::Mode::*;
        use super::PrimitiveMode::*;
        use super::CommandMode::*;
        match self.cursor().mode {
            Command(Normal) => match cmd {
                'i' => {
                    self.cursor_mut().mode = Mode::Primitive(PrimitiveMode::Insert(
                        InsertOptions {
                            mode: InsertMode::Insert,
                        }));

                },
                'h' => self.left(n as usize),
                'j' => self.down(n as usize),
                'k' => self.up(n as usize),
                'l' => self.right(n as usize),
                'x' => self.delete(),
                ' ' => self.next(),
                _ => {},
            },
            Primitive(Insert(_)) => {
                self.insert(cmd);
            },
        }
    }
}
<commit_msg>Add $ and 0 commands<commit_after>use super::*;
use redox::*;

impl Editor {
    pub fn exec(&mut self, Inst(n, cmd): Inst) {
        use super::Mode::*;
        use super::PrimitiveMode::*;
        use super::CommandMode::*;
        match self.cursor().mode {
            Command(Normal) => match cmd {
                'i' => {
                    self.cursor_mut().mode = Mode::Primitive(PrimitiveMode::Insert(
                        InsertOptions {
                            mode: InsertMode::Insert,
                        }));

                },
                'h' => self.left(n as usize),
                'j' => self.down(n as usize),
                'k' => self.up(n as usize),
                'l' => self.right(n as usize),
                'J' => self.down(15),
                'K' => self.up(15),
                'x' => self.delete(),
                'X' => {
                    self.previous();
                    self.delete();
                },
                '$' => self.cursor_mut().x = self.text[self.y()].len(),
                '0' => self.cursor_mut().x = 0,
                ' ' => self.next(),
                _ => {},
            },
            Primitive(Insert(_)) => {
                self.insert(cmd);
            },
        }
    }
}
<|endoftext|>


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

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Allow,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Deny,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub INACCESSIBLE_EXTERN_CRATE,
    Warn,
    "use of inaccessible extern crate erroneously allowed"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Warn,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
    Warn,
    "floating-point constants cannot be used in patterns"
}

declare_lint! {
    pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
    Warn,
    "constants of struct or enum type can only be used in a pattern if \
     the struct or enum has `#[derive(PartialEq, Eq)]`"
}

declare_lint! {
    pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
    Deny,
    "unit struct or enum variant erroneously allowed to match via path::ident(..)"
}

declare_lint! {
    pub RAW_POINTER_DERIVE,
    Warn,
    "uses of #[derive] with raw pointers are rarely correct"
}

declare_lint! {
    pub TRANSMUTE_FROM_FN_ITEM_TYPES,
    Warn,
    "transmute from function item type to pointer-sized type erroneously allowed"
}

declare_lint! {
    pub HR_LIFETIME_IN_ASSOC_TYPE,
    Warn,
    "binding for associated type references higher-ranked lifetime \
     that does not appear in the trait input types"
}

declare_lint! {
    pub OVERLAPPING_INHERENT_IMPLS,
    Warn,
    "two overlapping inherent impls define an item with the same name were erroneously allowed"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub SUPER_OR_SELF_IN_GLOBAL_PATH,
    Warn,
    "detects super or self keywords at the beginning of global path"
}

declare_lint! {
    pub UNSIZED_IN_TUPLE,
    Warn,
    "unsized types in the interior of a tuple were erroneously allowed"
}

declare_lint! {
    pub OBJECT_UNSAFE_FRAGMENT,
    Warn,
    "object-unsafe non-principal fragments in object types were erroneously allowed"
}

declare_lint! {
    pub LIFETIME_UNDERSCORE,
    Warn,
    "lifetimes or labels named `'_` were erroneously allowed"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            INACCESSIBLE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
            ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
            MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
            CONST_ERR,
            RAW_POINTER_DERIVE,
            TRANSMUTE_FROM_FN_ITEM_TYPES,
            OVERLAPPING_INHERENT_IMPLS,
            RENAMED_AND_REMOVED_LINTS,
            SUPER_OR_SELF_IN_GLOBAL_PATH,
            UNSIZED_IN_TUPLE,
            OBJECT_UNSAFE_FRAGMENT,
            HR_LIFETIME_IN_ASSOC_TYPE,
            LIFETIME_UNDERSCORE
        )
    }
}

impl LateLintPass for HardwiredLints {}
<commit_msg>Auto merge of #34923 - eddyb:deny-fn-item-transmute, r=nikomatsakis<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Allow,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Deny,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub INACCESSIBLE_EXTERN_CRATE,
    Warn,
    "use of inaccessible extern crate erroneously allowed"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Warn,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
    Warn,
    "floating-point constants cannot be used in patterns"
}

declare_lint! {
    pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
    Warn,
    "constants of struct or enum type can only be used in a pattern if \
     the struct or enum has `#[derive(PartialEq, Eq)]`"
}

declare_lint! {
    pub MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
    Deny,
    "unit struct or enum variant erroneously allowed to match via path::ident(..)"
}

declare_lint! {
    pub RAW_POINTER_DERIVE,
    Warn,
    "uses of #[derive] with raw pointers are rarely correct"
}

declare_lint! {
    pub TRANSMUTE_FROM_FN_ITEM_TYPES,
    Deny,
    "transmute from function item type to pointer-sized type erroneously allowed"
}

declare_lint! {
    pub HR_LIFETIME_IN_ASSOC_TYPE,
    Warn,
    "binding for associated type references higher-ranked lifetime \
     that does not appear in the trait input types"
}

declare_lint! {
    pub OVERLAPPING_INHERENT_IMPLS,
    Warn,
    "two overlapping inherent impls define an item with the same name were erroneously allowed"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub SUPER_OR_SELF_IN_GLOBAL_PATH,
    Warn,
    "detects super or self keywords at the beginning of global path"
}

declare_lint! {
    pub UNSIZED_IN_TUPLE,
    Warn,
    "unsized types in the interior of a tuple were erroneously allowed"
}

declare_lint! {
    pub OBJECT_UNSAFE_FRAGMENT,
    Warn,
    "object-unsafe non-principal fragments in object types were erroneously allowed"
}

declare_lint! {
    pub LIFETIME_UNDERSCORE,
    Warn,
    "lifetimes or labels named `'_` were erroneously allowed"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            INACCESSIBLE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN,
            ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
            MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
            CONST_ERR,
            RAW_POINTER_DERIVE,
            TRANSMUTE_FROM_FN_ITEM_TYPES,
            OVERLAPPING_INHERENT_IMPLS,
            RENAMED_AND_REMOVED_LINTS,
            SUPER_OR_SELF_IN_GLOBAL_PATH,
            UNSIZED_IN_TUPLE,
            OBJECT_UNSAFE_FRAGMENT,
            HR_LIFETIME_IN_ASSOC_TYPE,
            LIFETIME_UNDERSCORE
        )
    }
}

impl LateLintPass for HardwiredLints {}
<|endoftext|>


<commit_before><commit_msg>Hello world<commit_after><|endoftext|>


<commit_before>// Copyright 2012-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.

// Test that a `&mut` inside of an `&` is freezable.

struct MutSlice<'a, T> {
    data: &'a mut [T]
}

fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: uint) -> &'a T {
    &ms.data[index]
}

fn main() {
    let mut data = [1, 2, 3];
    {
        let slice = MutSlice { data: data };
        slice.data[0] += 4;
        let index0 = get(&slice, 0);
        let index1 = get(&slice, 1);
        let index2 = get(&slice, 2);
        assert_eq!(*index0, 5);
        assert_eq!(*index1, 2);
        assert_eq!(*index2, 3);
    }
    assert_eq!(data[0], 1);
    assert_eq!(data[1], 2);
    assert_eq!(data[2], 3);
}
<commit_msg>Make main pub in test case (cc #9629)<commit_after>// Copyright 2012-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.

// Test that a `&mut` inside of an `&` is freezable.

struct MutSlice<'a, T> {
    data: &'a mut [T]
}

fn get<'a, T>(ms: &'a MutSlice<'a, T>, index: uint) -> &'a T {
    &ms.data[index]
}

pub fn main() {
    let mut data = [1, 2, 3];
    {
        let slice = MutSlice { data: data };
        slice.data[0] += 4;
        let index0 = get(&slice, 0);
        let index1 = get(&slice, 1);
        let index2 = get(&slice, 2);
        assert_eq!(*index0, 5);
        assert_eq!(*index1, 2);
        assert_eq!(*index2, 3);
    }
    assert_eq!(data[0], 1);
    assert_eq!(data[1], 2);
    assert_eq!(data[2], 3);
}
<|endoftext|>


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

// Test that we can call static methods on ! both directly and when it appears in a generic

#![feature(never_type)]

trait StringifyType {
    fn stringify_type() -> &'static str;
}

impl StringifyType for ! {
    fn stringify_type() -> &'static str {
        "!"
    }
}

fn maybe_stringify<T: StringifyType>(opt: Option<T>) -> &'static str {
    match opt {
        Some(_) => T::stringify_type(),
        None => "none",
    }
}

fn main() {
    println!("! is {}", <!>::stringify_type());
    println!("None is {}", maybe_stringify(None::<!>));
}

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

// Test that we can call static methods on ! both directly and when it appears in a generic

#![feature(never_type)]

trait StringifyType {
    fn stringify_type() -> &'static str;
}

impl StringifyType for ! {
    fn stringify_type() -> &'static str {
        "!"
    }
}

fn maybe_stringify<T: StringifyType>(opt: Option<T>) -> &'static str {
    match opt {
        Some(_) => T::stringify_type(),
        None => "none",
    }
}

fn main() {
    println!("! is {}", <!>::stringify_type());
    println!("None is {}", maybe_stringify(None::<!>));
}

<|endoftext|>


<commit_before><commit_msg>Add initial rough sketches of design<commit_after>extern crate serde_derive;

use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

use chrono::{DateTime, Utc};
use clap::{App, Arg, ArgMatches, SubCommand};
use serde_derive::{Deserialize, Serialize};

#[derive(Deserialize, Debug, Clone)]
struct RepoConfig {
    path: String,
    #[serde(default = "default_false")]
    commit: bool,
    #[serde(default = "default_false")]
    sync_updates: bool,
}

fn default_false() -> bool {
    false
}

#[derive(Deserialize, Debug)]
struct Supfile {
    repo: RepoConfig,
    editor: Option<String>,
}

impl Supfile {
    pub fn from(str: &str) -> Result<Self, toml::de::Error> {
        toml::from_str(&str)
    }

    pub fn find() -> PathBuf {
        // TODO: pull in XDG crate for paths
        let default_dir = "~/.config/sup/";

        ["./", default_dir]
            .iter()
            .map(|dir| Path::new(dir).join("Supfile"))
            .find(|p| p.exists())
            .unwrap_or_else(|| {
                // TODO: offer to create path somehow
                panic!("can't find supfile")
            })
    }
}

#[derive(Deserialize, Serialize)]
enum TaskState {
    Todo,
    Partial,
    Complete,
    Canceled,
    Deferred { until: DateTime<Utc> },
}

#[derive(Deserialize, Serialize)]
enum UpdateKind {
    Note(String),
    Task(TaskState, String),
}

/// A Sup update is a supdate.
///
/// I hate this.
#[derive(Deserialize, Serialize)]
struct Supdate {
    id: String,
    timestamp: DateTime<Utc>,
    kind: UpdateKind,
    tags: Vec<String>,
}

impl Supdate {
    fn new(line: &str) -> Self {
        unimplemented!()
    }
}

struct SupdateLog {
    name: String,
    file: BufReader<File>,
}

impl SupdateLog {
    fn new(path: &Path) -> Self {
        let name = path
            .file_name()
            .expect("need file, not directory")
            .to_string_lossy()
            .into();

        let file = File::open(path).expect("could not open file");
        // TODO: Support versioning in line

        SupdateLog {
            name,
            file: BufReader::new(file),
        }
    }

    fn is_rollup(&self) -> bool {
        self.name.ends_with("0000_rollup.sup")
    }
}

impl Iterator for SupdateLog {
    type Item = Supdate;

    fn next(&mut self) -> Option<Supdate> {
        let mut line = String::new();
        return match self.file.read_line(&mut line) {
            // End of file
            Ok(0) => None,

            Ok(_) => {
                println!("line = {:?}", line);
                Some(Supdate::new(&line))
            }

            Err(e) => {
                println!("Failed to read line: {:?}", e);
                None
            }
        };
    }
}

/**
 * A Repository represents a directory containing SupdateLogs.
 *
 * The directory structure is something like this:
 *
 * repo/
 *   2019/
 *     08/
 *       20190800_rollup.sup
 *       20190801_235959.sup
 *       20190802_003030.sup
 *       20190802_123030.sup
 *
 * Rollups are special SupdateLogs which contain the collapsed content
 * of earlier entries, to put a bound on the number of entries which
 * must be read in order to construct the current state.
 */

struct Repository {
    config: RepoConfig,
}

impl Repository {
    fn new(cfg: RepoConfig) -> Self {
        // TODO: Handle error, return Result
        if !Path::new(&cfg.path).exists() {
            panic!("given repository does not exist")
        }

        Repository { config: cfg }
    }

    fn read_updates(&self) -> Vec<Supdate> {
        let file = File::open(&self.config.path).expect("");

        vec![]
    }
}

struct SupApp {
    matches: ArgMatches<'static>,
}

impl SupApp {
    fn new() -> Self {
        SupApp {
            matches: Self::parse_args(),
        }
    }

    fn parse_args<'a>() -> ArgMatches<'a> {
        App::new("sup")
            .version("0.0.0")
            .about("Keep track of what's up.")
            .arg(
                Arg::with_name("config")
                    .short("c")
                    .long("config")
                    .value_name("FILE")
                    .takes_value(true)
                    .help("Set custom location for Supfile"),
            )
            .subcommand(
                SubCommand::with_name("show")
                    .about("asdf")
                    .arg(Arg::with_name("DATE").takes_value(true).help("asdf")),
            )
            .subcommand(
                SubCommand::with_name("serve")
                    .about("launch web interface")
                    .arg(
                        Arg::with_name("port")
                            .short("p")
                            .long("port")
                            .takes_value(true),
                    ),
            )
            .get_matches()
    }

    fn load_config(&self) -> Result<Supfile, Box<dyn Error>> {
        let path = self
            .matches
            .value_of("config")
            .map(|p| Path::new(p).to_path_buf())
            .unwrap_or_else(Supfile::find);

        let bytes = std::fs::read_to_string(path.as_os_str())?;
        Ok(Supfile::from(&bytes)?)
    }

    fn run(&self) -> Result<(), Box<dyn Error>> {
        let cfg = self.load_config()?;
        let repo = Repository::new(cfg.repo.clone());

        match self.matches.subcommand() {
            ("show", Some(m)) => println!("TODO: show {:?}", m),
            ("serve", Some(m)) => println!("TODO: serve {:?}", m),
            _ => {
                println!("add update");

                run_add_update(&cfg)?;
            }
        };

        Ok(())
    }
}

fn run_add_update(_cfg: &Supfile) -> Result<(), Box<dyn Error>> {
    Ok(())
}

// TODO: Investiage this instead of Box<Error>
// https://github.com/rust-lang-nursery/failure
fn main() {
    let app = SupApp::new();
    match app.run() {
        Err(e) => println!("oh no! {:?}", e),
        Ok(_) => (),
    };
}
<|endoftext|>