mirror of https://github.com/rust-lang/rust.git
Auto merge of #61778 - petrochenkov:pass, r=Mark-Simulacrum
compiletest: Introduce `// {check,build,run}-pass` pass modes Pass UI tests now have three modes ``` // check-pass // build-pass // run-pass ``` mirroring equivalent well-known `cargo` commands. `// check-pass` will compile the test skipping codegen (which is expensive and isn't supposed to fail in most cases). `// build-pass` will compile and link the test without running it. `// run-pass` will compile, link and run the test. Tests without a "pass" annotation are still considered "fail" tests. Most UI tests would probably want to switch to `check-pass`. Tests validating codegen would probably want to run the generated code as well and use `run-pass`. `build-pass` should probably be rare (linking tests?). https://github.com/rust-lang/rust/pull/61755 will provide a way to run the tests with any mode, e.g. bump `check-pass` tests to `run-pass` to satisfy especially suspicious people, and be able to make sure that codegen doesn't breaks in some entirely unexpected way. Tests marked with any mode are expected to pass with any other mode, if that's not the case for some legitimate reason, then the test should be made a "fail" test rather than a "pass" test. Perhaps some secondary CI can verify this invariant, but that's not super urgent. `// compile-pass` still works and is equivalent to `build-pass`. Why is `// compile-pass` bad - 1) it gives an impression that the test is only compiled, but not linked, 2) it doesn't mirror a cargo command. It can be removed some time in the future in a separate PR. cc https://github.com/rust-lang/rust/issues/61712
This commit is contained in:
commit
2cd5ed495c
|
@ -2,7 +2,7 @@
|
|||
// rustc_on_unimplemented, but with this bug we are seeing it fire (on
|
||||
// subsequent runs) if incremental compilation is enabled.
|
||||
|
||||
// revisions: rpass1 rpass2
|
||||
// revisions: cfail1 cfail2
|
||||
// compile-pass
|
||||
|
||||
#![feature(on_unimplemented)]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// seeing it fire (on subsequent runs) if incremental compilation is
|
||||
// enabled.
|
||||
|
||||
// revisions: rpass1 rpass2
|
||||
// revisions: cfail1 cfail2
|
||||
// compile-pass
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// revisions:rpass1 rpass2
|
||||
// revisions:cfail1 cfail2
|
||||
// check-pass
|
||||
// compile-flags: --crate-type cdylib
|
||||
// skip-codegen
|
||||
|
||||
#![deny(unused_attributes)]
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// compile-pass
|
||||
// error-pattern:returned Box<dyn Error> from main()
|
||||
// failure-status: 1
|
||||
|
||||
use std::error::Error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// compile-pass
|
||||
// error-pattern:returned Box<Error> from main()
|
||||
// failure-status: 1
|
||||
|
||||
use std::io::{Error, ErrorKind};
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
// Test that with the `skip-codegen` option the test isn't executed.
|
||||
|
||||
// skip-codegen
|
||||
|
||||
fn main() {
|
||||
unreachable!();
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// check-pass
|
||||
// ignore-android
|
||||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
|
@ -11,14 +12,11 @@
|
|||
// ignore-mips
|
||||
// ignore-mips64
|
||||
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#![feature(asm)]
|
||||
#![allow(dead_code, non_upper_case_globals)]
|
||||
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "x86_64"))]
|
||||
pub fn main() {
|
||||
fn main() {
|
||||
// assignment not dead
|
||||
let mut x: isize = 0;
|
||||
unsafe {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
warning: unrecognized option
|
||||
--> $DIR/asm-misplaced-option.rs:26:64
|
||||
--> $DIR/asm-misplaced-option.rs:24:64
|
||||
|
|
||||
LL | asm!("mov $1, $0" : "=r"(x) : "r"(5_usize), "0"(x) : : "cc");
|
||||
| ^^^^
|
||||
|
||||
warning: expected a clobber, found an option
|
||||
--> $DIR/asm-misplaced-option.rs:33:80
|
||||
--> $DIR/asm-misplaced-option.rs:31:80
|
||||
|
|
||||
LL | asm!("add $2, $1; mov $1, $0" : "=r"(x) : "r"(x), "r"(8_usize) : "cc", "volatile");
|
||||
| ^^^^^^^^^^
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
pub type ParseResult<T> = Result<T, ()>;
|
||||
|
||||
pub enum Item<'a> { Literal(&'a str),
|
||||
}
|
||||
pub enum Item<'a> {
|
||||
Literal(&'a str)
|
||||
}
|
||||
|
||||
pub fn colon_or_space(s: &str) -> ParseResult<&str> {
|
||||
unimplemented!()
|
||||
|
@ -20,10 +20,9 @@ pub fn parse<'a, I>(mut s: &str, items: I) -> ParseResult<()>
|
|||
macro_rules! try_consume {
|
||||
($e:expr) => ({ let (s_, v) = try!($e); s = s_; v })
|
||||
}
|
||||
let offset = try_consume!(timezone_offset_zulu(s.trim_left(), colon_or_space));
|
||||
let offset = try_consume!(timezone_offset_zulu(s.trim_left(), colon_or_space));
|
||||
let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
|
||||
let offset = try_consume!(timezone_offset_zulu(s.trim_start(), colon_or_space));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// Check that you are allowed to implement using elision but write
|
||||
// trait without elision (a bug in this cropped up during
|
||||
// bootstrapping, so this is a regression test).
|
||||
|
||||
// check-pass
|
||||
|
||||
pub struct SplitWhitespace<'a> {
|
||||
x: &'a u8
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// check-pass
|
||||
// compile-flags: --cap-lints warn
|
||||
|
||||
#![warn(unused)]
|
||||
#![deny(warnings)]
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
|
||||
use std::option; //~ WARN
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -5,7 +5,7 @@ LL | use std::option;
|
|||
| ^^^^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/bad-lint-cap3.rs:4:9
|
||||
--> $DIR/bad-lint-cap3.rs:5:9
|
||||
|
|
||||
LL | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// Here we do not get a coherence conflict because `Baz: Iterator`
|
||||
// does not hold and (due to the orphan rules), we can rely on that.
|
||||
|
||||
// check-pass
|
||||
// revisions: old re
|
||||
|
||||
#![cfg_attr(re, feature(re_rebalance_coherence))]
|
||||
#![allow(dead_code)]
|
||||
// Here we do not get a coherence conflict because `Baz: Iterator`
|
||||
// does not hold and (due to the orphan rules), we can rely on that.
|
||||
|
||||
pub trait Foo<P> {}
|
||||
|
||||
|
@ -18,5 +17,4 @@ impl Foo<i32> for Baz { }
|
|||
|
||||
impl<A:Iterator> Foo<A::Item> for A { }
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
// revisions: old re
|
||||
|
||||
#![cfg_attr(re, feature(re_rebalance_coherence))]
|
||||
|
||||
pub trait Foo<P> {}
|
||||
|
||||
pub trait Bar {
|
||||
|
@ -17,5 +17,4 @@ impl Bar for i32 {
|
|||
type Output = u32;
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
// Test that we are able to introduce a negative constraint that
|
||||
// `MyType: !MyTrait` along with other "fundamental" wrappers.
|
||||
|
||||
// check-pass
|
||||
// aux-build:coherence_copy_like_lib.rs
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
// revisions: old re
|
||||
|
||||
#![cfg_attr(re, feature(re_rebalance_coherence))]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate coherence_copy_like_lib as lib;
|
||||
|
||||
|
@ -23,5 +21,4 @@ impl<T: lib::MyCopy> MyTrait for T { }
|
|||
// Huzzah.
|
||||
impl<'a> MyTrait for lib::MyFundamentalStruct<&'a MyType> { }
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
// Test that we are able to introduce a negative constraint that
|
||||
// `MyType: !MyTrait` along with other "fundamental" wrappers.
|
||||
|
||||
// check-pass
|
||||
// aux-build:coherence_copy_like_lib.rs
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
// revisions: old re
|
||||
|
||||
#![cfg_attr(re, feature(re_rebalance_coherence))]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate coherence_copy_like_lib as lib;
|
||||
|
||||
|
@ -22,5 +20,4 @@ impl lib::MyCopy for Box<MyType> { }
|
|||
impl lib::MyCopy for lib::MyFundamentalStruct<MyType> { }
|
||||
impl lib::MyCopy for lib::MyFundamentalStruct<Box<MyType>> { }
|
||||
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
// Test that we are able to introduce a negative constraint that
|
||||
// `MyType: !MyTrait` along with other "fundamental" wrappers.
|
||||
|
||||
// check-pass
|
||||
// aux-build:coherence_copy_like_lib.rs
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
// revisions: old re
|
||||
|
||||
#![cfg_attr(re, feature(re_rebalance_coherence))]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate coherence_copy_like_lib as lib;
|
||||
|
||||
|
@ -16,5 +14,4 @@ struct MyType { x: i32 }
|
|||
// naturally, legal
|
||||
impl lib::MyCopy for MyType { }
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(dead_code)]
|
||||
// check-pass
|
||||
|
||||
#![deny(unused_attributes)] // c.f #35584
|
||||
|
||||
mod auxiliary {
|
||||
#[cfg_attr(any(), path = "nonexistent_file.rs")] pub mod namespaced_enums;
|
||||
#[cfg_attr(all(), path = "namespaced_enums.rs")] pub mod nonexistent_file;
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let _ = auxiliary::namespaced_enums::Foo::A;
|
||||
let _ = auxiliary::nonexistent_file::Foo::A;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// compile-pass
|
||||
// run-pass
|
||||
|
||||
#![feature(const_fn_union)]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// compile-pass
|
||||
// run-pass
|
||||
|
||||
enum Foo {
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
// Test use of const fn from another crate without a feature gate.
|
||||
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(unused_variables)]
|
||||
// check-pass
|
||||
// aux-build:const_fn_lib.rs
|
||||
|
||||
extern crate const_fn_lib;
|
||||
|
||||
use const_fn_lib::foo;
|
||||
|
||||
|
||||
fn main() {
|
||||
let x = foo(); // use outside a constant is ok
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// skip-codegen
|
||||
// compile-pass
|
||||
// check-pass
|
||||
|
||||
macro_rules! mac {
|
||||
{} => {
|
||||
|
@ -19,5 +18,4 @@ macro_rules! mac {
|
|||
|
||||
mac! {}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
// inputs are handled by each, and (2.) to ease searching for related
|
||||
// occurrences in the source text.
|
||||
|
||||
// check-pass
|
||||
|
||||
#![warn(unused_attributes, unknown_lints)]
|
||||
#![allow(stable_features)]
|
||||
|
||||
// UNGATED WHITE-LISTED BUILT-IN ATTRIBUTES
|
||||
|
||||
|
@ -75,7 +76,7 @@
|
|||
// see issue-43106-gating-of-stable.rs
|
||||
// see issue-43106-gating-of-unstable.rs
|
||||
// see issue-43106-gating-of-deprecated.rs
|
||||
#![windows_subsystem = "1000"]
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
// UNGATED CRATE-LEVEL BUILT-IN ATTRIBUTES
|
||||
|
||||
|
@ -539,7 +540,7 @@ mod export_name {
|
|||
#[export_name = "2200"] impl S { }
|
||||
}
|
||||
|
||||
// Note that this test has a `skip-codegen`, so it
|
||||
// Note that this is a `check-pass` test, so it
|
||||
// will never invoke the linker. These are here nonetheless to point
|
||||
// out that we allow them at non-crate-level (though I do not know
|
||||
// whether they have the same effect here as at crate-level).
|
||||
|
@ -611,17 +612,17 @@ mod must_use {
|
|||
#[must_use] impl S { }
|
||||
}
|
||||
|
||||
#[windows_subsystem = "1000"]
|
||||
#[windows_subsystem = "windows"]
|
||||
mod windows_subsystem {
|
||||
mod inner { #![windows_subsystem="1000"] }
|
||||
mod inner { #![windows_subsystem="windows"] }
|
||||
|
||||
#[windows_subsystem = "1000"] fn f() { }
|
||||
#[windows_subsystem = "windows"] fn f() { }
|
||||
|
||||
#[windows_subsystem = "1000"] struct S;
|
||||
#[windows_subsystem = "windows"] struct S;
|
||||
|
||||
#[windows_subsystem = "1000"] type T = S;
|
||||
#[windows_subsystem = "windows"] type T = S;
|
||||
|
||||
#[windows_subsystem = "1000"] impl S { }
|
||||
#[windows_subsystem = "windows"] impl S { }
|
||||
}
|
||||
|
||||
// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,8 +5,7 @@
|
|||
//
|
||||
// (For non-crate-level cases, see issue-43106-gating-of-builtin-attrs.rs)
|
||||
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
#![deprecated]
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
mod foo {
|
||||
pub use bar::*;
|
||||
pub use main as f;
|
||||
|
@ -15,5 +15,4 @@ mod baz {
|
|||
pub use super::*;
|
||||
}
|
||||
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro, associated_type_defaults)]
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
|
||||
trait Base {
|
||||
type AssocTy;
|
||||
fn f();
|
||||
|
@ -35,5 +35,4 @@ macro mac() {
|
|||
|
||||
mac!();
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
// This used to ICE because the "if" being unreachable was not handled correctly
|
||||
fn err() {
|
||||
if loop {} {}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// check-pass
|
||||
// aux-build:import_crate_var.rs
|
||||
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#[macro_use] extern crate import_crate_var;
|
||||
|
||||
|
||||
fn main() {
|
||||
m!();
|
||||
//~^ WARN `$crate` may not be imported
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
warning: `$crate` may not be imported
|
||||
--> $DIR/import-crate-var.rs:9:5
|
||||
--> $DIR/import-crate-var.rs:7:5
|
||||
|
|
||||
LL | m!();
|
||||
| ^^^^^
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
struct Attr {
|
||||
name: String,
|
||||
value: String,
|
||||
|
@ -21,7 +20,6 @@ impl Element {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let element = Element { attrs: Vec::new() };
|
||||
let _ = unsafe { element.get_attr("foo") };
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
fn cb<'a,T>(_x: Box<dyn Fn((&'a i32, &'a (Vec<&'static i32>, bool))) -> T>) -> T {
|
||||
panic!()
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
cb(Box::new(|(k, &(ref v, b))| (*k, v.clone(), b)));
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
trait A<T> {}
|
||||
struct B<T> where B<T>: A<B<T>> { t: T }
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// skip-codegen
|
||||
// compile-pass
|
||||
// check-pass
|
||||
|
||||
#![feature(unboxed_closures, fn_traits)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl<A> FnOnce<(A,)> for Foo {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
#![feature(unboxed_closures, fn_traits)]
|
||||
|
||||
fn main() {
|
||||
let k = |x: i32| { x + 1 };
|
||||
Fn::call(&k, (0,));
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
struct CNFParser {
|
||||
token: char,
|
||||
}
|
||||
|
@ -14,12 +13,11 @@ impl CNFParser {
|
|||
self.consume_while(&(CNFParser::is_whitespace))
|
||||
}
|
||||
|
||||
fn consume_while(&mut self, p: &Fn(char) -> bool) {
|
||||
fn consume_while(&mut self, p: &dyn Fn(char) -> bool) {
|
||||
while p(self.token) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
mod a {
|
||||
pub mod b { pub struct Foo; }
|
||||
|
||||
|
@ -11,7 +11,6 @@ mod a {
|
|||
pub use self::c::*;
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let _ = a::c::Bar(a::b::Foo);
|
||||
let _ = a::Bar(a::b::Foo);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
trait Mirror {
|
||||
type It;
|
||||
}
|
||||
|
@ -9,8 +8,6 @@ impl<T> Mirror for T {
|
|||
type It = Self;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
let c: <u32 as Mirror>::It = 5;
|
||||
const CCCC: <u32 as Mirror>::It = 5;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(unused)]
|
||||
// check-pass
|
||||
|
||||
extern crate core;
|
||||
use core as core_export;
|
||||
use self::x::*;
|
||||
mod x {}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
@ -17,5 +16,4 @@ pub trait Bar {
|
|||
|
||||
impl<T: 'static, W: Bar<Output = T>> Foo<*mut T> for W {}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![deny(non_snake_case)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn SparklingGenerationForeignFunctionInterface() {}
|
||||
// check-pass
|
||||
|
||||
#![deny(non_snake_case)]
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn SparklingGenerationForeignFunctionInterface() {} // OK
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(dead_code)]
|
||||
// check-pass
|
||||
|
||||
pub type T = ();
|
||||
mod foo { pub use super::T; }
|
||||
mod bar { pub use super::T; }
|
||||
|
@ -15,5 +14,4 @@ mod baz {
|
|||
pub use self::bar::*;
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
mod foo {
|
||||
pub fn bar() {}
|
||||
|
@ -21,5 +19,4 @@ mod b {
|
|||
pub use a::bar;
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
pub use bar::*;
|
||||
mod bar {
|
||||
|
@ -11,5 +10,4 @@ mod baz {
|
|||
pub use main as f;
|
||||
}
|
||||
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
macro_rules! foo { () => {
|
||||
let x = 1;
|
||||
|
@ -22,7 +20,6 @@ macro_rules! baz {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
foo! {};
|
||||
bar! {};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
use std::fmt;
|
||||
|
||||
|
@ -7,7 +6,6 @@ use std::fmt;
|
|||
// an unsized tuple by transmuting a trait object.
|
||||
fn any<T>() -> T { unreachable!() }
|
||||
|
||||
|
||||
fn main() {
|
||||
let t: &(u8, dyn fmt::Debug) = any();
|
||||
println!("{:?}", &t.1);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
macro_rules! m {
|
||||
() => { #[cfg(any())] fn f() {} }
|
||||
|
@ -8,5 +7,4 @@ macro_rules! m {
|
|||
trait T {}
|
||||
impl T for () { m!(); }
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
macro_rules! null { ($i:tt) => {} }
|
||||
macro_rules! apply_null {
|
||||
($i:item) => { null! { $i } }
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
apply_null!(#[cfg(all())] fn f() {});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(unused)]
|
||||
// check-pass
|
||||
|
||||
macro_rules! make_item {
|
||||
() => { fn f() {} }
|
||||
|
@ -18,5 +16,4 @@ fn g() {
|
|||
make_stmt! {}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(dead_code)]
|
||||
// check-pass
|
||||
|
||||
trait RegularExpression: Sized {
|
||||
type Text;
|
||||
|
@ -18,5 +16,4 @@ enum FindCapturesInner<'r, 't> {
|
|||
Dynamic(FindCaptures<'t, ExecNoSyncStr<'r>>),
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -25,7 +24,6 @@ fn foo<'a>(x: &'a ()) -> <() as Lifetime<'a>>::Out {
|
|||
fn takes_lifetime(_f: for<'a> fn(&'a ()) -> <() as Lifetime<'a>>::Out) {
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
takes_lifetime(foo);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
// Unnecessary path disambiguator is ok
|
||||
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(unused)]
|
||||
// check-pass
|
||||
|
||||
macro_rules! m {
|
||||
($p: path) => {
|
||||
let _ = $p(0);
|
||||
|
@ -23,5 +22,4 @@ fn f() {
|
|||
m!(S::<u8>);
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
fn _test() -> impl Default { }
|
||||
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
pub trait Foo {
|
||||
type Bar;
|
||||
|
@ -17,7 +16,6 @@ impl<T> Broken for T {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let _m: &dyn Broken<Assoc=()> = &();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
#![feature(associated_type_defaults)]
|
||||
#![allow(warnings)]
|
||||
|
||||
trait State: Sized {
|
||||
type NextState: State = StateMachineEnded;
|
||||
fn execute(self) -> Option<Self::NextState>;
|
||||
|
@ -15,6 +15,4 @@ impl State for StateMachineEnded {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// check-pass
|
||||
// ignore-emscripten
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
macro_rules! interrupt_handler {
|
||||
|
@ -12,6 +12,4 @@ macro_rules! interrupt_handler {
|
|||
}
|
||||
interrupt_handler!{}
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
fn foo(_: &mut i32) -> bool { true }
|
||||
|
||||
|
||||
fn main() {
|
||||
let opt = Some(92);
|
||||
let mut x = 62;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// skip-codegen
|
||||
// compile-pass
|
||||
// check-pass
|
||||
|
||||
#![warn(unused)]
|
||||
|
||||
type Z = dyn for<'x> Send;
|
||||
//~^ WARN type alias is never used
|
||||
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![feature(associated_consts)]
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
trait MyTrait {
|
||||
const MY_CONST: &'static str;
|
||||
}
|
||||
|
@ -18,5 +16,4 @@ macro_rules! my_macro {
|
|||
|
||||
my_macro!();
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
|
||||
fn main() {
|
||||
let _x: fn(&i32) -> <&i32 as Deref>::Target = unimplemented!();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
#![allow(warnings)]
|
||||
// check-pass
|
||||
|
||||
enum E {
|
||||
A = {
|
||||
|
@ -9,5 +7,4 @@ enum E {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// Basic test for free regions in the NLL code. This test does not
|
||||
// report an error because of the (implied) bound that `'b: 'a`.
|
||||
|
||||
// check-pass
|
||||
// compile-flags:-Zborrowck=mir -Zverbose
|
||||
// compile-pass
|
||||
// skip-codegen
|
||||
|
||||
fn foo<'a, 'b>(x: &'a &'b u32) -> &'a u32 {
|
||||
&**x
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// compile-pass
|
||||
// skip-codegen
|
||||
// check-pass
|
||||
|
||||
#![deny(unreachable_patterns)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
#![feature(never_type)]
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
// compile-pass
|
||||
|
||||
#![deny(single_use_lifetimes)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
// Test that we DO NOT warn when lifetime name is used only
|
||||
// once in a fn return type -- using `'_` is not legal there,
|
||||
// as it must refer back to an argument.
|
||||
//
|
||||
// (Normally, using `'static` would be preferred, but there are
|
||||
// times when that is not what you want.)
|
||||
//
|
||||
// run-pass
|
||||
|
||||
// compile-pass
|
||||
|
||||
#![deny(single_use_lifetimes)]
|
||||
|
||||
fn b<'a>() -> &'a u32 { // OK: used only in return type
|
||||
&22
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
fn main() {}
|
||||
|
|
|
@ -290,6 +290,13 @@ impl EarlyProps {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum PassMode {
|
||||
Check,
|
||||
Build,
|
||||
Run,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TestProps {
|
||||
// Lines that should be expected, in order, on standard out
|
||||
|
@ -349,14 +356,10 @@ pub struct TestProps {
|
|||
// testing harness and used when generating compilation
|
||||
// arguments. (In particular, it propagates to the aux-builds.)
|
||||
pub incremental_dir: Option<PathBuf>,
|
||||
// Specifies that a test must actually compile without errors.
|
||||
pub compile_pass: bool,
|
||||
// How far should the test proceed while still passing.
|
||||
pub pass_mode: Option<PassMode>,
|
||||
// rustdoc will test the output of the `--test` option
|
||||
pub check_test_line_numbers_match: bool,
|
||||
// The test must be compiled and run successfully. Only used in UI tests for now.
|
||||
pub run_pass: bool,
|
||||
// Skip any codegen step and running the executable. Only for run-pass.
|
||||
pub skip_codegen: bool,
|
||||
// Do not pass `-Z ui-testing` to UI tests
|
||||
pub disable_ui_testing_normalization: bool,
|
||||
// customized normalization rules
|
||||
|
@ -396,10 +399,8 @@ impl TestProps {
|
|||
pretty_compare_only: false,
|
||||
forbid_output: vec![],
|
||||
incremental_dir: None,
|
||||
compile_pass: false,
|
||||
pass_mode: None,
|
||||
check_test_line_numbers_match: false,
|
||||
run_pass: false,
|
||||
skip_codegen: false,
|
||||
disable_ui_testing_normalization: false,
|
||||
normalize_stdout: vec![],
|
||||
normalize_stderr: vec![],
|
||||
|
@ -525,18 +526,7 @@ impl TestProps {
|
|||
self.check_test_line_numbers_match = config.parse_check_test_line_numbers_match(ln);
|
||||
}
|
||||
|
||||
if !self.run_pass {
|
||||
self.run_pass = config.parse_run_pass(ln);
|
||||
}
|
||||
|
||||
if !self.compile_pass {
|
||||
// run-pass implies compile_pass
|
||||
self.compile_pass = config.parse_compile_pass(ln) || self.run_pass;
|
||||
}
|
||||
|
||||
if !self.skip_codegen {
|
||||
self.skip_codegen = config.parse_skip_codegen(ln);
|
||||
}
|
||||
self.update_pass_mode(ln, cfg, config);
|
||||
|
||||
if !self.disable_ui_testing_normalization {
|
||||
self.disable_ui_testing_normalization =
|
||||
|
@ -583,6 +573,41 @@ impl TestProps {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
|
||||
let check_no_run = |s| {
|
||||
if config.mode != Mode::Ui && config.mode != Mode::Incremental {
|
||||
panic!("`{}` header is only supported in UI and incremental tests", s);
|
||||
}
|
||||
if config.mode == Mode::Incremental &&
|
||||
!revision.map_or(false, |r| r.starts_with("cfail")) &&
|
||||
!self.revisions.iter().all(|r| r.starts_with("cfail")) {
|
||||
panic!("`{}` header is only supported in `cfail` incremental tests", s);
|
||||
}
|
||||
};
|
||||
let pass_mode = if config.parse_name_directive(ln, "check-pass") {
|
||||
check_no_run("check-pass");
|
||||
Some(PassMode::Check)
|
||||
} else if config.parse_name_directive(ln, "build-pass") {
|
||||
check_no_run("build-pass");
|
||||
Some(PassMode::Build)
|
||||
} else if config.parse_name_directive(ln, "compile-pass") /* compatibility */ {
|
||||
check_no_run("compile-pass");
|
||||
Some(PassMode::Build)
|
||||
} else if config.parse_name_directive(ln, "run-pass") {
|
||||
if config.mode != Mode::Ui && config.mode != Mode::RunPass /* compatibility */ {
|
||||
panic!("`run-pass` header is only supported in UI tests")
|
||||
}
|
||||
Some(PassMode::Run)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
match (self.pass_mode, pass_mode) {
|
||||
(None, Some(_)) => self.pass_mode = pass_mode,
|
||||
(Some(_), Some(_)) => panic!("multiple `*-pass` headers in a single test"),
|
||||
(_, None) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
|
||||
|
@ -710,10 +735,6 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_compile_pass(&self, line: &str) -> bool {
|
||||
self.parse_name_directive(line, "compile-pass")
|
||||
}
|
||||
|
||||
fn parse_disable_ui_testing_normalization(&self, line: &str) -> bool {
|
||||
self.parse_name_directive(line, "disable-ui-testing-normalization")
|
||||
}
|
||||
|
@ -722,14 +743,6 @@ impl Config {
|
|||
self.parse_name_directive(line, "check-test-line-numbers-match")
|
||||
}
|
||||
|
||||
fn parse_run_pass(&self, line: &str) -> bool {
|
||||
self.parse_name_directive(line, "run-pass")
|
||||
}
|
||||
|
||||
fn parse_skip_codegen(&self, line: &str) -> bool {
|
||||
self.parse_name_directive(line, "skip-codegen")
|
||||
}
|
||||
|
||||
fn parse_assembly_output(&self, line: &str) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "assembly-output")
|
||||
.map(|r| r.trim().to_string())
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::common::{Config, TestPaths};
|
|||
use crate::common::{Incremental, MirOpt, RunMake, Ui, JsDocTest, Assembly};
|
||||
use diff;
|
||||
use crate::errors::{self, Error, ErrorKind};
|
||||
use crate::header::TestProps;
|
||||
use crate::header::{TestProps, PassMode};
|
||||
use crate::json;
|
||||
use regex::{Captures, Regex};
|
||||
use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
|
||||
|
@ -310,20 +310,19 @@ impl<'test> TestCx<'test> {
|
|||
}
|
||||
|
||||
fn should_run_successfully(&self) -> bool {
|
||||
let run_pass = match self.config.mode {
|
||||
match self.config.mode {
|
||||
RunPass => true,
|
||||
Ui => self.props.run_pass,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
return run_pass && !self.props.skip_codegen;
|
||||
Ui => self.props.pass_mode == Some(PassMode::Run),
|
||||
mode => panic!("unimplemented for mode {:?}", mode),
|
||||
}
|
||||
}
|
||||
|
||||
fn should_compile_successfully(&self) -> bool {
|
||||
match self.config.mode {
|
||||
CompileFail => self.props.compile_pass,
|
||||
CompileFail => false,
|
||||
RunPass => true,
|
||||
JsDocTest => true,
|
||||
Ui => self.props.compile_pass,
|
||||
Ui => self.props.pass_mode.is_some(),
|
||||
Incremental => {
|
||||
let revision = self.revision
|
||||
.expect("incremental tests require a list of revisions");
|
||||
|
@ -331,7 +330,7 @@ impl<'test> TestCx<'test> {
|
|||
true
|
||||
} else if revision.starts_with("cfail") {
|
||||
// FIXME: would be nice if incremental revs could start with "cpass"
|
||||
self.props.compile_pass
|
||||
self.props.pass_mode.is_some()
|
||||
} else {
|
||||
panic!("revision name must begin with rpass, rfail, or cfail");
|
||||
}
|
||||
|
@ -433,11 +432,9 @@ impl<'test> TestCx<'test> {
|
|||
"run-pass tests with expected warnings should be moved to ui/"
|
||||
);
|
||||
|
||||
if !self.props.skip_codegen {
|
||||
let proc_res = self.exec_compiled_test();
|
||||
if !proc_res.status.success() {
|
||||
self.fatal_proc_rec("test run failed!", &proc_res);
|
||||
}
|
||||
let proc_res = self.exec_compiled_test();
|
||||
if !proc_res.status.success() {
|
||||
self.fatal_proc_rec("test run failed!", &proc_res);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1341,7 @@ impl<'test> TestCx<'test> {
|
|||
fn check_error_patterns(&self, output_to_check: &str, proc_res: &ProcRes) {
|
||||
debug!("check_error_patterns");
|
||||
if self.props.error_patterns.is_empty() {
|
||||
if self.props.compile_pass {
|
||||
if self.props.pass_mode.is_some() {
|
||||
return;
|
||||
} else {
|
||||
self.fatal(&format!(
|
||||
|
@ -1971,7 +1968,7 @@ impl<'test> TestCx<'test> {
|
|||
}
|
||||
}
|
||||
|
||||
if self.props.skip_codegen {
|
||||
if self.props.pass_mode == Some(PassMode::Check) {
|
||||
assert!(
|
||||
!self
|
||||
.props
|
||||
|
|
Loading…
Reference in New Issue