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 @@ -60,6 +60,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 @@ -75,6 +75,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 @@ -275,6 +276,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)));

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 @@ -958,6 +958,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 @@ -119,6 +119,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 @@ -34,6 +34,9 @@ passes_attr_crate_level =
.suggestion = to apply to the crate, use an inner attribute
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information

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 @@ -223,6 +223,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::RustcMustImplementOneOf { attr_span, fn_names }) => {
self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target)
},
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::EiiExternTarget { .. }
| AttributeKind::EiiExternItem
Expand All @@ -233,7 +239,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::Pointee(..)
| AttributeKind::Dummy
| AttributeKind::RustcBuiltinMacro { .. }
| AttributeKind::Ignore { .. }
| AttributeKind::InstructionSet(..)
| AttributeKind::Path(..)
| AttributeKind::NoImplicitPrelude(..)
Expand Down Expand Up @@ -284,7 +289,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::PassByValue (..)
| AttributeKind::StdInternalSymbol (..)
| AttributeKind::Coverage (..)
| AttributeKind::ShouldPanic { .. }
| AttributeKind::Coroutine(..)
| AttributeKind::Linkage(..)
| AttributeKind::MustUse { .. }
Expand All @@ -306,6 +310,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::CfgAttrTrace
| AttributeKind::ThreadLocal
| AttributeKind::CfiEncoding { .. }
| AttributeKind::TestTrace
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
Expand Down Expand Up @@ -448,6 +453,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 @@ -1360,3 +1360,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 @@ -2263,6 +2263,7 @@ symbols! {
test_case,
test_removed_feature,
test_runner,
test_trace: "<test_trace>",
test_unstable_lint,
thread,
thread_local,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
scope 4 {
debug _x => _8;
}
scope 18 (inlined foo) {
scope 19 (inlined foo) {
let mut _27: *const [()];
}
}
scope 16 (inlined slice_from_raw_parts::<()>) {
scope 17 (inlined std::ptr::from_raw_parts::<[()], ()>) {
scope 17 (inlined slice_from_raw_parts::<()>) {
scope 18 (inlined std::ptr::from_raw_parts::<[()], ()>) {
}
}
}
Expand All @@ -49,19 +49,21 @@
scope 7 {
let _21: std::ptr::NonNull<[u8]>;
scope 8 {
scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) {
scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) {
scope 13 (inlined NonNull::<[u8]>::cast::<u8>) {
scope 12 (inlined NonNull::<[u8]>::as_mut_ptr) {
scope 13 (inlined NonNull::<[u8]>::as_non_null_ptr) {
scope 14 (inlined NonNull::<[u8]>::cast::<u8>) {
let mut _25: *mut [u8];
scope 14 (inlined NonNull::<[u8]>::as_ptr) {
scope 15 (inlined NonNull::<[u8]>::as_ptr) {
}
}
}
scope 15 (inlined NonNull::<u8>::as_ptr) {
scope 16 (inlined NonNull::<u8>::as_ptr) {
}
}
}
scope 10 (inlined <std::alloc::Global as Allocator>::allocate) {
scope 11 (inlined std::alloc::Global::alloc_impl) {
}
}
}
scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) {
Expand Down Expand Up @@ -192,8 +194,8 @@
+ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }};
StorageDead(_24);
StorageLive(_19);
- _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _18, const false) -> [return: bb7, unwind unreachable];
+ _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
- _19 = std::alloc::Global::alloc_impl_runtime(copy _18, const false) -> [return: bb7, unwind unreachable];
+ _19 = std::alloc::Global::alloc_impl_runtime(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable];
}

bb7: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@ fn generic_in_place(_1: *mut Box<[T]>) -> () {
}
}
scope 18 (inlined <std::alloc::Global as Allocator>::deallocate) {
let mut _9: *mut u8;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did these mir-opt tests change?

scope 19 (inlined Layout::size) {
}
scope 20 (inlined NonNull::<u8>::as_ptr) {
}
scope 21 (inlined std::alloc::dealloc) {
let mut _10: usize;
scope 22 (inlined Layout::size) {
}
scope 23 (inlined Layout::align) {
scope 24 (inlined std::ptr::Alignment::as_usize) {
scope 19 (inlined std::alloc::Global::deallocate_impl) {
scope 20 (inlined std::alloc::Global::deallocate_impl_runtime) {
let mut _9: *mut u8;
scope 21 (inlined Layout::size) {
}
scope 22 (inlined NonNull::<u8>::as_ptr) {
}
scope 23 (inlined std::alloc::dealloc) {
let mut _10: usize;
scope 24 (inlined Layout::size) {
}
scope 25 (inlined Layout::align) {
scope 26 (inlined std::ptr::Alignment::as_usize) {
}
}
}
}
}
Expand Down
Loading
Loading