Rollup merge of #84871 - richkadel:no-coverage-unstable-only, r=nagisa
Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating) Fixes: #84836 Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta). I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1` With unstable features disabled, I get the expected result as shown here: ```shell $ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc src/test/run-make-fulldeps/coverage/no_cov_crate.rs error[E0554]: `#![feature]` may not be used on the dev release channel --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1 | 2 | #![feature(no_coverage)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0554`. ``` r? ````@Mark-Simulacrum```` cc: ````@tmandry```` ````@wesleywiser````
This commit is contained in:
commit
aaf23892ab
9 changed files with 18 additions and 91 deletions
|
@ -15,20 +15,12 @@ pub fn expand_deriving_eq(
|
||||||
item: &Annotatable,
|
item: &Annotatable,
|
||||||
push: &mut dyn FnMut(Annotatable),
|
push: &mut dyn FnMut(Annotatable),
|
||||||
) {
|
) {
|
||||||
|
let span = cx.with_def_site_ctxt(span);
|
||||||
let inline = cx.meta_word(span, sym::inline);
|
let inline = cx.meta_word(span, sym::inline);
|
||||||
let no_coverage_ident =
|
|
||||||
rustc_ast::attr::mk_nested_word_item(Ident::new(sym::no_coverage, span));
|
|
||||||
let no_coverage_feature =
|
|
||||||
rustc_ast::attr::mk_list_item(Ident::new(sym::feature, span), vec![no_coverage_ident]);
|
|
||||||
let no_coverage = cx.meta_word(span, sym::no_coverage);
|
|
||||||
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
|
let hidden = rustc_ast::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
|
||||||
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
|
let doc = rustc_ast::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
|
||||||
let attrs = vec![
|
let no_coverage = cx.meta_word(span, sym::no_coverage);
|
||||||
cx.attribute(inline),
|
let attrs = vec![cx.attribute(inline), cx.attribute(doc), cx.attribute(no_coverage)];
|
||||||
cx.attribute(no_coverage_feature),
|
|
||||||
cx.attribute(no_coverage),
|
|
||||||
cx.attribute(doc),
|
|
||||||
];
|
|
||||||
let trait_def = TraitDef {
|
let trait_def = TraitDef {
|
||||||
span,
|
span,
|
||||||
attributes: Vec::new(),
|
attributes: Vec::new(),
|
||||||
|
|
|
@ -273,13 +273,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
template!(List: "address, memory, thread"),
|
template!(List: "address, memory, thread"),
|
||||||
experimental!(no_sanitize)
|
experimental!(no_sanitize)
|
||||||
),
|
),
|
||||||
ungated!(
|
gated!(no_coverage, AssumedUsed, template!(Word), experimental!(no_coverage)),
|
||||||
// Not exclusively gated at the crate level (though crate-level is
|
|
||||||
// supported). The feature can alternatively be enabled on individual
|
|
||||||
// functions.
|
|
||||||
no_coverage, AssumedUsed,
|
|
||||||
template!(Word),
|
|
||||||
),
|
|
||||||
|
|
||||||
// FIXME: #14408 assume docs are used since rustdoc looks at them.
|
// FIXME: #14408 assume docs are used since rustdoc looks at them.
|
||||||
ungated!(doc, AssumedUsed, template!(List: "hidden|inline|...", NameValueStr: "string")),
|
ungated!(doc, AssumedUsed, template!(List: "hidden|inline|...", NameValueStr: "string")),
|
||||||
|
|
|
@ -2661,8 +2661,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
||||||
let mut inline_span = None;
|
let mut inline_span = None;
|
||||||
let mut link_ordinal_span = None;
|
let mut link_ordinal_span = None;
|
||||||
let mut no_sanitize_span = None;
|
let mut no_sanitize_span = None;
|
||||||
let mut no_coverage_feature_enabled = false;
|
|
||||||
let mut no_coverage_attr = None;
|
|
||||||
for attr in attrs.iter() {
|
for attr in attrs.iter() {
|
||||||
if tcx.sess.check_name(attr, sym::cold) {
|
if tcx.sess.check_name(attr, sym::cold) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD;
|
||||||
|
@ -2726,15 +2724,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED;
|
||||||
} else if tcx.sess.check_name(attr, sym::no_mangle) {
|
} else if tcx.sess.check_name(attr, sym::no_mangle) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||||
} else if attr.has_name(sym::feature) {
|
|
||||||
if let Some(list) = attr.meta_item_list() {
|
|
||||||
if list.iter().any(|nested_meta_item| nested_meta_item.has_name(sym::no_coverage)) {
|
|
||||||
tcx.sess.mark_attr_used(attr);
|
|
||||||
no_coverage_feature_enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if tcx.sess.check_name(attr, sym::no_coverage) {
|
} else if tcx.sess.check_name(attr, sym::no_coverage) {
|
||||||
no_coverage_attr = Some(attr);
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
|
||||||
} else if tcx.sess.check_name(attr, sym::rustc_std_internal_symbol) {
|
} else if tcx.sess.check_name(attr, sym::rustc_std_internal_symbol) {
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL;
|
||||||
} else if tcx.sess.check_name(attr, sym::used) {
|
} else if tcx.sess.check_name(attr, sym::used) {
|
||||||
|
@ -2945,23 +2936,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(no_coverage_attr) = no_coverage_attr {
|
|
||||||
if tcx.sess.features_untracked().no_coverage || no_coverage_feature_enabled {
|
|
||||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE
|
|
||||||
} else {
|
|
||||||
let mut err = feature_err(
|
|
||||||
&tcx.sess.parse_sess,
|
|
||||||
sym::no_coverage,
|
|
||||||
no_coverage_attr.span,
|
|
||||||
"the `#[no_coverage]` attribute is an experimental feature",
|
|
||||||
);
|
|
||||||
if tcx.sess.parse_sess.unstable_features.is_nightly_build() {
|
|
||||||
err.help("or, alternatively, add `#[feature(no_coverage)]` to the function");
|
|
||||||
}
|
|
||||||
err.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
|
codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
|
||||||
if !attr.has_name(sym::inline) {
|
if !attr.has_name(sym::inline) {
|
||||||
return ia;
|
return ia;
|
||||||
|
|
|
@ -274,8 +274,7 @@ pub trait Eq: PartialEq<Self> {
|
||||||
//
|
//
|
||||||
// This should never be implemented by hand.
|
// This should never be implemented by hand.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[cfg_attr(not(bootstrap), feature(no_coverage))]
|
#[cfg_attr(not(bootstrap), no_coverage)] // rust-lang/rust#84605
|
||||||
#[cfg_attr(not(bootstrap), no_coverage)]
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
fn assert_receiver_is_total_eq(&self) {}
|
fn assert_receiver_is_total_eq(&self) {}
|
||||||
|
@ -284,7 +283,7 @@ pub trait Eq: PartialEq<Self> {
|
||||||
/// Derive macro generating an impl of the trait `Eq`.
|
/// Derive macro generating an impl of the trait `Eq`.
|
||||||
#[rustc_builtin_macro]
|
#[rustc_builtin_macro]
|
||||||
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
|
||||||
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
|
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
|
||||||
pub macro Eq($item:item) {
|
pub macro Eq($item:item) {
|
||||||
/* compiler built-in */
|
/* compiler built-in */
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,7 @@
|
||||||
#![feature(const_caller_location)]
|
#![feature(const_caller_location)]
|
||||||
#![feature(slice_ptr_get)]
|
#![feature(slice_ptr_get)]
|
||||||
#![feature(no_niche)] // rust-lang/rust#68303
|
#![feature(no_niche)] // rust-lang/rust#68303
|
||||||
|
#![cfg_attr(not(bootstrap), feature(no_coverage))] // rust-lang/rust#84605
|
||||||
#![feature(int_error_matching)]
|
#![feature(int_error_matching)]
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
1| |// Enables `no_coverage` on individual functions
|
|
||||||
2| |
|
|
||||||
3| |#[feature(no_coverage)]
|
|
||||||
4| |#[no_coverage]
|
|
||||||
5| |fn do_not_add_coverage_1() {
|
|
||||||
6| | println!("called but not covered");
|
|
||||||
7| |}
|
|
||||||
8| |
|
|
||||||
9| |#[no_coverage]
|
|
||||||
10| |#[feature(no_coverage)]
|
|
||||||
11| |fn do_not_add_coverage_2() {
|
|
||||||
12| | println!("called but not covered");
|
|
||||||
13| |}
|
|
||||||
14| |
|
|
||||||
15| 1|fn main() {
|
|
||||||
16| 1| do_not_add_coverage_1();
|
|
||||||
17| 1| do_not_add_coverage_2();
|
|
||||||
18| 1|}
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
// Enables `no_coverage` on individual functions
|
|
||||||
|
|
||||||
#[feature(no_coverage)]
|
|
||||||
#[no_coverage]
|
|
||||||
fn do_not_add_coverage_1() {
|
|
||||||
println!("called but not covered");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_coverage]
|
|
||||||
#[feature(no_coverage)]
|
|
||||||
fn do_not_add_coverage_2() {
|
|
||||||
println!("called but not covered");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
do_not_add_coverage_1();
|
|
||||||
do_not_add_coverage_2();
|
|
||||||
}
|
|
|
@ -1,8 +1,13 @@
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
#[no_coverage]
|
#[derive(PartialEq, Eq)] // ensure deriving `Eq` does not enable `feature(no_coverage)`
|
||||||
#[feature(no_coverage)] // does not have to be enabled before `#[no_coverage]`
|
struct Foo {
|
||||||
fn no_coverage_is_enabled_on_this_function() {}
|
a: u8,
|
||||||
|
b: u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[no_coverage] //~ ERROR the `#[no_coverage]` attribute is an experimental feature
|
#[no_coverage] //~ ERROR the `#[no_coverage]` attribute is an experimental feature
|
||||||
fn requires_feature_no_coverage() {}
|
fn requires_feature_no_coverage() -> bool {
|
||||||
|
let bar = Foo { a: 0, b: 0 };
|
||||||
|
bar == Foo { a: 0, b: 0 }
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
error[E0658]: the `#[no_coverage]` attribute is an experimental feature
|
error[E0658]: the `#[no_coverage]` attribute is an experimental feature
|
||||||
--> $DIR/feature-gate-no_coverage.rs:7:1
|
--> $DIR/feature-gate-no_coverage.rs:9:1
|
||||||
|
|
|
|
||||||
LL | #[no_coverage]
|
LL | #[no_coverage]
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information
|
= note: see issue #84605 <https://github.com/rust-lang/rust/issues/84605> for more information
|
||||||
= help: add `#![feature(no_coverage)]` to the crate attributes to enable
|
= help: add `#![feature(no_coverage)]` to the crate attributes to enable
|
||||||
= help: or, alternatively, add `#[feature(no_coverage)]` to the function
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue