Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
}

fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
if attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace) {
if attr.has_any_name(&[sym::cfg_trace, sym::cfg_attr_trace, sym::test_trace]) {
// It's not a valid identifier, so avoid printing it
// to keep the printed code reasonably parse-able.
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ impl<S: Stage> AttributeParser<S> for NakedParser {
sym::cfg_attr_trace,
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
sym::test,
sym::test_trace,
sym::ignore,
sym::should_panic,
sym::bench,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_attr_parsing/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub(crate) mod rustc_internal;
pub(crate) mod semantics;
pub(crate) mod stability;
pub(crate) mod test_attrs;
pub(crate) mod trace;
pub(crate) mod traits;
pub(crate) mod transparency;
pub(crate) mod util;
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use super::prelude::*;

pub(crate) struct TestTraceParser;

impl<S: Stage> NoArgsAttributeParser<S> for TestTraceParser {
const PATH: &[Symbol] = &[sym::test_trace];

const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Ignore;

const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);

const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::TestTrace;
}
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser};
use crate::attributes::trace::TestTraceParser;
use crate::attributes::traits::{
AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser,
DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser,
Expand Down Expand Up @@ -290,6 +291,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
Single<WithoutArgs<SpecializationTraitParser>>,
Single<WithoutArgs<StdInternalSymbolParser>>,
Single<WithoutArgs<TestTraceParser>>,
Single<WithoutArgs<ThreadLocalParser>>,
Single<WithoutArgs<TrackCallerParser>>,
Single<WithoutArgs<TypeConstParser>>,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/validate_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use rustc_span::{Span, Symbol, sym};
use crate::{AttributeParser, Late, session_diagnostics as errors};

pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
if attr.is_doc_comment() || attr.has_name(sym::cfg_trace) || attr.has_name(sym::cfg_attr_trace)
if attr.is_doc_comment()
|| attr.has_any_name(&[sym::cfg_trace, sym::cfg_attr_trace, sym::test_trace])
{
return;
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_builtin_macros/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub(crate) fn expand_test_or_bench(
item: Annotatable,
is_bench: bool,
) -> Vec<Annotatable> {
let (item, is_stmt) = match item {
let (mut item, is_stmt) = match item {
Annotatable::Item(i) => (i, false),
Annotatable::Stmt(box ast::Stmt { kind: ast::StmtKind::Item(i), .. }) => (i, true),
other => {
Expand All @@ -136,6 +136,11 @@ pub(crate) fn expand_test_or_bench(
return vec![];
}

// Add a trace to the originating test function, so that we can
// check if attributes that have `#[test]` or `#[bench]` as a requirement
// actually are annotated with said attributes
item.attrs.push(cx.attr_word(sym::test_trace, cx.with_def_site_ctxt(attr_sp)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The crater run in #150727 (comment) had a bunch of failures (such as https://crater-reports.s3.amazonaws.com/pr-150727/try%2366388cc165a6c4ac98c074dc9f0281ff23528c55/gh/0958436455sarayut.master/log.txt) because this creates an attribute without a TokenStream. Can you look into this and make a regression test if easily possible?


if let Some(attr) = attr::find_by_name(&item.attrs, sym::naked) {
cx.dcx().emit_err(errors::NakedFunctionTestingAttribute {
testing_span: attr_sp,
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,10 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
cfg_attr_trace, Normal, template!(Word /* irrelevant */), DuplicatesOk,
EncodeCrossCrate::No
),
ungated!(
test_trace, Normal, template!(Word), ErrorFollowing,
EncodeCrossCrate::No
),

// ==========================================================================
// Internal attributes, Diagnostics related:
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,9 @@ pub enum AttributeKind {
/// `#[unsafe(force_target_feature(enable = "...")]`.
TargetFeature { features: ThinVec<(Symbol, Span)>, attr_span: Span, was_forced: bool },

/// Represents `#[<test_trace>]`
TestTrace,

/// Represents `#[thread_local]`
ThreadLocal,

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl AttributeKind {
Stability { .. } => Yes,
StdInternalSymbol(..) => No,
TargetFeature { .. } => No,
TestTrace => No,
ThreadLocal => No,
TrackCaller(..) => Yes,
TypeConst(..) => Yes,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ passes_attr_application_struct_union =
attribute should be applied to a struct or union
.label = not a struct or union

passes_attr_must_be_applied_to_test_or_bench = `#[{$attr_name}]` should only be applied to functions annotated with `#[test]` or `#[bench]`
.warn = {-passes_previously_accepted}

passes_autodiff_attr =
`#[autodiff]` should be applied to a function
.label = not a function
Expand Down
35 changes: 33 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target)
},
Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)},
Attribute::Parsed(AttributeKind::ShouldPanic { span, .. }) => {
self.check_should_panic(attrs, *span, target);
},
Attribute::Parsed(AttributeKind::Ignore { span, .. }) => {
self.check_ignore(attrs, *span, target);
}
Attribute::Parsed(
AttributeKind::EiiDeclaration { .. }
| AttributeKind::EiiForeignItem
Expand All @@ -235,7 +241,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::Pointee(..)
| AttributeKind::Dummy
| AttributeKind::RustcBuiltinMacro { .. }
| AttributeKind::Ignore { .. }
| AttributeKind::InstructionSet(..)
| AttributeKind::Path(..)
| AttributeKind::NoImplicitPrelude(..)
Expand Down Expand Up @@ -286,7 +291,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::PassByValue (..)
| AttributeKind::StdInternalSymbol (..)
| AttributeKind::Coverage (..)
| AttributeKind::ShouldPanic { .. }
| AttributeKind::Coroutine(..)
| AttributeKind::Linkage(..)
| AttributeKind::MustUse { .. }
Expand Down Expand Up @@ -315,6 +319,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcDumpPredicates
| AttributeKind::RustcDumpDefParents
| AttributeKind::RustcDumpVtable(..)
| AttributeKind::TestTrace
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
Expand Down Expand Up @@ -484,6 +489,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.check_mix_no_mangle_export(hir_id, attrs);
}

fn check_ignore(&self, attrs: &[Attribute], attr_span: Span, target: Target) {
// The error message only makes sense if it's actually being applied on a function
if matches!(target, Target::Fn) {
if !find_attr!(attrs, AttributeKind::TestTrace) {
self.dcx().emit_warn(errors::MustBeAppliedToTest {
attr_span,
attr_name: sym::ignore,
warning: true,
});
}
}
}

fn check_should_panic(&self, attrs: &[Attribute], attr_span: Span, target: Target) {
// The error message only makes sense if it's actually being applied on a function
if matches!(target, Target::Fn) {
if !find_attr!(attrs, AttributeKind::TestTrace) {
self.dcx().emit_warn(errors::MustBeAppliedToTest {
attr_span,
attr_name: sym::should_panic,
warning: true,
});
}
}
}

fn check_rustc_must_implement_one_of(
&self,
attr_span: Span,
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,3 +1316,13 @@ pub(crate) struct FunctionNamesDuplicated {
#[primary_span]
pub spans: Vec<Span>,
}

#[derive(Diagnostic)]
#[diag(passes_attr_must_be_applied_to_test_or_bench)]
pub(crate) struct MustBeAppliedToTest {
#[primary_span]
pub attr_span: Span,
#[warning]
pub warning: bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason #[warning] is configurable here?
I think this can just always be a warning

(you can do this by applying #[warning] to the struct)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is what all the other FCW in rustc_passes/messages.ftl do AFAICT

pub attr_name: Symbol,
}
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2273,6 +2273,7 @@ symbols! {
test_case,
test_removed_feature,
test_runner,
test_trace: "<test_trace>",
test_unstable_lint,
thread,
thread_local,
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/attributes/ignore.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ check-pass
#![feature(test)]

#[ignore]
//~^ WARN `#[ignore]` should only be applied to functions annotated with `#[test]` or `#[bench]`
//~| WARN this was previously accepted
pub fn foo() {}


#[test]
#[ignore]
pub fn bar() {}

#[ignore]
#[bench]
pub fn bazz() {}

fn main() { }
10 changes: 10 additions & 0 deletions tests/ui/attributes/ignore.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
warning: `#[ignore]` should only be applied to functions annotated with `#[test]` or `#[bench]`
--> $DIR/ignore.rs:4:1
|
LL | #[ignore]
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

warning: 1 warning emitted

18 changes: 18 additions & 0 deletions tests/ui/attributes/should-panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ check-pass
#![feature(test)]

#[should_panic]
//~^ WARN `#[should_panic]` should only be applied to functions annotated with `#[test]` or `#[bench]`
//~| WARN this was previously accepted
pub fn foo() {}


#[test]
#[should_panic]
pub fn bar() {}

#[should_panic]
#[bench]
pub fn bazz() {}

fn main() { }
10 changes: 10 additions & 0 deletions tests/ui/attributes/should-panic.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
warning: `#[should_panic]` should only be applied to functions annotated with `#[test]` or `#[bench]`
--> $DIR/should-panic.rs:4:1
|
LL | #[should_panic]
| ^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!

warning: 1 warning emitted

20 changes: 20 additions & 0 deletions tests/ui/attributes/test_trace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//@ compile-flags: --test

fn main() {}

#[test_trace]
//~^ ERROR cannot find attribute `test_trace` in this scope
fn foo() {}


#[test]
#[test_trace]
//~^ ERROR cannot find attribute `test_trace` in this scope
fn bar() {}

#[test]
#[test_trace]
//~^ ERROR cannot find attribute `test_trace` in this scope
#[test]
//~^ WARN duplicated attribute
fn bazz() {}
46 changes: 46 additions & 0 deletions tests/ui/attributes/test_trace.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
error: cannot find attribute `test_trace` in this scope
--> $DIR/test_trace.rs:5:3
|
LL | #[test_trace]
| ^^^^^^^^^^
|
help: a built-in attribute with a similar name exists
|
LL - #[test_trace]
LL + #[<test_trace>]
|

error: cannot find attribute `test_trace` in this scope
--> $DIR/test_trace.rs:11:3
|
LL | #[test_trace]
| ^^^^^^^^^^
|
help: a built-in attribute with a similar name exists
|
LL - #[test_trace]
LL + #[<test_trace>]
|

error: cannot find attribute `test_trace` in this scope
--> $DIR/test_trace.rs:16:3
|
LL | #[test_trace]
| ^^^^^^^^^^
|
help: a built-in attribute with a similar name exists
|
LL - #[test_trace]
LL + #[<test_trace>]
|

warning: duplicated attribute
--> $DIR/test_trace.rs:18:1
|
LL | #[test]
| ^^^^^^^
|
= note: `#[warn(duplicate_macro_attributes)]` on by default

error: aborting due to 3 previous errors; 1 warning emitted

10 changes: 8 additions & 2 deletions tests/ui/attributes/unsafe/extraneous-unsafe-attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ fn b() {}
#[unsafe(test)] //~ ERROR: is not an unsafe attribute
fn aa() {}

#[unsafe(ignore = "test")] //~ ERROR: is not an unsafe attribute
#[unsafe(ignore = "test")]
//~^ ERROR: is not an unsafe attribute
//~| WARN`#[ignore]` should only be applied to functions annotated with `#[test]` or `#[bench]`
//~| WARN this was previously accepted by the compiler
fn bb() {}

#[unsafe(should_panic(expected = "test"))] //~ ERROR: is not an unsafe attribute
#[unsafe(should_panic(expected = "test"))]
//~^ ERROR: is not an unsafe attribute
//~| WARN `#[should_panic]` should only be applied to functions annotated with `#[test]` or `#[bench]`
//~| WARN this was previously accepted
fn cc() {}

#[unsafe(macro_use)] //~ ERROR: is not an unsafe attribute
Expand Down
Loading
Loading