From e8b6d3cc9ebec76b63a2f4d6b54d8eae58f07c5f Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 8 Jan 2017 02:48:37 +0100 Subject: [PATCH 1/9] Use only one feature struct, and use hash maps in both occasions --- src/tools/tidy/src/features.rs | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index ac5dff0980c08..3c62bb83b402d 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -39,14 +39,7 @@ impl fmt::Display for Status { } } - struct Feature { - name: String, - level: Status, - since: String, -} - -struct LibFeature { level: Status, since: String, } @@ -54,7 +47,7 @@ struct LibFeature { pub fn check(path: &Path, bad: &mut bool) { let features = collect_lang_features(&path.join("libsyntax/feature_gate.rs")); assert!(!features.is_empty()); - let mut lib_features = HashMap::::new(); + let mut lib_features = HashMap::::new(); let mut contents = String::new(); super::walk(path, @@ -97,7 +90,7 @@ pub fn check(path: &Path, bad: &mut bool) { None => "None", }; - if features.iter().any(|f| f.name == feature_name) { + if features.contains_key(feature_name) { err("duplicating a lang feature"); } if let Some(ref s) = lib_features.get(feature_name) { @@ -110,7 +103,7 @@ pub fn check(path: &Path, bad: &mut bool) { continue; } lib_features.insert(feature_name.to_owned(), - LibFeature { + Feature { level: level, since: since.to_owned(), }); @@ -122,9 +115,9 @@ pub fn check(path: &Path, bad: &mut bool) { } let mut lines = Vec::new(); - for feature in features { + for (name, feature) in features { lines.push(format!("{:<32} {:<8} {:<12} {:<8}", - feature.name, + name, "lang", feature.level, feature.since)); @@ -150,7 +143,7 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { .map(|(i, j)| &line[i..j]) } -fn collect_lang_features(path: &Path) -> Vec { +fn collect_lang_features(path: &Path) -> HashMap { let mut contents = String::new(); t!(t!(File::open(path)).read_to_string(&mut contents)); @@ -165,11 +158,11 @@ fn collect_lang_features(path: &Path) -> Vec { }; let name = parts.next().unwrap().trim(); let since = parts.next().unwrap().trim().trim_matches('"'); - Some(Feature { - name: name.to_owned(), - level: level, - since: since.to_owned(), - }) + Some((name.to_owned(), + Feature { + level: level, + since: since.to_owned(), + })) }) .collect() } From a13cecacb4f3ffd6faae2080046078ff53748815 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 8 Jan 2017 03:24:40 +0100 Subject: [PATCH 2/9] Require compile-fail tests for new lang features Its non trivial to test lang feature gates, and people forget to add such tests. So we extend the features lint of the tidy tool to ensure that all new lang features contain a new compile-fail test. Of course, one could drop this requirement and just grep all tests in run-pass for #![feature(abc)] and then run this test again, removing the mention, requiring that it fails. But this only tests for the existence of a compilation failure. Manual tests ensure that also the correct lines spawn the error, and also test the actual error message. For library features, it makes no sense to require such a test, as here code is used that is generic for all library features. --- src/tools/tidy/src/features.rs | 72 +++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 3c62bb83b402d..290a1d9facb30 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,6 +16,7 @@ //! * The set of library features is disjoint from the set of language features //! * Library features have at most one stability level //! * Library features have at most one `since` value +//! * All stability attributes have tests to ensure they are actually stable/unstable use std::collections::HashMap; use std::fmt; @@ -42,10 +43,11 @@ impl fmt::Display for Status { struct Feature { level: Status, since: String, + has_gate_test: bool, } pub fn check(path: &Path, bad: &mut bool) { - let features = collect_lang_features(&path.join("libsyntax/feature_gate.rs")); + let mut features = collect_lang_features(&path.join("libsyntax/feature_gate.rs")); assert!(!features.is_empty()); let mut lib_features = HashMap::::new(); @@ -106,10 +108,77 @@ pub fn check(path: &Path, bad: &mut bool) { Feature { level: level, since: since.to_owned(), + has_gate_test: false, }); } }); + super::walk(&path.join("test/compile-fail"), + &mut |path| super::filter_dirs(path), + &mut |file| { + let filename = file.file_name().unwrap().to_string_lossy(); + if !filename.ends_with(".rs") || filename == "features.rs" || + filename == "diagnostic_list.rs" { + return; + } + + contents.truncate(0); + t!(t!(File::open(&file), &file).read_to_string(&mut contents)); + + for (i, line) in contents.lines().enumerate() { + let mut err = |msg: &str| { + println!("{}:{}: {}", file.display(), i + 1, msg); + *bad = true; + }; + + let gate_test_str = "gate-test-"; + + if !line.contains(gate_test_str) { + continue; + } + + let feature_name = match line.find(gate_test_str) { + Some(i) => { + &line[i+gate_test_str.len()..line[i+1..].find(' ').unwrap_or(line.len())] + }, + None => continue, + }; + let found_feature = features.get_mut(feature_name) + .map(|v| { v.has_gate_test = true; () }) + .is_some(); + + let found_lib_feature = features.get_mut(feature_name) + .map(|v| { v.has_gate_test = true; () }) + .is_some(); + + if !(found_feature || found_lib_feature) { + err(&format!("gate-test test found referencing a nonexistent feature '{}'", + feature_name)); + } + } + }); + + // Only check the number of lang features. + // Obligatory testing for library features is dumb. + let gate_untested = features.iter() + .filter(|&(_, f)| f.level == Status::Unstable) + .filter(|&(_, f)| !f.has_gate_test) + .count(); + + // FIXME get this number down to zero. + let gate_untested_expected = 98; + + if gate_untested != gate_untested_expected { + print!("Expected {} gate untested features, but found {}. ", + gate_untested_expected, gate_untested); + if gate_untested < gate_untested_expected { + println!("Did you forget to reduce the expected number?"); + } else { + println!("Did you forget to add a gate test for your new feature?"); + } + *bad = true; + } + if *bad { return; } @@ -162,6 +231,7 @@ fn collect_lang_features(path: &Path) -> HashMap { Feature { level: level, since: since.to_owned(), + has_gate_test: false, })) }) .collect() From 0bcd3b2e7903ef3664176133544fe11af6fcdfb3 Mon Sep 17 00:00:00 2001 From: est31 Date: Sun, 8 Jan 2017 03:57:27 +0100 Subject: [PATCH 3/9] Add gate-test- to some already existing tests --- src/test/compile-fail/gated-attr-literals.rs | 2 ++ src/test/compile-fail/gated-naked_functions.rs | 2 ++ src/test/compile-fail/never-disabled.rs | 2 ++ src/test/compile-fail/unadjusted-unstable.rs | 2 ++ src/tools/tidy/src/features.rs | 2 +- 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/gated-attr-literals.rs b/src/test/compile-fail/gated-attr-literals.rs index f3132d5593e62..04abc44caecd7 100644 --- a/src/test/compile-fail/gated-attr-literals.rs +++ b/src/test/compile-fail/gated-attr-literals.rs @@ -10,6 +10,8 @@ // Check that literals in attributes don't parse without the feature gate. +// gate-test-attr_literals + #![feature(rustc_attrs)] #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/compile-fail/gated-naked_functions.rs b/src/test/compile-fail/gated-naked_functions.rs index ceb475e119217..5eb4118102768 100644 --- a/src/test/compile-fail/gated-naked_functions.rs +++ b/src/test/compile-fail/gated-naked_functions.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-naked_functions + #[naked] //~^ the `#[naked]` attribute is an experimental feature fn naked() {} diff --git a/src/test/compile-fail/never-disabled.rs b/src/test/compile-fail/never-disabled.rs index 11b9f412957eb..fb6b34fcbb676 100644 --- a/src/test/compile-fail/never-disabled.rs +++ b/src/test/compile-fail/never-disabled.rs @@ -10,6 +10,8 @@ // Test that ! errors when used in illegal positions with feature(never_type) disabled +// gate-test-never_type + trait Foo { type Wub; } diff --git a/src/test/compile-fail/unadjusted-unstable.rs b/src/test/compile-fail/unadjusted-unstable.rs index 501f4451ed8d5..2c23050085d88 100644 --- a/src/test/compile-fail/unadjusted-unstable.rs +++ b/src/test/compile-fail/unadjusted-unstable.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-abi_unadjusted + extern "unadjusted" fn foo() { //~^ ERROR: unadjusted ABI is an implementation detail and perma-unstable } diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 290a1d9facb30..15763778d9249 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -166,7 +166,7 @@ pub fn check(path: &Path, bad: &mut bool) { .count(); // FIXME get this number down to zero. - let gate_untested_expected = 98; + let gate_untested_expected = 94; if gate_untested != gate_untested_expected { print!("Expected {} gate untested features, but found {}. ", From 6795ddf342ceffc155be3a587dac9951269ef7f8 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 11 Jan 2017 02:20:30 +0100 Subject: [PATCH 4/9] Don't require gate tests for removed features --- src/tools/tidy/src/features.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 15763778d9249..8e14bcdebc837 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,7 +16,7 @@ //! * The set of library features is disjoint from the set of language features //! * Library features have at most one stability level //! * Library features have at most one `since` value -//! * All stability attributes have tests to ensure they are actually stable/unstable +//! * All unstable lang features have tests to ensure they are actually unstable use std::collections::HashMap; use std::fmt; @@ -27,6 +27,7 @@ use std::path::Path; #[derive(PartialEq)] enum Status { Stable, + Removed, Unstable, } @@ -35,6 +36,7 @@ impl fmt::Display for Status { let as_str = match *self { Status::Stable => "stable", Status::Unstable => "unstable", + Status::Removed => "removed", }; fmt::Display::fmt(as_str, f) } @@ -221,7 +223,7 @@ fn collect_lang_features(path: &Path) -> HashMap { let mut parts = line.trim().split(","); let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) { Some("active") => Status::Unstable, - Some("removed") => Status::Unstable, + Some("removed") => Status::Removed, Some("accepted") => Status::Stable, _ => return None, }; From 3f6964e22db1a63c7244a9e841254c41e1a88540 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 11 Jan 2017 02:21:49 +0100 Subject: [PATCH 5/9] Automatically treat test files "feature-gate-$f.rs" as gate tests for feature $f --- src/tools/tidy/src/features.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 8e14bcdebc837..abc6ecf1b066e 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -124,6 +124,9 @@ pub fn check(path: &Path, bad: &mut bool) { return; } + let filen_underscore = filename.replace("-","_").replace(".rs",""); + test_filen_gate(&filen_underscore, &mut features); + contents.truncate(0); t!(t!(File::open(&file), &file).read_to_string(&mut contents)); @@ -214,6 +217,19 @@ fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> { .map(|(i, j)| &line[i..j]) } +fn test_filen_gate(filen_underscore: &str, + features: &mut HashMap) -> bool { + if filen_underscore.starts_with("feature_gate") { + for (n, f) in features.iter_mut() { + if filen_underscore == format!("feature_gate_{}", n) { + f.has_gate_test = true; + return true; + } + } + } + return false; +} + fn collect_lang_features(path: &Path) -> HashMap { let mut contents = String::new(); t!(t!(File::open(path)).read_to_string(&mut contents)); From 404572921d1c2cf87cf56a7c983d4ce9438d4a40 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 11 Jan 2017 02:25:02 +0100 Subject: [PATCH 6/9] Use a whitelist and print nice hints --- src/tools/tidy/src/features.rs | 38 +++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index abc6ecf1b066e..b0da6647eb900 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -163,24 +163,38 @@ pub fn check(path: &Path, bad: &mut bool) { } }); + // FIXME get this whitelist empty. + let whitelist = vec![ + "abi_ptx", "simd", "safe_suggestion", "macro_reexport", + "more_struct_aliases", "static_recursion", "reflect", + "quote", "cfg_target_has_atomic", "custom_attribute", + "default_type_parameter_fallback", "pushpop_unsafe", + "use_extern_macros", "staged_api", "const_indexing", + "unboxed_closures", "stmt_expr_attributes", + "cfg_target_thread_local", "unwind_attributes", + "inclusive_range_syntax" + ]; + // Only check the number of lang features. // Obligatory testing for library features is dumb. let gate_untested = features.iter() .filter(|&(_, f)| f.level == Status::Unstable) .filter(|&(_, f)| !f.has_gate_test) - .count(); + .filter(|&(n, _)| !whitelist.contains(&n.as_str())) + .collect::>(); - // FIXME get this number down to zero. - let gate_untested_expected = 94; + for &(name, _) in gate_untested.iter() { + println!("Expected a gate test for the feature '{}'.", name); + println!("Hint: create a file named 'feature-gate-{}.rs' in the compile-fail\ + \n test suite, with its failures due to missing usage of\ + \n #![feature({})].", name, name); + println!("Hint: If you already have such a test and don't want to rename it,\ + \n you can also add a // gate-test-{} line to the test file.", + name); + } - if gate_untested != gate_untested_expected { - print!("Expected {} gate untested features, but found {}. ", - gate_untested_expected, gate_untested); - if gate_untested < gate_untested_expected { - println!("Did you forget to reduce the expected number?"); - } else { - println!("Did you forget to add a gate test for your new feature?"); - } + if gate_untested.len() > 0 { + println!("Found {} features without a gate test.", gate_untested.len()); *bad = true; } @@ -189,7 +203,7 @@ pub fn check(path: &Path, bad: &mut bool) { } let mut lines = Vec::new(); - for (name, feature) in features { + for (name, feature) in features.iter() { lines.push(format!("{:<32} {:<8} {:<12} {:<8}", name, "lang", From 6a29fab274ff72e429b9d323f204a0617d53d8e3 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 11 Jan 2017 02:25:44 +0100 Subject: [PATCH 7/9] Mark even more tests as gate tests Now, no feature outside of the whitelist is without a test marked as its gate test. --- src/test/compile-fail/asm-gated.rs | 2 ++ src/test/compile-fail/asm-gated2.rs | 2 ++ .../compile-fail/attr-on-generic-formals-wo-feature-gate.rs | 2 ++ src/test/compile-fail/check-static-values-constraints.rs | 2 ++ src/test/compile-fail/concat_idents-gate.rs | 2 ++ src/test/compile-fail/concat_idents-gate2.rs | 2 ++ src/test/compile-fail/const-fn-stability.rs | 2 ++ src/test/compile-fail/feature-gate-abi.rs | 4 ++++ src/test/compile-fail/feature-gate-advanced-slice-features.rs | 2 ++ .../feature-gate-allow-internal-unstable-nested-macro.rs | 2 ++ src/test/compile-fail/feature-gate-assoc-type-defaults.rs | 2 ++ src/test/compile-fail/feature-gate-box-expr.rs | 2 ++ src/test/compile-fail/feature-gate-box-pat.rs | 2 ++ src/test/compile-fail/feature-gate-dropck-ugeh.rs | 2 ++ src/test/compile-fail/feature-gate-may-dangle.rs | 2 ++ src/test/compile-fail/feature-gate-placement-expr.rs | 2 ++ src/test/compile-fail/gated-associated_consts.rs | 2 ++ src/test/compile-fail/gated-box-syntax.rs | 2 ++ src/test/compile-fail/gated-concat_idents.rs | 2 ++ src/test/compile-fail/gated-link-args.rs | 2 ++ src/test/compile-fail/gated-link-llvm-intrinsics.rs | 2 ++ src/test/compile-fail/gated-no-core.rs | 2 ++ src/test/compile-fail/gated-non-ascii-idents.rs | 2 ++ src/test/compile-fail/gated-plugin_registrar.rs | 2 ++ src/test/compile-fail/gated-target_feature.rs | 2 ++ src/test/compile-fail/gated-thread-local.rs | 2 ++ src/test/compile-fail/gated-trace_macros.rs | 1 + src/test/compile-fail/i128-feature-2.rs | 3 +++ src/test/compile-fail/i128-feature.rs | 3 +++ src/test/compile-fail/impl-trait/feature-gate.rs | 2 ++ src/test/compile-fail/link-cfg-gated.rs | 2 ++ src/test/compile-fail/linkage1.rs | 2 ++ src/test/compile-fail/log-syntax-gate.rs | 2 ++ src/test/compile-fail/log-syntax-gate2.rs | 2 ++ src/test/compile-fail/no-core-gated.rs | 2 ++ src/test/compile-fail/numeric-fields-feature-gate.rs | 2 ++ src/test/compile-fail/panic-runtime/needs-gate.rs | 3 +++ src/test/compile-fail/privacy/restricted/feature-gate.rs | 2 ++ src/test/compile-fail/rfc1445/feature-gate.rs | 2 ++ src/test/compile-fail/single-derive-attr.rs | 2 ++ .../specialization/specialization-feature-gate-default.rs | 2 ++ .../specialization/specialization-feature-gate-overlap.rs | 2 ++ src/test/compile-fail/static-mut-not-constant.rs | 2 ++ src/test/compile-fail/type-ascription-feature-gate.rs | 2 ++ src/test/compile-fail/union/union-feature-gate.rs | 2 ++ src/test/compile-fail/windows-subsystem-gated.rs | 2 ++ 46 files changed, 96 insertions(+) diff --git a/src/test/compile-fail/asm-gated.rs b/src/test/compile-fail/asm-gated.rs index 8d053bdae789b..cd9cc22370149 100644 --- a/src/test/compile-fail/asm-gated.rs +++ b/src/test/compile-fail/asm-gated.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-asm + fn main() { unsafe { asm!(""); //~ ERROR inline assembly is not stable enough diff --git a/src/test/compile-fail/asm-gated2.rs b/src/test/compile-fail/asm-gated2.rs index d2ee01109f8d8..222190de9fe9c 100644 --- a/src/test/compile-fail/asm-gated2.rs +++ b/src/test/compile-fail/asm-gated2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-asm + fn main() { unsafe { println!("{}", asm!("")); //~ ERROR inline assembly is not stable diff --git a/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs b/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs index 944802f450a6d..b341f7c78257a 100644 --- a/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs +++ b/src/test/compile-fail/attr-on-generic-formals-wo-feature-gate.rs @@ -16,6 +16,8 @@ // using `rustc_attrs` feature. There is a separate compile-fail/ test // ensuring that the attribute feature-gating works in this context.) +// gate-test-generic_param_attrs + #![feature(rustc_attrs)] #![allow(dead_code)] diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs index df22e2ea4de13..f65968e0e1192 100644 --- a/src/test/compile-fail/check-static-values-constraints.rs +++ b/src/test/compile-fail/check-static-values-constraints.rs @@ -10,6 +10,8 @@ // Verifies all possible restrictions for statics values. +// gate-test-drop_types_in_const + #![feature(box_syntax)] use std::marker; diff --git a/src/test/compile-fail/concat_idents-gate.rs b/src/test/compile-fail/concat_idents-gate.rs index f4d97445725cd..5b125d0e51c08 100644 --- a/src/test/compile-fail/concat_idents-gate.rs +++ b/src/test/compile-fail/concat_idents-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-concat_idents + const XY_1: i32 = 10; fn main() { diff --git a/src/test/compile-fail/concat_idents-gate2.rs b/src/test/compile-fail/concat_idents-gate2.rs index d8f8f803edcc8..5a9ffe98c93ca 100644 --- a/src/test/compile-fail/concat_idents-gate2.rs +++ b/src/test/compile-fail/concat_idents-gate2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-concat_idents + const XY_1: i32 = 10; fn main() { diff --git a/src/test/compile-fail/const-fn-stability.rs b/src/test/compile-fail/const-fn-stability.rs index 9913c2fa12c4a..436244525e1c2 100644 --- a/src/test/compile-fail/const-fn-stability.rs +++ b/src/test/compile-fail/const-fn-stability.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-const_fn + // Test use of const fn without feature gate. const fn foo() -> usize { 0 } //~ ERROR const fn is unstable diff --git a/src/test/compile-fail/feature-gate-abi.rs b/src/test/compile-fail/feature-gate-abi.rs index 0c01f955c063b..c0fb94e8c42c9 100644 --- a/src/test/compile-fail/feature-gate-abi.rs +++ b/src/test/compile-fail/feature-gate-abi.rs @@ -8,6 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-intrinsics +// gate-test-platform_intrinsics +// gate-test-abi_vectorcall + // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental diff --git a/src/test/compile-fail/feature-gate-advanced-slice-features.rs b/src/test/compile-fail/feature-gate-advanced-slice-features.rs index 1daca371b3409..dc9b4e634ab72 100644 --- a/src/test/compile-fail/feature-gate-advanced-slice-features.rs +++ b/src/test/compile-fail/feature-gate-advanced-slice-features.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-advanced_slice_patterns + #![feature(slice_patterns)] fn main() { diff --git a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs index 9ebf8a9b74a6c..1aabe6b87dff5 100644 --- a/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs +++ b/src/test/compile-fail/feature-gate-allow-internal-unstable-nested-macro.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-allow_internal_unstable + macro_rules! bar { () => { // more layers don't help: diff --git a/src/test/compile-fail/feature-gate-assoc-type-defaults.rs b/src/test/compile-fail/feature-gate-assoc-type-defaults.rs index fc4871a712dff..de3521eb0f20b 100644 --- a/src/test/compile-fail/feature-gate-assoc-type-defaults.rs +++ b/src/test/compile-fail/feature-gate-assoc-type-defaults.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-associated_type_defaults + trait Foo { type Bar = u8; //~ ERROR associated type defaults are unstable } diff --git a/src/test/compile-fail/feature-gate-box-expr.rs b/src/test/compile-fail/feature-gate-box-expr.rs index f1bb5c0dea21d..65d437d0c0d31 100644 --- a/src/test/compile-fail/feature-gate-box-expr.rs +++ b/src/test/compile-fail/feature-gate-box-expr.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-box_syntax + // Check that `box EXPR` is feature-gated. // // See also feature-gate-placement-expr.rs diff --git a/src/test/compile-fail/feature-gate-box-pat.rs b/src/test/compile-fail/feature-gate-box-pat.rs index e64081823e74c..c30f3952dbfbe 100644 --- a/src/test/compile-fail/feature-gate-box-pat.rs +++ b/src/test/compile-fail/feature-gate-box-pat.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-box_patterns + fn main() { let box x = Box::new('c'); //~ ERROR box pattern syntax is experimental println!("x: {}", x); diff --git a/src/test/compile-fail/feature-gate-dropck-ugeh.rs b/src/test/compile-fail/feature-gate-dropck-ugeh.rs index aa479a987a35b..7c290b3c9c262 100644 --- a/src/test/compile-fail/feature-gate-dropck-ugeh.rs +++ b/src/test/compile-fail/feature-gate-dropck-ugeh.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-dropck_parametricity + // Ensure that attempts to use the unsafe attribute are feature-gated. // Example adapted from RFC 1238 text (just left out the feature gate). diff --git a/src/test/compile-fail/feature-gate-may-dangle.rs b/src/test/compile-fail/feature-gate-may-dangle.rs index 23f8ead0ca9dc..0bf1e93d9aace 100644 --- a/src/test/compile-fail/feature-gate-may-dangle.rs +++ b/src/test/compile-fail/feature-gate-may-dangle.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-dropck_eyepatch + // Check that `may_dangle` is rejected if `dropck_eyepatch` feature gate is absent. #![feature(generic_param_attrs)] diff --git a/src/test/compile-fail/feature-gate-placement-expr.rs b/src/test/compile-fail/feature-gate-placement-expr.rs index 080364c08554f..e3478876763b4 100644 --- a/src/test/compile-fail/feature-gate-placement-expr.rs +++ b/src/test/compile-fail/feature-gate-placement-expr.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-placement_in_syntax + // Check that `in PLACE { EXPR }` is feature-gated. // // See also feature-gate-box-expr.rs diff --git a/src/test/compile-fail/gated-associated_consts.rs b/src/test/compile-fail/gated-associated_consts.rs index cfa75ff9763e9..ee4422faf3a24 100644 --- a/src/test/compile-fail/gated-associated_consts.rs +++ b/src/test/compile-fail/gated-associated_consts.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-associated_consts + trait MyTrait { const C: bool; //~^ associated constants are experimental diff --git a/src/test/compile-fail/gated-box-syntax.rs b/src/test/compile-fail/gated-box-syntax.rs index a2643fe02b8f7..9a68ddb305960 100644 --- a/src/test/compile-fail/gated-box-syntax.rs +++ b/src/test/compile-fail/gated-box-syntax.rs @@ -10,6 +10,8 @@ // Test that the use of the box syntax is gated by `box_syntax` feature gate. +// gate-test-box_syntax + fn main() { let x = box 3; //~^ ERROR box expression syntax is experimental; you can call `Box::new` instead. diff --git a/src/test/compile-fail/gated-concat_idents.rs b/src/test/compile-fail/gated-concat_idents.rs index 054e70f382268..af288a9790440 100644 --- a/src/test/compile-fail/gated-concat_idents.rs +++ b/src/test/compile-fail/gated-concat_idents.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-concat_idents + fn main() { concat_idents!(a, b); //~ ERROR `concat_idents` is not stable enough } diff --git a/src/test/compile-fail/gated-link-args.rs b/src/test/compile-fail/gated-link-args.rs index 7b1405c913f6b..d34057e290eba 100644 --- a/src/test/compile-fail/gated-link-args.rs +++ b/src/test/compile-fail/gated-link-args.rs @@ -11,6 +11,8 @@ // Test that `#[link_args]` attribute is gated by `link_args` // feature gate. +// gate-test-link_args + #[link_args = "aFdEfSeVEEE"] extern {} //~^ ERROR the `link_args` attribute is not portable across platforms diff --git a/src/test/compile-fail/gated-link-llvm-intrinsics.rs b/src/test/compile-fail/gated-link-llvm-intrinsics.rs index 92a1b071437e6..681824ae71dd0 100644 --- a/src/test/compile-fail/gated-link-llvm-intrinsics.rs +++ b/src/test/compile-fail/gated-link-llvm-intrinsics.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-link_llvm_intrinsics + extern { #[link_name = "llvm.sqrt.f32"] fn sqrt(x: f32) -> f32; diff --git a/src/test/compile-fail/gated-no-core.rs b/src/test/compile-fail/gated-no-core.rs index 0a55a8a78ce5a..66b9c2e56705f 100644 --- a/src/test/compile-fail/gated-no-core.rs +++ b/src/test/compile-fail/gated-no-core.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-no_core + #![no_core] //~ ERROR no_core is experimental fn main() {} diff --git a/src/test/compile-fail/gated-non-ascii-idents.rs b/src/test/compile-fail/gated-non-ascii-idents.rs index 9e042c3a7d50e..1dff22839ad87 100644 --- a/src/test/compile-fail/gated-non-ascii-idents.rs +++ b/src/test/compile-fail/gated-non-ascii-idents.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-non_ascii_idents + extern crate core as bäz; //~ ERROR non-ascii idents use föö::bar; //~ ERROR non-ascii idents diff --git a/src/test/compile-fail/gated-plugin_registrar.rs b/src/test/compile-fail/gated-plugin_registrar.rs index 9cdebde7b7b98..8d185d183b419 100644 --- a/src/test/compile-fail/gated-plugin_registrar.rs +++ b/src/test/compile-fail/gated-plugin_registrar.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-plugin_registrar + // Test that `#[plugin_registrar]` attribute is gated by `plugin_registrar` // feature gate. diff --git a/src/test/compile-fail/gated-target_feature.rs b/src/test/compile-fail/gated-target_feature.rs index da2e41a0f5e42..02db8a71d5340 100644 --- a/src/test/compile-fail/gated-target_feature.rs +++ b/src/test/compile-fail/gated-target_feature.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-target_feature + #[target_feature = "+sse2"] //~^ the `#[target_feature]` attribute is an experimental feature fn foo() {} diff --git a/src/test/compile-fail/gated-thread-local.rs b/src/test/compile-fail/gated-thread-local.rs index f355c6562c8b0..b02ce9b7ecb81 100644 --- a/src/test/compile-fail/gated-thread-local.rs +++ b/src/test/compile-fail/gated-thread-local.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-thread_local + // Test that `#[thread_local]` attribute is gated by `thread_local` // feature gate. // diff --git a/src/test/compile-fail/gated-trace_macros.rs b/src/test/compile-fail/gated-trace_macros.rs index 19b08ce655c06..0b85b19f176d7 100644 --- a/src/test/compile-fail/gated-trace_macros.rs +++ b/src/test/compile-fail/gated-trace_macros.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-trace_macros fn main() { trace_macros!(true); //~ ERROR: `trace_macros` is not stable diff --git a/src/test/compile-fail/i128-feature-2.rs b/src/test/compile-fail/i128-feature-2.rs index 4a76d39921842..d3bd810ceb2b4 100644 --- a/src/test/compile-fail/i128-feature-2.rs +++ b/src/test/compile-fail/i128-feature-2.rs @@ -7,6 +7,9 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. + +// gate-test-i128_type + fn test1() -> i128 { //~ ERROR 128-bit type is unstable 0 } diff --git a/src/test/compile-fail/i128-feature.rs b/src/test/compile-fail/i128-feature.rs index 87dda469f9390..e94fd14a42163 100644 --- a/src/test/compile-fail/i128-feature.rs +++ b/src/test/compile-fail/i128-feature.rs @@ -7,6 +7,9 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. + +// gate-test-i128_type + fn test2() { 0i128; //~ ERROR 128-bit integers are not stable } diff --git a/src/test/compile-fail/impl-trait/feature-gate.rs b/src/test/compile-fail/impl-trait/feature-gate.rs index 8239b06f2b4a3..f171b6becc4b7 100644 --- a/src/test/compile-fail/impl-trait/feature-gate.rs +++ b/src/test/compile-fail/impl-trait/feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-conservative_impl_trait + fn foo() -> impl Fn() { || {} } //~^ ERROR `impl Trait` is experimental diff --git a/src/test/compile-fail/link-cfg-gated.rs b/src/test/compile-fail/link-cfg-gated.rs index 27918a27caf50..bb6fb9e356352 100644 --- a/src/test/compile-fail/link-cfg-gated.rs +++ b/src/test/compile-fail/link-cfg-gated.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-link_cfg + #[link(name = "foo", cfg(foo))] //~^ ERROR: is feature gated extern {} diff --git a/src/test/compile-fail/linkage1.rs b/src/test/compile-fail/linkage1.rs index 555cc2b9a7aad..1cf208f021588 100644 --- a/src/test/compile-fail/linkage1.rs +++ b/src/test/compile-fail/linkage1.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-linkage + extern { #[linkage = "extern_weak"] static foo: isize; //~^ ERROR: the `linkage` attribute is experimental and not portable diff --git a/src/test/compile-fail/log-syntax-gate.rs b/src/test/compile-fail/log-syntax-gate.rs index 63c66e53c5ee8..b9688af35dc90 100644 --- a/src/test/compile-fail/log-syntax-gate.rs +++ b/src/test/compile-fail/log-syntax-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-log_syntax + fn main() { log_syntax!() //~ ERROR `log_syntax!` is not stable enough } diff --git a/src/test/compile-fail/log-syntax-gate2.rs b/src/test/compile-fail/log-syntax-gate2.rs index bb19e97ab0fa8..dcbe7eefee52c 100644 --- a/src/test/compile-fail/log-syntax-gate2.rs +++ b/src/test/compile-fail/log-syntax-gate2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-log_syntax + fn main() { println!("{}", log_syntax!()); //~ ERROR `log_syntax!` is not stable } diff --git a/src/test/compile-fail/no-core-gated.rs b/src/test/compile-fail/no-core-gated.rs index dbaa4177e1429..27f8fda98ab34 100644 --- a/src/test/compile-fail/no-core-gated.rs +++ b/src/test/compile-fail/no-core-gated.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-no_core + #![no_core] //~ ERROR no_core is experimental fn main() {} diff --git a/src/test/compile-fail/numeric-fields-feature-gate.rs b/src/test/compile-fail/numeric-fields-feature-gate.rs index 3ce85813a9b51..bd8ec16ef8826 100644 --- a/src/test/compile-fail/numeric-fields-feature-gate.rs +++ b/src/test/compile-fail/numeric-fields-feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-relaxed_adts + struct S(u8); fn main() { diff --git a/src/test/compile-fail/panic-runtime/needs-gate.rs b/src/test/compile-fail/panic-runtime/needs-gate.rs index 02f3da58f1da8..1b3b978c40811 100644 --- a/src/test/compile-fail/panic-runtime/needs-gate.rs +++ b/src/test/compile-fail/panic-runtime/needs-gate.rs @@ -8,6 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-needs_panic_runtime +// gate-test-panic_runtime + #![panic_runtime] //~ ERROR: is an experimental feature #![needs_panic_runtime] //~ ERROR: is an experimental feature diff --git a/src/test/compile-fail/privacy/restricted/feature-gate.rs b/src/test/compile-fail/privacy/restricted/feature-gate.rs index 53ae439867f98..e81e1e30d1750 100644 --- a/src/test/compile-fail/privacy/restricted/feature-gate.rs +++ b/src/test/compile-fail/privacy/restricted/feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-pub_restricted + pub(crate) //~ ERROR experimental mod foo {} diff --git a/src/test/compile-fail/rfc1445/feature-gate.rs b/src/test/compile-fail/rfc1445/feature-gate.rs index 1f2d7819e26d8..b51ee3d8b5ed8 100644 --- a/src/test/compile-fail/rfc1445/feature-gate.rs +++ b/src/test/compile-fail/rfc1445/feature-gate.rs @@ -14,6 +14,8 @@ // revisions: with_gate no_gate +// gate-test-structural_match + #![allow(dead_code)] #![deny(future_incompatible)] #![feature(rustc_attrs)] diff --git a/src/test/compile-fail/single-derive-attr.rs b/src/test/compile-fail/single-derive-attr.rs index 0b1b3141f5bf7..cd37611aceda9 100644 --- a/src/test/compile-fail/single-derive-attr.rs +++ b/src/test/compile-fail/single-derive-attr.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-custom_derive + #[derive_Clone] //~^ ERROR attributes of the form `#[derive_*]` are reserved struct Test; diff --git a/src/test/compile-fail/specialization/specialization-feature-gate-default.rs b/src/test/compile-fail/specialization/specialization-feature-gate-default.rs index e7c194ce84df9..3a01ecdf9db6f 100644 --- a/src/test/compile-fail/specialization/specialization-feature-gate-default.rs +++ b/src/test/compile-fail/specialization/specialization-feature-gate-default.rs @@ -10,6 +10,8 @@ // Check that specialization must be ungated to use the `default` keyword +// gate-test-specialization + trait Foo { fn foo(&self); } diff --git a/src/test/compile-fail/specialization/specialization-feature-gate-overlap.rs b/src/test/compile-fail/specialization/specialization-feature-gate-overlap.rs index d11ab56ff7e87..5eb48eab15e52 100644 --- a/src/test/compile-fail/specialization/specialization-feature-gate-overlap.rs +++ b/src/test/compile-fail/specialization/specialization-feature-gate-overlap.rs @@ -10,6 +10,8 @@ // Check that writing an overlapping impl is not allow unless specialization is ungated. +// gate-test-specialization + trait Foo { fn foo(&self); } diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs index 9b83c42609aa5..7c37abf765769 100644 --- a/src/test/compile-fail/static-mut-not-constant.rs +++ b/src/test/compile-fail/static-mut-not-constant.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-drop_types_in_const + #![feature(box_syntax)] static mut a: Box = box 3; diff --git a/src/test/compile-fail/type-ascription-feature-gate.rs b/src/test/compile-fail/type-ascription-feature-gate.rs index d3c07d653f40c..bf4ca03069c57 100644 --- a/src/test/compile-fail/type-ascription-feature-gate.rs +++ b/src/test/compile-fail/type-ascription-feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-type_ascription + // Type ascription is feature gated fn main() { diff --git a/src/test/compile-fail/union/union-feature-gate.rs b/src/test/compile-fail/union/union-feature-gate.rs index abfc4d909218b..0c2165871f6db 100644 --- a/src/test/compile-fail/union/union-feature-gate.rs +++ b/src/test/compile-fail/union/union-feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-untagged_unions + union U { //~ ERROR unions are unstable and possibly buggy a: u8, } diff --git a/src/test/compile-fail/windows-subsystem-gated.rs b/src/test/compile-fail/windows-subsystem-gated.rs index 4b563e78e55c8..63f891a2af7bf 100644 --- a/src/test/compile-fail/windows-subsystem-gated.rs +++ b/src/test/compile-fail/windows-subsystem-gated.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-windows_subsystem + #![windows_subsystem = "console"] //~^ ERROR: the windows subsystem attribute is currently unstable From bdee52e94d3f8ac8cd1bb649529a43f8b893d9a7 Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 11 Jan 2017 02:34:30 +0100 Subject: [PATCH 8/9] Add docs --- COMPILER_TESTS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/COMPILER_TESTS.md b/COMPILER_TESTS.md index 91975c1f9ed9a..58df1aae6d3f0 100644 --- a/COMPILER_TESTS.md +++ b/COMPILER_TESTS.md @@ -45,6 +45,10 @@ whole, instead of just a few lines inside the test. * `should-fail` indicates that the test should fail; used for "meta testing", where we test the compiletest program itself to check that it will generate errors in appropriate scenarios. This header is ignored for pretty-printer tests. +* `gate-test-X` where `X` is a feature marks the test as "gate test" for feature X. + Such tests are supposed to ensure that the compiler errors when usage of a gated + feature is attempted without the proper `#![feature(X)]` tag. + Each unstable lang feature is required to have a gate test. ## Revisions From c6f99b4aeab135bf0cc53bd871108ffc948950ef Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 12 Jan 2017 23:55:32 +0100 Subject: [PATCH 9/9] Also mark the struct_field_attributes regression test Rebase on top of PR 38814 made required this. --- src/test/compile-fail/struct-field-attr-feature-gate.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/compile-fail/struct-field-attr-feature-gate.rs b/src/test/compile-fail/struct-field-attr-feature-gate.rs index 665c3fd67f48f..47495be4ad2c9 100644 --- a/src/test/compile-fail/struct-field-attr-feature-gate.rs +++ b/src/test/compile-fail/struct-field-attr-feature-gate.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// gate-test-struct_field_attributes + struct Foo { present: (), }