Auto merge of #42964 - arielb1:rollup, r=arielb1

Rollup of 12 pull requests

- Successful merges: #42219, #42831, #42832, #42884, #42886, #42901, #42919, #42920, #42946, #42953, #42955, #42958
- Failed merges:
This commit is contained in:
bors 2017-06-29 08:40:39 +00:00
commit 7acce3724d
30 changed files with 492 additions and 188 deletions

View File

@ -171,16 +171,22 @@ before_script:
if [[ "$SKIP_BUILD" == true ]]; then
export RUN_SCRIPT="echo 'skipping, not a full build'";
else
RUN_SCRIPT="stamp src/ci/init_repo.sh . $HOME/rustsrc";
RUN_SCRIPT="src/ci/init_repo.sh . $HOME/rustsrc";
if [ "$TRAVIS_OS_NAME" = "osx" ]; then
export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/run.sh";
export RUN_SCRIPT="$RUN_SCRIPT && src/ci/run.sh";
else
export RUN_SCRIPT="$RUN_SCRIPT && stamp src/ci/docker/run.sh $IMAGE";
export RUN_SCRIPT="$RUN_SCRIPT && src/ci/docker/run.sh $IMAGE";
fi
fi
# Log time information from this machine and an external machine for insight into possible
# clock drift. Timezones don't matter since relative deltas give all the necessary info.
script:
- sh -x -c "$RUN_SCRIPT"
- >
date && curl -s --head https://google.com | grep ^Date: | sed 's/Date: //g'
- stamp sh -x -c "$RUN_SCRIPT"
- >
date && curl -s --head https://google.com | grep ^Date: | sed 's/Date: //g'
after_success:
- >

View File

@ -2,7 +2,7 @@
The tracking issue for this feature is: [#40872]
[#29599]: https://github.com/rust-lang/rust/issues/40872
[#40872]: https://github.com/rust-lang/rust/issues/40872
------------------------

View File

@ -873,7 +873,7 @@ pub unsafe trait Alloc {
{
let k = Layout::new::<T>();
if k.size() > 0 {
unsafe { self.alloc(k).map(|p|Unique::new(*p as *mut T)) }
unsafe { self.alloc(k).map(|p| Unique::new(p as *mut T)) }
} else {
Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
}

View File

@ -498,12 +498,10 @@ pub use core::fmt::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple};
use string;
/// The format function takes a precompiled format string and a list of
/// arguments, to return the resulting formatted string.
/// The `format` function takes an `Arguments` struct and returns the resulting
/// formatted string.
///
/// # Arguments
///
/// * args - a structure of arguments generated via the `format_args!` macro.
/// The `Arguments` instance can be created with the `format_args!` macro.
///
/// # Examples
///

View File

@ -379,8 +379,9 @@ impl<T: Ord> Ord for Reverse<T> {
///
/// ## Derivable
///
/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
/// ordering based on the top-to-bottom declaration order of the struct's members.
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
/// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
///
/// ## How can I implement `Ord`?
///
@ -512,8 +513,9 @@ impl PartialOrd for Ordering {
///
/// ## Derivable
///
/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
/// ordering based on the top-to-bottom declaration order of the struct's members.
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members.
/// When `derive`d on enums, variants are ordered by their top-to-bottom declaration order.
///
/// ## How can I implement `PartialOrd`?
///

View File

@ -897,14 +897,11 @@ pub trait UpperExp {
fn fmt(&self, f: &mut Formatter) -> Result;
}
/// The `write` function takes an output stream, a precompiled format string,
/// and a list of arguments. The arguments will be formatted according to the
/// specified format string into the output stream provided.
/// The `write` function takes an output stream, and an `Arguments` struct
/// that can be precompiled with the `format_args!` macro.
///
/// # Arguments
///
/// * output - the buffer to write output to
/// * args - the precompiled arguments generated by `format_args!`
/// The arguments will be formatted according to the specified format string
/// into the output stream provided.
///
/// # Examples
///

View File

@ -510,7 +510,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
}
let name = lint.name_lower();
let mut def = None;
// Except for possible note details, forbid behaves like deny.
let effective_level = if level == Forbid { Deny } else { level };
@ -525,7 +524,8 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
match source {
Default => {
err.note(&format!("#[{}({})] on by default", level.as_str(), name));
sess.diag_note_once(&mut err, lint,
&format!("#[{}({})] on by default", level.as_str(), name));
},
CommandLine(lint_flag_val) => {
let flag = match level {
@ -534,20 +534,24 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
};
let hyphen_case_lint_name = name.replace("_", "-");
if lint_flag_val.as_str() == name {
err.note(&format!("requested on the command line with `{} {}`",
flag, hyphen_case_lint_name));
sess.diag_note_once(&mut err, lint,
&format!("requested on the command line with `{} {}`",
flag, hyphen_case_lint_name));
} else {
let hyphen_case_flag_val = lint_flag_val.as_str().replace("_", "-");
err.note(&format!("`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag, hyphen_case_flag_val));
sess.diag_note_once(&mut err, lint,
&format!("`{} {}` implied by `{} {}`",
flag, hyphen_case_lint_name, flag,
hyphen_case_flag_val));
}
},
Node(lint_attr_name, src) => {
def = Some(src);
sess.diag_span_note_once(&mut err, lint, src, "lint level defined here");
if lint_attr_name.as_str() != name {
let level_str = level.as_str();
err.note(&format!("#[{}({})] implied by #[{}({})]",
level_str, name, level_str, lint_attr_name));
sess.diag_note_once(&mut err, lint,
&format!("#[{}({})] implied by #[{}({})]",
level_str, name, level_str, lint_attr_name));
}
}
}
@ -563,10 +567,6 @@ pub fn raw_struct_lint<'a, S>(sess: &'a Session,
err.note(&citation);
}
if let Some(span) = def {
sess.diag_span_note_once(&mut err, lint, span, "lint level defined here");
}
err
}

View File

@ -79,10 +79,10 @@ pub struct Session {
pub working_dir: (String, bool),
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<lint::LintTable>,
/// Set of (LintId, span, message) tuples tracking lint (sub)diagnostics
/// that have been set once, but should not be set again, in order to avoid
/// redundantly verbose output (Issue #24690).
pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Span, String)>>,
/// Set of (LintId, Option<Span>, message) tuples tracking lint
/// (sub)diagnostics that have been set once, but should not be set again,
/// in order to avoid redundantly verbose output (Issue #24690).
pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Option<Span>, String)>>,
pub plugin_llvm_passes: RefCell<Vec<String>>,
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
@ -157,6 +157,13 @@ pub struct PerfStats {
pub decode_def_path_tables_time: Cell<Duration>,
}
/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
enum DiagnosticBuilderMethod {
Note,
SpanNote,
// add more variants as needed to support one-time diagnostics
}
impl Session {
pub fn local_crate_disambiguator(&self) -> Symbol {
*self.crate_disambiguator.borrow()
@ -329,34 +336,53 @@ impl Session {
&self.parse_sess.span_diagnostic
}
/// Analogous to calling `.span_note` on the given DiagnosticBuilder, but
/// deduplicates on lint ID, span, and message for this `Session` if we're
/// not outputting in JSON mode.
//
// FIXME: if the need arises for one-time diagnostics other than
// `span_note`, we almost certainly want to generalize this
// "check/insert-into the one-time diagnostics map, then set message if
// it's not already there" code to accomodate all of them
pub fn diag_span_note_once<'a, 'b>(&'a self,
diag_builder: &'b mut DiagnosticBuilder<'a>,
lint: &'static lint::Lint, span: Span, message: &str) {
/// Analogous to calling methods on the given `DiagnosticBuilder`, but
/// deduplicates on lint ID, span (if any), and message for this `Session`
/// if we're not outputting in JSON mode.
fn diag_once<'a, 'b>(&'a self,
diag_builder: &'b mut DiagnosticBuilder<'a>,
method: DiagnosticBuilderMethod,
lint: &'static lint::Lint, message: &str, span: Option<Span>) {
let mut do_method = || {
match method {
DiagnosticBuilderMethod::Note => {
diag_builder.note(message);
},
DiagnosticBuilderMethod::SpanNote => {
diag_builder.span_note(span.expect("span_note expects a span"), message);
}
}
};
match self.opts.error_format {
// when outputting JSON for tool consumption, the tool might want
// the duplicates
config::ErrorOutputType::Json => {
diag_builder.span_note(span, &message);
do_method()
},
_ => {
let lint_id = lint::LintId::of(lint);
let id_span_message = (lint_id, span, message.to_owned());
let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
if fresh {
diag_builder.span_note(span, &message);
do_method()
}
}
}
}
pub fn diag_span_note_once<'a, 'b>(&'a self,
diag_builder: &'b mut DiagnosticBuilder<'a>,
lint: &'static lint::Lint, span: Span, message: &str) {
self.diag_once(diag_builder, DiagnosticBuilderMethod::SpanNote, lint, message, Some(span));
}
pub fn diag_note_once<'a, 'b>(&'a self,
diag_builder: &'b mut DiagnosticBuilder<'a>,
lint: &'static lint::Lint, message: &str) {
self.diag_once(diag_builder, DiagnosticBuilderMethod::Note, lint, message, None);
}
pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap {
self.parse_sess.codemap()
}

View File

@ -684,13 +684,9 @@ fn fl_lit_check_expr(cx: &EarlyContext, expr: &ast::Expr) {
// These may occur in patterns
// and can maybe contain float literals
ExprKind::Unary(_, ref f) => fl_lit_check_expr(cx, f),
// These may occur in patterns
// and can't contain float literals
ExprKind::Path(..) => (),
// If something unhandled is encountered, we need to expand the
// search or ignore more ExprKinds.
_ => span_bug!(expr.span, "Unhandled expression {:?} in float lit pattern lint",
expr.node),
// Other kinds of exprs can't occur in patterns so we don't have to check them
// (ast_validation will emit an error if they occur)
_ => (),
}
}

View File

@ -93,6 +93,17 @@ impl<'a> AstValidator<'a> {
}
}
}
/// matches '-' lit | lit (cf. parser::Parser::parse_pat_literal_maybe_minus)
fn check_expr_within_pat(&self, expr: &Expr) {
match expr.node {
ExprKind::Lit(..) | ExprKind::Path(..) => {}
ExprKind::Unary(UnOp::Neg, ref inner)
if match inner.node { ExprKind::Lit(_) => true, _ => false } => {}
_ => self.err_handler().span_err(expr.span, "arbitrary expressions aren't allowed \
in patterns")
}
}
}
impl<'a> Visitor<'a> for AstValidator<'a> {
@ -308,6 +319,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
visit::walk_generics(self, g)
}
fn visit_pat(&mut self, pat: &'a Pat) {
match pat.node {
PatKind::Lit(ref expr) => {
self.check_expr_within_pat(expr);
}
PatKind::Range(ref start, ref end, _) => {
self.check_expr_within_pat(start);
self.check_expr_within_pat(end);
}
_ => {}
}
visit::walk_pat(self, pat)
}
}
pub fn check_crate(session: &Session, krate: &Crate) {

View File

@ -769,7 +769,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
block_info.should_panic, block_info.no_run,
block_info.ignore, block_info.test_harness,
block_info.compile_fail, block_info.error_codes,
line, filename);
line, filename, block_info.allow_fail);
} else {
tests.add_old_test(text, filename);
}
@ -859,7 +859,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
block_info.should_panic, block_info.no_run,
block_info.ignore, block_info.test_harness,
block_info.compile_fail, block_info.error_codes,
line, filename);
line, filename, block_info.allow_fail);
prev_offset = offset;
}
Event::Start(Tag::Header(level)) => {
@ -889,6 +889,7 @@ struct LangString {
test_harness: bool,
compile_fail: bool,
error_codes: Vec<String>,
allow_fail: bool,
}
impl LangString {
@ -902,6 +903,7 @@ impl LangString {
test_harness: false,
compile_fail: false,
error_codes: Vec::new(),
allow_fail: false,
}
}
@ -930,6 +932,7 @@ impl LangString {
}
"no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; }
"ignore" => { data.ignore = true; seen_rust_tags = !seen_other_tags; }
"allow_fail" => { data.allow_fail = true; seen_rust_tags = !seen_other_tags; }
"rust" => { data.rust = true; seen_rust_tags = true; }
"test_harness" => {
data.test_harness = true;
@ -1118,7 +1121,7 @@ mod tests {
fn test_lang_string_parse() {
fn t(s: &str,
should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool,
compile_fail: bool, error_codes: Vec<String>) {
compile_fail: bool, allow_fail: bool, error_codes: Vec<String>) {
assert_eq!(LangString::parse(s), LangString {
should_panic: should_panic,
no_run: no_run,
@ -1128,25 +1131,31 @@ mod tests {
compile_fail: compile_fail,
error_codes: error_codes,
original: s.to_owned(),
allow_fail: allow_fail,
})
}
fn v() -> Vec<String> {
Vec::new()
}
// marker | should_panic| no_run| ignore| rust | test_harness| compile_fail
// | error_codes
t("", false, false, false, true, false, false, Vec::new());
t("rust", false, false, false, true, false, false, Vec::new());
t("sh", false, false, false, false, false, false, Vec::new());
t("ignore", false, false, true, true, false, false, Vec::new());
t("should_panic", true, false, false, true, false, false, Vec::new());
t("no_run", false, true, false, true, false, false, Vec::new());
t("test_harness", false, false, false, true, true, false, Vec::new());
t("compile_fail", false, true, false, true, false, true, Vec::new());
t("{.no_run .example}", false, true, false, true, false, false, Vec::new());
t("{.sh .should_panic}", true, false, false, false, false, false, Vec::new());
t("{.example .rust}", false, false, false, true, false, false, Vec::new());
t("{.test_harness .rust}", false, false, false, true, true, false, Vec::new());
t("text, no_run", false, true, false, false, false, false, Vec::new());
t("text,no_run", false, true, false, false, false, false, Vec::new());
// | allow_fail | error_codes
t("", false, false, false, true, false, false, false, v());
t("rust", false, false, false, true, false, false, false, v());
t("sh", false, false, false, false, false, false, false, v());
t("ignore", false, false, true, true, false, false, false, v());
t("should_panic", true, false, false, true, false, false, false, v());
t("no_run", false, true, false, true, false, false, false, v());
t("test_harness", false, false, false, true, true, false, false, v());
t("compile_fail", false, true, false, true, false, true, false, v());
t("allow_fail", false, false, false, true, false, false, true, v());
t("{.no_run .example}", false, true, false, true, false, false, false, v());
t("{.sh .should_panic}", true, false, false, false, false, false, false, v());
t("{.example .rust}", false, false, false, true, false, false, false, v());
t("{.test_harness .rust}", false, false, false, true, true, false, false, v());
t("text, no_run", false, true, false, false, false, false, false, v());
t("text,no_run", false, true, false, false, false, false, false, v());
}
#[test]

View File

@ -467,7 +467,7 @@ impl Collector {
pub fn add_test(&mut self, test: String,
should_panic: bool, no_run: bool, should_ignore: bool,
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
line: usize, filename: String) {
line: usize, filename: String, allow_fail: bool) {
let name = self.generate_name(line, &filename);
// to be removed when hoedown is removed
if self.render_type == RenderType::Pulldown {
@ -499,6 +499,7 @@ impl Collector {
ignore: should_ignore,
// compiler failures are test failures
should_panic: testing::ShouldPanic::No,
allow_fail: allow_fail,
},
testfn: testing::DynTestFn(box move |()| {
let panic = io::set_panic(None);

View File

@ -949,63 +949,9 @@ mod arch {
mod tests {
use super::*;
use iter::repeat;
use rand::{self, Rng};
use ffi::{OsString, OsStr};
use ffi::OsStr;
use path::{Path, PathBuf};
fn make_rand_name() -> OsString {
let mut rng = rand::thread_rng();
let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
.collect::<String>());
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_self_exe_path() {
@ -1017,32 +963,6 @@ mod tests {
assert!(path.is_absolute());
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = repeat("x").take(10000).collect::<String>();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| {
&*k == &*n && &*v == "VALUE"
}));
assert!(vars_os().any(|(k, v)| {
&*k == &*n && &*v == "VALUE"
}));
}
#[test]
fn test() {
assert!((!Path::new("test-path").is_absolute()));

View File

@ -276,7 +276,7 @@ impl<'a> Prefix<'a> {
/// ```
/// use std::path;
///
/// assert!(path::is_separator('/'));
/// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
/// assert!(!path::is_separator('❤'));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
@ -1499,9 +1499,9 @@ impl AsRef<OsStr> for PathBuf {
/// A slice of a path (akin to [`str`]).
///
/// This type supports a number of operations for inspecting a path, including
/// breaking the path into its components (separated by `/` or `\`, depending on
/// the platform), extracting the file name, determining whether the path is
/// absolute, and so on.
/// breaking the path into its components (separated by `/` on Unix and by either
/// `/` or `\` on Windows), extracting the file name, determining whether the path
/// is absolute, and so on.
///
/// This is an *unsized* type, meaning that it must always be used behind a
/// pointer like `&` or [`Box`]. For an owned version of this type,
@ -1520,10 +1520,11 @@ impl AsRef<OsStr> for PathBuf {
/// use std::path::Path;
/// use std::ffi::OsStr;
///
/// let path = Path::new("/tmp/foo/bar.txt");
/// // Note: this example does work on Windows
/// let path = Path::new("./foo/bar.txt");
///
/// let parent = path.parent();
/// assert_eq!(parent, Some(Path::new("/tmp/foo")));
/// assert_eq!(parent, Some(Path::new("./foo")));
///
/// let file_stem = path.file_stem();
/// assert_eq!(file_stem, Some(OsStr::new("bar")));

View File

@ -354,6 +354,9 @@ declare_features! (
// rustc internal
(active, abi_thiscall, "1.19.0", None),
// Allows a test to fail without failing the whole suite
(active, allow_fail, "1.19.0", Some(42219)),
);
declare_features! (
@ -812,6 +815,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
"used internally by rustc",
cfg_fn!(rustc_attrs))),
("allow_fail", Normal, Gated(Stability::Unstable,
"allow_fail",
"allow_fail attribute is currently unstable",
cfg_fn!(allow_fail))),
// Crate level attributes
("crate_name", CrateLevel, Ungated),
("crate_type", CrateLevel, Ungated),

View File

@ -1659,8 +1659,10 @@ impl<'a> Parser<'a> {
Ok(codemap::Spanned { node: lit, span: lo.to(self.prev_span) })
}
/// matches '-' lit | lit
/// matches '-' lit | lit (cf. ast_validation::AstValidator::check_expr_within_pat)
pub fn parse_pat_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
maybe_whole_expr!(self);
let minus_lo = self.span;
let minus_present = self.eat(&token::BinOp(token::Minus));
let lo = self.span;

View File

@ -52,7 +52,8 @@ struct Test {
path: Vec<Ident> ,
bench: bool,
ignore: bool,
should_panic: ShouldPanic
should_panic: ShouldPanic,
allow_fail: bool,
}
struct TestCtxt<'a> {
@ -133,7 +134,8 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
path: self.cx.path.clone(),
bench: is_bench_fn(&self.cx, &i),
ignore: is_ignored(&i),
should_panic: should_panic(&i, &self.cx)
should_panic: should_panic(&i, &self.cx),
allow_fail: is_allowed_fail(&i),
};
self.cx.testfns.push(test);
self.tests.push(i.ident);
@ -383,6 +385,10 @@ fn is_ignored(i: &ast::Item) -> bool {
i.attrs.iter().any(|attr| attr.check_name("ignore"))
}
fn is_allowed_fail(i: &ast::Item) -> bool {
i.attrs.iter().any(|attr| attr.check_name("allow_fail"))
}
fn should_panic(i: &ast::Item, cx: &TestCtxt) -> ShouldPanic {
match i.attrs.iter().find(|attr| attr.check_name("should_panic")) {
Some(attr) => {
@ -668,6 +674,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
}
}
};
let allow_fail_expr = ecx.expr_bool(span, test.allow_fail);
// self::test::TestDesc { ... }
let desc_expr = ecx.expr_struct(
@ -675,7 +682,8 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
test_path("TestDesc"),
vec![field("name", name_expr),
field("ignore", ignore_expr),
field("should_panic", fail_expr)]);
field("should_panic", fail_expr),
field("allow_fail", allow_fail_expr)]);
let mut visible_path = match cx.toplevel_reexport {

View File

@ -212,6 +212,7 @@ pub struct TestDesc {
pub name: TestName,
pub ignore: bool,
pub should_panic: ShouldPanic,
pub allow_fail: bool,
}
#[derive(Clone)]
@ -523,6 +524,7 @@ pub enum TestResult {
TrFailed,
TrFailedMsg(String),
TrIgnored,
TrAllowedFail,
TrMetrics(MetricMap),
TrBench(BenchSamples),
}
@ -543,6 +545,7 @@ struct ConsoleTestState<T> {
passed: usize,
failed: usize,
ignored: usize,
allowed_fail: usize,
filtered_out: usize,
measured: usize,
metrics: MetricMap,
@ -572,6 +575,7 @@ impl<T: Write> ConsoleTestState<T> {
passed: 0,
failed: 0,
ignored: 0,
allowed_fail: 0,
filtered_out: 0,
measured: 0,
metrics: MetricMap::new(),
@ -594,6 +598,10 @@ impl<T: Write> ConsoleTestState<T> {
self.write_short_result("ignored", "i", term::color::YELLOW)
}
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
self.write_short_result("FAILED (allowed)", "a", term::color::YELLOW)
}
pub fn write_metric(&mut self) -> io::Result<()> {
self.write_pretty("metric", term::color::CYAN)
}
@ -669,6 +677,7 @@ impl<T: Write> ConsoleTestState<T> {
TrOk => self.write_ok(),
TrFailed | TrFailedMsg(_) => self.write_failed(),
TrIgnored => self.write_ignored(),
TrAllowedFail => self.write_allowed_fail(),
TrMetrics(ref mm) => {
self.write_metric()?;
self.write_plain(&format!(": {}\n", mm.fmt_metrics()))
@ -702,6 +711,7 @@ impl<T: Write> ConsoleTestState<T> {
TrFailed => "failed".to_owned(),
TrFailedMsg(ref msg) => format!("failed: {}", msg),
TrIgnored => "ignored".to_owned(),
TrAllowedFail => "failed (allowed)".to_owned(),
TrMetrics(ref mm) => mm.fmt_metrics(),
TrBench(ref bs) => fmt_bench_samples(bs),
},
@ -761,7 +771,8 @@ impl<T: Write> ConsoleTestState<T> {
}
pub fn write_run_finish(&mut self) -> io::Result<bool> {
assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
assert!(self.passed + self.failed + self.ignored + self.measured +
self.allowed_fail == self.total);
if self.options.display_output {
self.write_outputs()?;
@ -778,12 +789,24 @@ impl<T: Write> ConsoleTestState<T> {
} else {
self.write_pretty("FAILED", term::color::RED)?;
}
let s = format!(". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
self.passed,
self.failed,
self.ignored,
self.measured,
self.filtered_out);
let s = if self.allowed_fail > 0 {
format!(
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out\n\n",
self.passed,
self.failed + self.allowed_fail,
self.allowed_fail,
self.ignored,
self.measured,
self.filtered_out)
} else {
format!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out\n\n",
self.passed,
self.failed,
self.ignored,
self.measured,
self.filtered_out)
};
self.write_plain(&s)?;
return Ok(success);
}
@ -891,6 +914,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
st.not_failures.push((test, stdout));
}
TrIgnored => st.ignored += 1,
TrAllowedFail => st.allowed_fail += 1,
TrMetrics(mm) => {
let tname = test.name;
let MetricMap(mm) = mm;
@ -945,12 +969,14 @@ fn should_sort_failures_before_printing_them() {
name: StaticTestName("a"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
};
let test_b = TestDesc {
name: StaticTestName("b"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
};
let mut st = ConsoleTestState {
@ -962,6 +988,7 @@ fn should_sort_failures_before_printing_them() {
passed: 0,
failed: 0,
ignored: 0,
allowed_fail: 0,
filtered_out: 0,
measured: 0,
max_name_len: 10,
@ -1471,8 +1498,13 @@ fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any + Send>>) -> Tes
.unwrap_or(false) {
TrOk
} else {
TrFailedMsg(format!("Panic did not include expected string '{}'", msg))
if desc.allow_fail {
TrAllowedFail
} else {
TrFailedMsg(format!("Panic did not include expected string '{}'", msg))
}
},
_ if desc.allow_fail => TrAllowedFail,
_ => TrFailed,
}
}
@ -1706,6 +1738,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1723,6 +1756,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1742,6 +1776,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::Yes,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1761,6 +1796,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::YesWithMessage("error message"),
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1782,6 +1818,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::YesWithMessage(expected),
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1799,6 +1836,7 @@ mod tests {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::Yes,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| f())),
};
@ -1832,6 +1870,7 @@ mod tests {
name: StaticTestName("1"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| {})),
},
@ -1840,6 +1879,7 @@ mod tests {
name: StaticTestName("2"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| {})),
}];
@ -1863,6 +1903,7 @@ mod tests {
name: StaticTestName(name),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| {}))
})
@ -1944,6 +1985,7 @@ mod tests {
name: DynTestName((*name).clone()),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move |()| testfn())),
};

View File

@ -0,0 +1,17 @@
// Copyright 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.
// check that #[allow_fail] is feature-gated
#[allow_fail] //~ ERROR allow_fail attribute is currently unstable
fn ok_to_fail() {
assert!(false);
}

View File

@ -0,0 +1,36 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
macro_rules! enum_number {
($name:ident { $($variant:ident = $value:expr, )* }) => {
enum $name {
$($variant = $value,)*
}
fn foo(value: i32) -> Option<$name> {
match value {
$( $value => Some($name::$variant), )* // PatKind::Lit
$( $value ... 42 => Some($name::$variant), )* // PatKind::Range
_ => None
}
}
}
}
enum_number!(Change {
Pos = 1,
Neg = -1,
Arith = 1 + 1, //~ ERROR arbitrary expressions aren't allowed in patterns
//~^ ERROR arbitrary expressions aren't allowed in patterns
//~^^ ERROR only char and numeric types are allowed in range patterns
});
fn main() {}

View File

@ -0,0 +1,27 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(alloc, allocator_api, heap_api, unique)]
extern crate alloc;
use alloc::heap::HeapAlloc;
use alloc::allocator::Alloc;
fn main() {
unsafe {
let ptr = HeapAlloc.alloc_one::<i32>().unwrap_or_else(|e| {
HeapAlloc.oom(e)
});
*ptr.as_ptr() = 4;
assert_eq!(*ptr.as_ptr(), 4);
HeapAlloc.dealloc_one(ptr);
}
}

98
src/test/run-pass/env.rs Normal file
View File

@ -0,0 +1,98 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --test
#![feature(rand, std_panic)]
use std::env::*;
use std::__rand as rand;
use std::__rand::Rng;
use std::iter::repeat;
use std::ffi::{OsString, OsStr};
fn make_rand_name() -> OsString {
let mut rng = rand::thread_rng();
let n = format!("TEST{}", rng.gen_ascii_chars().take(10)
.collect::<String>());
let n = OsString::from(n);
assert!(var_os(&n).is_none());
n
}
fn eq(a: Option<OsString>, b: Option<&str>) {
assert_eq!(a.as_ref().map(|s| &**s), b.map(OsStr::new).map(|s| &*s));
}
#[test]
fn test_set_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
eq(var_os(&n), Some("VALUE"));
}
#[test]
fn test_remove_var() {
let n = make_rand_name();
set_var(&n, "VALUE");
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_set_var_overwrite() {
let n = make_rand_name();
set_var(&n, "1");
set_var(&n, "2");
eq(var_os(&n), Some("2"));
set_var(&n, "");
eq(var_os(&n), Some(""));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_var_big() {
let mut s = "".to_string();
let mut i = 0;
while i < 100 {
s.push_str("aaaaaaaaaa");
i += 1;
}
let n = make_rand_name();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
}
#[test]
#[cfg_attr(target_os = "emscripten", ignore)]
fn test_env_set_get_huge() {
let n = make_rand_name();
let s = repeat("x").take(10000).collect::<String>();
set_var(&n, &s);
eq(var_os(&n), Some(&s));
remove_var(&n);
eq(var_os(&n), None);
}
#[test]
fn test_env_set_var() {
let n = make_rand_name();
let mut e = vars_os();
set_var(&n, "VALUE");
assert!(!e.any(|(k, v)| {
&*k == &*n && &*v == "VALUE"
}));
assert!(vars_os().any(|(k, v)| {
&*k == &*n && &*v == "VALUE"
}));
}

View File

@ -0,0 +1,35 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
macro_rules! enum_number {
($name:ident { $($variant:ident = $value:expr, )* }) => {
enum $name {
$($variant = $value,)*
}
fn foo(value: i32) -> Option<$name> {
match value {
$( $value => Some($name::$variant), )*
_ => None
}
}
}
}
enum_number!(Change {
Down = -1,
None = 0,
Up = 1,
});
fn main() {
if let Some(Change::Down) = foo(-1) {} else { panic!() }
}

View File

@ -0,0 +1,24 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-flags: --test
#![feature(allow_fail)]
#[test]
#[allow_fail]
fn test1() {
panic!();
}
#[test]
#[allow_fail]
fn test2() {
assert!(true);
}

View File

@ -4,12 +4,12 @@ error: function `CamelCase` should have a snake case name such as `camel_case`
14 | fn CamelCase() {}
| ^^^^^^^^^^^^^^^^^
|
= note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
note: lint level defined here
--> $DIR/lint-group-style.rs:11:9
|
11 | #![deny(bad_style)]
| ^^^^^^^^^
= note: #[deny(non_snake_case)] implied by #[deny(bad_style)]
error: function `CamelCase` should have a snake case name such as `camel_case`
--> $DIR/lint-group-style.rs:22:9
@ -17,12 +17,12 @@ error: function `CamelCase` should have a snake case name such as `camel_case`
22 | fn CamelCase() {}
| ^^^^^^^^^^^^^^^^^
|
= note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
note: lint level defined here
--> $DIR/lint-group-style.rs:20:14
|
20 | #[forbid(bad_style)]
| ^^^^^^^^^
= note: #[forbid(non_snake_case)] implied by #[forbid(bad_style)]
error: static variable `bad` should have an upper case name such as `BAD`
--> $DIR/lint-group-style.rs:24:9
@ -30,12 +30,12 @@ error: static variable `bad` should have an upper case name such as `BAD`
24 | static bad: isize = 1;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
note: lint level defined here
--> $DIR/lint-group-style.rs:20:14
|
20 | #[forbid(bad_style)]
| ^^^^^^^^^
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(bad_style)]
warning: function `CamelCase` should have a snake case name such as `camel_case`
--> $DIR/lint-group-style.rs:30:9
@ -43,12 +43,12 @@ warning: function `CamelCase` should have a snake case name such as `camel_case`
30 | fn CamelCase() {}
| ^^^^^^^^^^^^^^^^^
|
= note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
note: lint level defined here
--> $DIR/lint-group-style.rs:28:17
|
28 | #![warn(bad_style)]
| ^^^^^^^^^
= note: #[warn(non_snake_case)] implied by #[warn(bad_style)]
warning: type `snake_case` should have a camel case name such as `SnakeCase`
--> $DIR/lint-group-style.rs:32:9
@ -56,12 +56,12 @@ warning: type `snake_case` should have a camel case name such as `SnakeCase`
32 | struct snake_case;
| ^^^^^^^^^^^^^^^^^^
|
= note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
note: lint level defined here
--> $DIR/lint-group-style.rs:28:17
|
28 | #![warn(bad_style)]
| ^^^^^^^^^
= note: #[warn(non_camel_case_types)] implied by #[warn(bad_style)]
error: aborting due to previous error(s)

View File

@ -23,6 +23,4 @@ warning: function is never used: `no_parens`
20 | | return <T as ToString>::to_string(&arg);
21 | | }
| |_^
|
= note: #[warn(dead_code)] on by default

View File

@ -0,0 +1,28 @@
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> $DIR/shadowed-type-parameter.rs:30:27
|
27 | trait Bar<T> {
| - first `T` declared here
...
30 | fn shadow_in_required<T>(&self);
| ^ shadows another type parameter
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> $DIR/shadowed-type-parameter.rs:33:27
|
27 | trait Bar<T> {
| - first `T` declared here
...
33 | fn shadow_in_provided<T>(&self) {}
| ^ shadows another type parameter
error[E0194]: type parameter `T` shadows another type parameter of the same name
--> $DIR/shadowed-type-parameter.rs:18:25
|
17 | impl<T> Foo<T> {
| - first `T` declared here
18 | fn shadow_in_method<T>(&self) {}
| ^ shadows another type parameter
error: aborting due to previous error(s)

View File

@ -4,20 +4,18 @@ error: variable `theTwo` should have a snake case name such as `the_two`
19 | let theTwo = 2;
| ^^^^^^
|
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
note: lint level defined here
--> $DIR/issue-24690.rs:16:9
|
16 | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
error: variable `theOtherTwo` should have a snake case name such as `the_other_two`
--> $DIR/issue-24690.rs:20:9
|
20 | let theOtherTwo = 2;
| ^^^^^^^^^^^
|
= note: #[deny(non_snake_case)] implied by #[deny(warnings)]
error: unused variable: `theOtherTwo`
--> $DIR/issue-24690.rs:20:9
@ -25,12 +23,12 @@ error: unused variable: `theOtherTwo`
20 | let theOtherTwo = 2;
| ^^^^^^^^^^^
|
= note: #[deny(unused_variables)] implied by #[deny(warnings)]
note: lint level defined here
--> $DIR/issue-24690.rs:16:9
|
16 | #![deny(warnings)]
| ^^^^^^^^
= note: #[deny(unused_variables)] implied by #[deny(warnings)]
error: aborting due to previous error(s)

View File

@ -476,6 +476,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn
name: make_test_name(config, testpaths),
ignore: ignore,
should_panic: should_panic,
allow_fail: false,
},
testfn: make_test_closure(config, testpaths),
}