From 27250c6ae62de58749f4d30a913217118fda2480 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 3 May 2020 01:49:15 +0200 Subject: [PATCH 1/3] Add a `MustUse` trait to complement `#[must_use]` --- src/libcore/marker.rs | 10 ++ src/librustc_hir/lang_items.rs | 2 + src/librustc_lint/unused.rs | 111 +++++++++++++++++- src/librustc_span/symbol.rs | 1 + .../atomic-lock-free/atomic_lock_free.rs | 4 + src/test/ui/lint/must-use-trait-blanket.rs | 32 +++++ .../ui/lint/must-use-trait-blanket.stderr | 15 +++ src/test/ui/lint/must-use-trait-in-bounds.rs | 18 +++ .../ui/lint/must-use-trait-in-bounds.stderr | 14 +++ src/test/ui/lint/must-use-trait-message.rs | 22 ++++ .../ui/lint/must-use-trait-message.stderr | 15 +++ src/test/ui/lint/must-use-trait-simple.rs | 18 +++ src/test/ui/lint/must-use-trait-simple.stderr | 14 +++ 13 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/must-use-trait-blanket.rs create mode 100644 src/test/ui/lint/must-use-trait-blanket.stderr create mode 100644 src/test/ui/lint/must-use-trait-in-bounds.rs create mode 100644 src/test/ui/lint/must-use-trait-in-bounds.stderr create mode 100644 src/test/ui/lint/must-use-trait-message.rs create mode 100644 src/test/ui/lint/must-use-trait-message.stderr create mode 100644 src/test/ui/lint/must-use-trait-simple.rs create mode 100644 src/test/ui/lint/must-use-trait-simple.stderr diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 09a8b417e6e22..8b2c198a558d5 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -757,6 +757,16 @@ impl Unpin for *const T {} #[stable(feature = "pin_raw", since = "1.38.0")] impl Unpin for *mut T {} +/// Indicates that a type must be consumed explicitly. +/// +/// cf. `#[must_use]` +#[unstable(feature = "must_use_trait", issue = "none")] +#[cfg_attr(not(bootstrap), lang = "must_use")] +pub trait MustUse { + /// An explanation for why values of this type must be used. + const REASON: &'static str = ""; +} + /// Implementations of `Copy` for primitive types. /// /// Implementations that cannot be described in Rust diff --git a/src/librustc_hir/lang_items.rs b/src/librustc_hir/lang_items.rs index 53f72804a848d..69997200d0a1a 100644 --- a/src/librustc_hir/lang_items.rs +++ b/src/librustc_hir/lang_items.rs @@ -256,4 +256,6 @@ language_item_table! { AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; TerminationTraitLangItem, "termination", termination, Target::Trait; + + MustUseTraitLangItem, "must_use", must_use_trait, Target::Trait; } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index ddd252cb290e4..4f61b2fc61bbf 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -11,14 +11,26 @@ use rustc_feature::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; +use rustc_hir::lang_items::LangItem; use rustc_middle::ty::adjustment; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::{ + mir::interpret::ConstValue, + traits::{specialization_graph, ObligationCause, Vtable}, + ty::{self, Ty}, +}; use rustc_session::lint::builtin::UNUSED_ATTRIBUTES; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span, DUMMY_SP}; +use rustc_trait_selection::{ + infer::TyCtxtInferExt, + traits::{FulfillmentContext, Obligation, SelectionContext, TraitEngine}, +}; +use ty::{AssocKind, Binder, TraitPredicate}; +use ast::Ident; use log::debug; +use std::str; declare_lint! { pub UNUSED_MUST_USE, @@ -134,6 +146,103 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { return true; } + let must_use_trait = match cx.tcx.lang_items().require(LangItem::MustUseTraitLangItem) { + Ok(def_id) => def_id, + Err(s) => { + cx.tcx.sess.fatal(&s); + } + }; + let did = cx.tcx.hir().get_parent_did(expr.hir_id); + let param_env = cx.tcx.param_env(did); + let must_use_reason = cx.tcx.infer_ctxt().enter(|infcx| { + // If `MustUse` is implemented, we want to know the `REASON` value, so we have to + // use the selection context directly and obtain a `VtableImpl`. + let substs = infcx.tcx.mk_substs_trait(ty, &[]); + let trait_ref = ty::TraitRef { def_id: must_use_trait, substs }; + let pred = TraitPredicate { trait_ref }; + let obl = Obligation::new(ObligationCause::dummy(), param_env, Binder::bind(pred)); + + let mut selcx = SelectionContext::new(&infcx); + let vtable = if let Ok(Some(vtable)) = selcx.select(&obl) { + vtable + } else { + // Not implemented. + return None; + }; + + // There is an impl that *might* apply. Make sure it does. + let mut fulfillcx = FulfillmentContext::new(); + fulfillcx.register_bound( + &infcx, + param_env, + ty, + must_use_trait, + ObligationCause::dummy(), + ); + if !fulfillcx.select_all_or_error(&infcx).is_ok() { + // It does not hold. + return None; + } + + let data = match vtable { + // When a concrete impl is known to apply, use its `REASON` value (or any + // parent's in the specialization graph). + Vtable::VtableImpl(data) => data, + + // We might get a `VtableParam` if we have a `T: MustUse` bound. We do lint in + // this case, but cannot know the message. + Vtable::VtableParam(_) => return Some(String::new()), + + // `MustUse` isn't object safe, but could be if assoc. consts were object safe. + // In case that ever happens, don't lint on `dyn MustUse`. + Vtable::VtableObject(_) => return None, + + _ => { + bug!("unexpected vtable for MustUse selection: {:?}", vtable); + } + }; + + let reason_const = if let Ok(ancestors) = + specialization_graph::ancestors(infcx.tcx, must_use_trait, data.impl_def_id) + { + ancestors + .leaf_def(infcx.tcx, Ident::with_dummy_span(sym::REASON), AssocKind::Const) + .expect("could not find MustUse::REASON") + .item + } else { + // Error building the specialization graph. Don't warn. + return None; + }; + + let const_val = if let Ok(const_val) = + infcx.const_eval_resolve(param_env, reason_const.def_id, substs, None, None) + { + const_val + } else { + return None; + }; + + if let ConstValue::Slice { data, start, end } = const_val { + let bytes = data.inspect_with_undef_and_ptr_outside_interpreter(start..end); + Some(String::from_utf8(bytes.to_vec()).unwrap()) + } else { + bug!("unexpected ConstValue for MustUse::REASON: {:?}", const_val); + } + }); + + if let Some(reason) = must_use_reason { + cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + let msg = + format!("unused {}`{}`{} that must be used", descr_pre, ty, descr_post); + let mut err = lint.build(&msg); + if !reason.is_empty() { + err.note(&reason); + } + err.emit(); + }); + return true; + } + let plural_suffix = pluralize!(plural_len); match ty.kind { diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index f194506e66069..c77b2741aed69 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -588,6 +588,7 @@ symbols! { Rc, Ready, reason, + REASON, recursion_limit, reexport_test_harness_main, reflect, diff --git a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs index bc7951a04da86..0494881edf506 100644 --- a/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs +++ b/src/test/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs @@ -12,6 +12,10 @@ trait Sized {} trait Copy {} #[lang = "freeze"] trait Freeze {} +#[lang = "must_use"] +trait MustUse { + const REASON: &'static str = ""; +} impl Copy for *mut T {} diff --git a/src/test/ui/lint/must-use-trait-blanket.rs b/src/test/ui/lint/must-use-trait-blanket.rs new file mode 100644 index 0000000000000..cb6e2a561cec5 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-blanket.rs @@ -0,0 +1,32 @@ +//! Tests the `MustUse` trait implemented with a conditional blanket impl. + +#![feature(must_use_trait)] +#![deny(unused_must_use)] //~ NOTE the lint level is defined here + +use std::marker::MustUse; + +struct Box(T); + +impl Box { + fn new(t: T) -> Self { + Box(t) + } +} + +impl MustUse for Box { + const REASON: &'static str = T::REASON; +} + +struct St; + +impl MustUse for St { + const REASON: &'static str = "because I said so"; +} + +fn main() { + Box::new(St); + //~^ ERROR unused `Box` that must be used + //~| NOTE because I said so + + Box::new(()); +} diff --git a/src/test/ui/lint/must-use-trait-blanket.stderr b/src/test/ui/lint/must-use-trait-blanket.stderr new file mode 100644 index 0000000000000..d6480ee5ccbc8 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-blanket.stderr @@ -0,0 +1,15 @@ +error: unused `Box` that must be used + --> $DIR/must-use-trait-blanket.rs:27:5 + | +LL | Box::new(St); + | ^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must-use-trait-blanket.rs:4:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: because I said so + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must-use-trait-in-bounds.rs b/src/test/ui/lint/must-use-trait-in-bounds.rs new file mode 100644 index 0000000000000..a3e5accebc20e --- /dev/null +++ b/src/test/ui/lint/must-use-trait-in-bounds.rs @@ -0,0 +1,18 @@ +//! Tests that `T: MustUse` bounds do emit the lint. +//! +//! This is rather useless, but at least shouldn't ICE. Maybe it should be forbidden to use +//! `MustUse` in bounds. + +#![feature(must_use_trait)] +#![deny(unused_must_use)] //~ NOTE the lint level is defined here + +use std::marker::MustUse; + +trait Tr: MustUse {} + +fn f(t: T) { + t; + //~^ ERROR unused `T` that must be used +} + +fn main() {} diff --git a/src/test/ui/lint/must-use-trait-in-bounds.stderr b/src/test/ui/lint/must-use-trait-in-bounds.stderr new file mode 100644 index 0000000000000..f2ddf5acb5d15 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-in-bounds.stderr @@ -0,0 +1,14 @@ +error: unused `T` that must be used + --> $DIR/must-use-trait-in-bounds.rs:14:5 + | +LL | t; + | ^^ + | +note: the lint level is defined here + --> $DIR/must-use-trait-in-bounds.rs:7:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must-use-trait-message.rs b/src/test/ui/lint/must-use-trait-message.rs new file mode 100644 index 0000000000000..22d9aa716ae47 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-message.rs @@ -0,0 +1,22 @@ +#![feature(must_use_trait)] +#![deny(unused_must_use)] //~ NOTE the lint level is defined here + +use std::marker::MustUse; + +struct St; + +impl St { + fn new() -> Self { + St + } +} + +impl MustUse for St { + const REASON: &'static str = "because I said so"; +} + +fn main() { + St::new(); + //~^ ERROR unused `St` that must be used + //~| NOTE because I said so +} diff --git a/src/test/ui/lint/must-use-trait-message.stderr b/src/test/ui/lint/must-use-trait-message.stderr new file mode 100644 index 0000000000000..14e830ea37055 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-message.stderr @@ -0,0 +1,15 @@ +error: unused `St` that must be used + --> $DIR/must-use-trait-message.rs:19:5 + | +LL | St::new(); + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must-use-trait-message.rs:2:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + = note: because I said so + +error: aborting due to previous error + diff --git a/src/test/ui/lint/must-use-trait-simple.rs b/src/test/ui/lint/must-use-trait-simple.rs new file mode 100644 index 0000000000000..06c50773a31e8 --- /dev/null +++ b/src/test/ui/lint/must-use-trait-simple.rs @@ -0,0 +1,18 @@ +#![feature(must_use_trait)] +#![deny(unused_must_use)] + +use std::marker::MustUse; + +struct St; + +impl St { + fn new() -> Self { + St + } +} + +impl MustUse for St {} + +fn main() { + St::new(); //~ ERROR unused `St` that must be used +} diff --git a/src/test/ui/lint/must-use-trait-simple.stderr b/src/test/ui/lint/must-use-trait-simple.stderr new file mode 100644 index 0000000000000..10fcf294e906a --- /dev/null +++ b/src/test/ui/lint/must-use-trait-simple.stderr @@ -0,0 +1,14 @@ +error: unused `St` that must be used + --> $DIR/must-use-trait-simple.rs:17:5 + | +LL | St::new(); + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/must-use-trait-simple.rs:2:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From 915931487264279f9bb2e99f1bdae7eecb5ffd47 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sun, 3 May 2020 21:17:24 +0200 Subject: [PATCH 2/3] Make `#[must_use]` a builtin macro The macro just expands to its input and replaces itself with `#[rustc_must_use]` for now. Technically this is a breaking change since it will now error when used as a crate-level attribute. This does nothing, so it should just be removed when that happens. --- src/libcore/macros/mod.rs | 9 + src/libcore/prelude/v1.rs | 5 + src/librustc_builtin_macros/lib.rs | 2 + src/librustc_builtin_macros/must_use.rs | 37 ++ src/librustc_expand/expand.rs | 1 + src/librustc_feature/builtin_attrs.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_span/symbol.rs | 1 + src/libstd/prelude/v1.rs | 5 + .../issue-43106-gating-of-builtin-attrs.rs | 1 - ...issue-43106-gating-of-builtin-attrs.stderr | 374 +++++++++--------- .../issue-43106-gating-of-must_use.rs | 6 + .../issue-43106-gating-of-must_use.stderr | 10 + .../param-attrs-builtin-attrs.rs | 20 +- .../param-attrs-builtin-attrs.stderr | 120 +++--- 16 files changed, 336 insertions(+), 261 deletions(-) create mode 100644 src/librustc_builtin_macros/must_use.rs create mode 100644 src/test/ui/feature-gate/issue-43106-gating-of-must_use.rs create mode 100644 src/test/ui/feature-gate/issue-43106-gating-of-must_use.stderr diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs index 14bfa8bab8939..fb643e61802a7 100644 --- a/src/libcore/macros/mod.rs +++ b/src/libcore/macros/mod.rs @@ -1446,4 +1446,13 @@ pub(crate) mod builtin { pub macro RustcEncodable($item:item) { /* compiler built-in */ } + + /// Indicates that a value must be explicitly consumed by the user. + #[cfg(not(bootstrap))] + #[rustc_builtin_macro] + #[stable(feature = "rust1", since = "1.0.0")] + #[allow_internal_unstable(rustc_attrs)] + pub macro must_use($item:item) { + /* compiler built-in */ + } } diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs index b4fff3d67b555..0afc9ddebc57f 100644 --- a/src/libcore/prelude/v1.rs +++ b/src/libcore/prelude/v1.rs @@ -76,3 +76,8 @@ pub use crate::macros::builtin::{ )] #[doc(no_inline)] pub use crate::macros::builtin::cfg_accessible; + +#[cfg(not(bootstrap))] +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[doc(no_inline)] +pub use crate::macros::builtin::must_use; diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs index bc1767a1238f8..e97d998cf5d6c 100644 --- a/src/librustc_builtin_macros/lib.rs +++ b/src/librustc_builtin_macros/lib.rs @@ -34,6 +34,7 @@ mod global_allocator; mod global_asm; mod llvm_asm; mod log_syntax; +mod must_use; mod source_util; mod test; mod trace_macros; @@ -92,6 +93,7 @@ pub fn register_builtin_macros(resolver: &mut dyn Resolver, edition: Edition) { global_allocator: global_allocator::expand, test: test::expand_test, test_case: test::expand_test_case, + must_use: must_use::expand, } register_derive! { diff --git a/src/librustc_builtin_macros/must_use.rs b/src/librustc_builtin_macros/must_use.rs new file mode 100644 index 0000000000000..1df2592517ae2 --- /dev/null +++ b/src/librustc_builtin_macros/must_use.rs @@ -0,0 +1,37 @@ +use ast::{AttrStyle, Ident, MacArgs, Path}; +use rustc_ast::{ast, tokenstream::TokenStream}; +use rustc_attr::{mk_attr, HasAttrs}; +use rustc_expand::base::{Annotatable, ExtCtxt}; +use rustc_feature::BUILTIN_ATTRIBUTE_MAP; +use rustc_parse::validate_attr; +use rustc_span::{sym, Span}; + +pub fn expand( + ecx: &mut ExtCtxt<'_>, + span: Span, + meta: &ast::MetaItem, + mut item: Annotatable, +) -> Vec { + // Validate input against the `#[rustc_must_use]` template. + let (_, _, template, _) = &BUILTIN_ATTRIBUTE_MAP[&sym::rustc_must_use]; + let attr = ecx.attribute(meta.clone()); + validate_attr::check_builtin_attribute(ecx.parse_sess, &attr, sym::must_use, template.clone()); + + let reason = meta.name_value_literal(); + let mac_args = match reason { + None => MacArgs::Empty, + Some(lit) => MacArgs::Eq(span, TokenStream::new(vec![lit.token_tree().into()])), + }; + + // def-site context makes rustc accept the unstable `rustc_must_use` + let span = ecx.with_def_site_ctxt(item.span()); + item.visit_attrs(|attrs| { + attrs.push(mk_attr( + AttrStyle::Outer, + Path::from_ident(Ident::with_dummy_span(sym::rustc_must_use)), + mac_args, + span, + )); + }); + vec![item] +} diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs index 972e75d201b90..15ea3a36ff5c8 100644 --- a/src/librustc_expand/expand.rs +++ b/src/librustc_expand/expand.rs @@ -1084,6 +1084,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { if !self.cx.ecfg.custom_inner_attributes() && attr.style == ast::AttrStyle::Inner && !attr.has_name(sym::test) + && !attr.has_name(sym::must_use) { feature_err( &self.cx.parse_sess, diff --git a/src/librustc_feature/builtin_attrs.rs b/src/librustc_feature/builtin_attrs.rs index 466b318bca730..697b3c5c339d4 100644 --- a/src/librustc_feature/builtin_attrs.rs +++ b/src/librustc_feature/builtin_attrs.rs @@ -202,7 +202,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), - ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")), // FIXME(#14407) ungated!( deprecated, Normal, @@ -440,6 +439,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Diagnostics related: // ========================================================================== + rustc_attr!(rustc_must_use, Whitelisted, template!(Word, NameValueStr: "reason"), IMPL_DETAIL), rustc_attr!( rustc_on_unimplemented, Whitelisted, template!( diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 4f61b2fc61bbf..20a3141ffdf45 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -327,7 +327,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { descr_post_path: &str, ) -> bool { for attr in cx.tcx.get_attrs(def_id).iter() { - if attr.check_name(sym::must_use) { + if attr.check_name(sym::rustc_must_use) { cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { let msg = format!( "unused {}`{}`{} that must be used", diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index aa78ac609457f..76fde0f68f940 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -293,7 +293,7 @@ impl<'a> base::Resolver for Resolver<'a> { invoc_id.set_expn_data(ext.expn_data(parent_scope.expansion, span, fast_print_path(path))); if let Res::Def(_, def_id) = res { - if after_derive { + if after_derive && !ext.is_builtin { self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); } self.macro_defs.insert(invoc_id, def_id); diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index c77b2741aed69..f9f159d87e9b6 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -648,6 +648,7 @@ symbols! { rustc_layout_scalar_valid_range_start, rustc_macro_transparency, rustc_mir, + rustc_must_use, rustc_nonnull_optimization_guaranteed, rustc_object_lifetime_default, rustc_on_unimplemented, diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs index 0fbd6b62f18ff..ee9aaaf245484 100644 --- a/src/libstd/prelude/v1.rs +++ b/src/libstd/prelude/v1.rs @@ -62,6 +62,11 @@ pub use core::prelude::v1::{ #[doc(hidden)] pub use core::prelude::v1::cfg_accessible; +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[cfg(not(bootstrap))] +#[doc(hidden)] +pub use core::prelude::v1::must_use; + // The file so far is equivalent to src/libcore/prelude/v1.rs, // and below to src/liballoc/prelude.rs. // Those files are duplicated rather than using glob imports diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index f702b10ccd126..3ffa5fcb74f70 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -77,7 +77,6 @@ #![link_name = "1900"] #![link_section = "1800"] // see issue-43106-gating-of-rustc_deprecated.rs -#![must_use] // see issue-43106-gating-of-stable.rs // see issue-43106-gating-of-unstable.rs // see issue-43106-gating-of-deprecated.rs diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 02bed6723bf72..171c01c6c62f7 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -29,157 +29,157 @@ LL | #![deny(x5100)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:105:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:104:8 | LL | #[warn(x5400)] | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:108:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:107:25 | LL | mod inner { #![warn(x5400)] } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:111:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:110:12 | LL | #[warn(x5400)] fn f() { } | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:114:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:113:12 | LL | #[warn(x5400)] struct S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:117:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:12 | LL | #[warn(x5400)] type T = S; | ^^^^^ warning: unknown lint: `x5400` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:120:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:12 | LL | #[warn(x5400)] impl S { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:9 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:123:9 | LL | #[allow(x5300)] | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:26 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:126:26 | LL | mod inner { #![allow(x5300)] } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:130:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:129:13 | LL | #[allow(x5300)] fn f() { } | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:133:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:132:13 | LL | #[allow(x5300)] struct S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:136:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:13 | LL | #[allow(x5300)] type T = S; | ^^^^^ warning: unknown lint: `x5300` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:139:13 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:13 | LL | #[allow(x5300)] impl S { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:10 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:142:10 | LL | #[forbid(x5200)] | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:27 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:145:27 | LL | mod inner { #![forbid(x5200)] } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:149:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:148:14 | LL | #[forbid(x5200)] fn f() { } | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:152:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:151:14 | LL | #[forbid(x5200)] struct S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:155:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:14 | LL | #[forbid(x5200)] type T = S; | ^^^^^ warning: unknown lint: `x5200` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:158:14 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:14 | LL | #[forbid(x5200)] impl S { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:8 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:161:8 | LL | #[deny(x5100)] | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:25 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:164:25 | LL | mod inner { #![deny(x5100)] } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:168:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:167:12 | LL | #[deny(x5100)] fn f() { } | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:171:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:170:12 | LL | #[deny(x5100)] struct S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:174:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:173:12 | LL | #[deny(x5100)] type T = S; | ^^^^^ warning: unknown lint: `x5100` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:12 | LL | #[deny(x5100)] impl S { } | ^^^^^ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:465:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:17 | LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | mod inner { #![macro_escape] } = help: try an outer attribute: `#[macro_use]` warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:17 | LL | mod inner { #![plugin_registrar] } | ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version @@ -195,25 +195,25 @@ LL | mod inner { #![plugin_registrar] } = note: `#[warn(deprecated)]` on by default warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:5 | LL | #[plugin_registrar] struct S; | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:230:5 | LL | #[plugin_registrar] type T = S; | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5 | LL | #[plugin_registrar] impl S { } | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:1 | LL | #[plugin_registrar] | ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version @@ -225,19 +225,19 @@ LL | #![plugin_registrar] | ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version warning: use of deprecated attribute `crate_id`: no longer used. - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:91:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:1 | LL | #![crate_id = "10"] | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute warning: use of deprecated attribute `no_start`: no longer used. - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:96:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:95:1 | LL | #![no_start] | ^^^^^^^^^^^^ help: remove this attribute warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:12 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:93:12 | LL | #![feature(rust1)] | ^^^^^ @@ -245,7 +245,7 @@ LL | #![feature(rust1)] = note: `#[warn(stable_features)]` on by default warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:184:5 | LL | #[macro_use] fn f() { } | ^^^^^^^^^^^^ @@ -257,913 +257,913 @@ LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:188:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:187:5 | LL | #[macro_use] struct S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:191:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:5 | LL | #[macro_use] type T = S; | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:194:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:193:5 | LL | #[macro_use] impl S { } | ^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:200:17 | LL | mod inner { #![macro_export] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:203:5 | LL | #[macro_export] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:207:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:206:5 | LL | #[macro_export] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:210:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:209:5 | LL | #[macro_export] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:213:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:212:5 | LL | #[macro_export] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:197:1 | LL | #[macro_export] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:220:17 | LL | mod inner { #![plugin_registrar] } | ^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:226:5 | LL | #[plugin_registrar] struct S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:231:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:230:5 | LL | #[plugin_registrar] type T = S; | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:235:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:234:5 | LL | #[plugin_registrar] impl S { } | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:217:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:1 | LL | #[plugin_registrar] | ^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:243:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:242:17 | LL | mod inner { #![main] } | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:248:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:5 | LL | #[main] struct S; | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:251:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5 | LL | #[main] type T = S; | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:254:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5 | LL | #[main] impl S { } | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:240:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:239:1 | LL | #[main] | ^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:261:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:17 | LL | mod inner { #![start] } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:265:5 | LL | #[start] struct S; | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:268:5 | LL | #[start] type T = S; | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:271:5 | LL | #[start] impl S { } | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:1 | LL | #[start] | ^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:5 | LL | #[path = "3800"] fn f() { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:328:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:327:5 | LL | #[path = "3800"] struct S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:331:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5 | LL | #[path = "3800"] type T = S; | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:334:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:5 | LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:341:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:340:17 | LL | mod inner { #![automatically_derived] } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:344:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:5 | LL | #[automatically_derived] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:347:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:346:5 | LL | #[automatically_derived] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:349:5 | LL | #[automatically_derived] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:352:5 | LL | #[automatically_derived] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:338:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:337:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:373:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:372:17 | LL | mod inner { #![no_link] } | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:376:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:5 | LL | #[no_link] fn f() { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:379:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:5 | LL | #[no_link] struct S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:382:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:381:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:385:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:369:1 | LL | #[no_link] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:392:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:391:17 | LL | mod inner { #![should_panic] } | ^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:5 | LL | #[should_panic] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:5 | LL | #[should_panic] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:400:5 | LL | #[should_panic] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:403:5 | LL | #[should_panic] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:388:1 | LL | #[should_panic] | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:17 | LL | mod inner { #![ignore] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:413:5 | LL | #[ignore] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:416:5 | LL | #[ignore] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:419:5 | LL | #[ignore] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:422:5 | LL | #[ignore] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:1 | LL | #[ignore] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:17 | LL | mod inner { #![no_implicit_prelude] } | ^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:433:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:432:5 | LL | #[no_implicit_prelude] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:436:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:435:5 | LL | #[no_implicit_prelude] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:439:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:438:5 | LL | #[no_implicit_prelude] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:442:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:441:5 | LL | #[no_implicit_prelude] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:1 | LL | #[no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:449:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:448:17 | LL | mod inner { #![reexport_test_harness_main="2900"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:452:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:5 | LL | #[reexport_test_harness_main = "2900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:455:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:454:5 | LL | #[reexport_test_harness_main = "2900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:458:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:5 | LL | #[reexport_test_harness_main = "2900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:461:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:460:5 | LL | #[reexport_test_harness_main = "2900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:446:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:445:1 | LL | #[reexport_test_harness_main = "2900"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:472:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:471:5 | LL | #[macro_escape] fn f() { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:475:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5 | LL | #[macro_escape] struct S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:478:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:477:5 | LL | #[macro_escape] type T = S; | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:481:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:5 | LL | #[macro_escape] impl S { } | ^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:489:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:488:17 | LL | mod inner { #![no_std] } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:5 | LL | #[no_std] fn f() { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:497:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:497:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:496:5 | LL | #[no_std] struct S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:501:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:500:5 | LL | #[no_std] type T = S; | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:504:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:505:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:504:5 | LL | #[no_std] impl S { } | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:1 | LL | #[no_std] | ^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:484:1 | LL | #[no_std] | ^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643:17 | LL | mod inner { #![crate_name="0900"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:648:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:648:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5 | LL | #[crate_name = "0900"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:652:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:652:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:651:5 | LL | #[crate_name = "0900"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:656:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:655:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:656:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:655:5 | LL | #[crate_name = "0900"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:5 | LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:640:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:640:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:639:1 | LL | #[crate_name = "0900"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668:17 | LL | mod inner { #![crate_type="0800"] } | ^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:672:5 | LL | #[crate_type = "0800"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:677:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:677:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:5 | LL | #[crate_type = "0800"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:680:5 | LL | #[crate_type = "0800"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5 | LL | #[crate_type = "0800"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:665:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:664:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:665:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:664:1 | LL | #[crate_type = "0800"] | ^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:694:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:17 | LL | mod inner { #![feature(x0600)] } | ^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:698:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:698:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:697:5 | LL | #[feature(x0600)] fn f() { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:5 | LL | #[feature(x0600)] struct S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:706:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5 | LL | #[feature(x0600)] type T = S; | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:709:5 | LL | #[feature(x0600)] impl S { } | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:689:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:689:1 | LL | #[feature(x0600)] | ^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:719:17 | LL | mod inner { #![no_main] } | ^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5 | LL | #[no_main] fn f() { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:728:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5 | LL | #[no_main] struct S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:5 | LL | #[no_main] type T = S; | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:735:5 | LL | #[no_main] impl S { } | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:1 | LL | #[no_main] | ^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:716:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:1 | LL | #[no_main] | ^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:757:17 | LL | mod inner { #![recursion_limit="0200"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:5 | LL | #[recursion_limit="0200"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:766:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5 | LL | #[recursion_limit="0200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:769:5 | LL | #[recursion_limit="0200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:774:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:774:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:773:5 | LL | #[recursion_limit="0200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:754:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:1 | LL | #[recursion_limit="0200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be in the root module - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:783:17 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:782:17 | LL | mod inner { #![type_length_limit="0100"] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:787:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:787:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:786:5 | LL | #[type_length_limit="0100"] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:791:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:791:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:790:5 | LL | #[type_length_limit="0100"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:795:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:795:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:794:5 | LL | #[type_length_limit="0100"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:799:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:799:5 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:798:5 | LL | #[type_length_limit="0100"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: unused attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:779:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:778:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]` - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:779:1 + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:778:1 | LL | #[type_length_limit="0100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-must_use.rs b/src/test/ui/feature-gate/issue-43106-gating-of-must_use.rs new file mode 100644 index 0000000000000..2343b6fe1aa01 --- /dev/null +++ b/src/test/ui/feature-gate/issue-43106-gating-of-must_use.rs @@ -0,0 +1,6 @@ +// The non-crate level cases are in issue-43106-gating-of-builtin-attrs.rs. + +#![must_use = "4200"] +//~^ ERROR cannot determine resolution for the attribute macro `must_use` + +fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-must_use.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-must_use.stderr new file mode 100644 index 0000000000000..10f11e17d10d1 --- /dev/null +++ b/src/test/ui/feature-gate/issue-43106-gating-of-must_use.stderr @@ -0,0 +1,10 @@ +error: cannot determine resolution for the attribute macro `must_use` + --> $DIR/issue-43106-gating-of-must_use.rs:3:4 + | +LL | #![must_use = "4200"] + | ^^^^^^^^ + | + = note: import resolution is stuck, try simplifying macro imports + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs index bf09171c9a12a..6916032f2ee1b 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs @@ -7,7 +7,7 @@ extern "C" { /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -23,7 +23,7 @@ type FnType = fn( /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -38,7 +38,7 @@ pub fn foo( /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -58,7 +58,7 @@ impl SelfStruct { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -73,7 +73,7 @@ impl SelfStruct { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -94,7 +94,7 @@ impl RefStruct { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -113,7 +113,7 @@ trait RefTrait { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -128,7 +128,7 @@ trait RefTrait { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -148,7 +148,7 @@ impl RefTrait for RefStruct { /// Baz //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, @@ -165,7 +165,7 @@ fn main() { /// Bar //~^ ERROR documentation comments cannot be applied to function #[must_use] - //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in + //~^ ERROR expected an inert attribute, found an attribute macro /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32 diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr index 4d0349e8765f0..e602688cd8e9d 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr @@ -4,60 +4,120 @@ error: expected an inert attribute, found an attribute macro LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:9:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:21:5 | LL | #[test] a: u32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:25:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:36:5 | LL | #[test] a: u32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:40:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:56:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:60:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:71:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:75:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:92:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:96:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:111:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:115:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:126:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:130:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:146:9 | LL | #[test] a: i32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:150:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: expected an inert attribute, found an attribute macro --> $DIR/param-attrs-builtin-attrs.rs:163:9 | LL | #[test] a: u32, | ^^^^^^^ +error: expected an inert attribute, found an attribute macro + --> $DIR/param-attrs-builtin-attrs.rs:167:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:3:9 | @@ -70,12 +130,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Bar | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:9:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:11:9 | @@ -100,12 +154,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Bar | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:25:5 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:27:5 | @@ -130,12 +178,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Bar | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:40:5 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:42:5 | @@ -166,12 +208,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:60:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:62:9 | @@ -196,12 +232,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:75:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:77:9 | @@ -232,12 +262,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:96:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:98:9 | @@ -268,12 +292,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:115:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:117:9 | @@ -298,12 +316,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:130:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:132:9 | @@ -334,12 +346,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Baz | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:150:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:152:9 | @@ -364,12 +370,6 @@ error: documentation comments cannot be applied to function parameters LL | /// Bar | ^^^^^^^ doc comments are not allowed here -error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:167:9 - | -LL | #[must_use] - | ^^^^^^^^^^^ - error: documentation comments cannot be applied to function parameters --> $DIR/param-attrs-builtin-attrs.rs:169:9 | From 76c59e1cd4c40393a75e63907c5181ce93ddb9a1 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 5 May 2020 00:03:10 +0200 Subject: [PATCH 3/3] Expand `#[must_use]` on types to a `MustUse` impl --- src/libcore/macros/mod.rs | 2 +- src/librustc_builtin_macros/must_use.rs | 163 +++++++++++++++++- src/librustc_lint/unused.rs | 1 - src/librustc_middle/middle/stability.rs | 4 +- src/librustc_span/lib.rs | 14 +- src/librustc_span/symbol.rs | 1 + src/librustdoc/clean/types.rs | 12 ++ src/test/ui/lint/must_use-default-ty-param.rs | 14 ++ .../ui/lint/must_use-forbid-deprecated.rs | 11 ++ src/test/ui/lint/must_use-tuple.rs | 10 +- src/test/ui/lint/must_use-tuple.stderr | 10 +- .../ui/macros/must-use-in-macro-55516.stderr | 2 +- 12 files changed, 219 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/lint/must_use-default-ty-param.rs create mode 100644 src/test/ui/lint/must_use-forbid-deprecated.rs diff --git a/src/libcore/macros/mod.rs b/src/libcore/macros/mod.rs index fb643e61802a7..9b19a948bf091 100644 --- a/src/libcore/macros/mod.rs +++ b/src/libcore/macros/mod.rs @@ -1451,7 +1451,7 @@ pub(crate) mod builtin { #[cfg(not(bootstrap))] #[rustc_builtin_macro] #[stable(feature = "rust1", since = "1.0.0")] - #[allow_internal_unstable(rustc_attrs)] + #[allow_internal_unstable(rustc_attrs, must_use_trait)] pub macro must_use($item:item) { /* compiler built-in */ } diff --git a/src/librustc_builtin_macros/must_use.rs b/src/librustc_builtin_macros/must_use.rs index 1df2592517ae2..b74b110fb41f8 100644 --- a/src/librustc_builtin_macros/must_use.rs +++ b/src/librustc_builtin_macros/must_use.rs @@ -1,10 +1,11 @@ -use ast::{AttrStyle, Ident, MacArgs, Path}; -use rustc_ast::{ast, tokenstream::TokenStream}; +use ast::{AttrStyle, Ident, MacArgs}; +use rustc_ast::{ast, ptr::P, tokenstream::TokenStream}; use rustc_attr::{mk_attr, HasAttrs}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_feature::BUILTIN_ATTRIBUTE_MAP; use rustc_parse::validate_attr; -use rustc_span::{sym, Span}; +use rustc_span::{sym, symbol::kw, Span}; +use std::iter; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -23,15 +24,163 @@ pub fn expand( Some(lit) => MacArgs::Eq(span, TokenStream::new(vec![lit.token_tree().into()])), }; - // def-site context makes rustc accept the unstable `rustc_must_use` - let span = ecx.with_def_site_ctxt(item.span()); + // def-site context makes rustc accept the unstable `rustc_must_use` and `MustUse` trait. + let def_span = ecx.with_def_site_ctxt(item.span()); + + // Put a `#[rustc_must_use]` on the item in any case. This allows rustdoc to pick it up and + // render it. item.visit_attrs(|attrs| { attrs.push(mk_attr( AttrStyle::Outer, - Path::from_ident(Ident::with_dummy_span(sym::rustc_must_use)), + ast::Path::from_ident(Ident::with_dummy_span(sym::rustc_must_use)), mac_args, - span, + def_span, )); }); + + // This macro desugars `#[must_use]` on types to `impl`s of the `MustUse` trait. + // Any other uses are forwarded to the `#[rustc_must_use]` macro. + if let Annotatable::Item(ast_item) = &item { + match &ast_item.kind { + ast::ItemKind::Enum(_, generics) + | ast::ItemKind::Struct(_, generics) + | ast::ItemKind::Union(_, generics) => { + // Generate a derive-style impl for a concrete type. + let impl_items = if let Some(reason) = reason { + let item = ast::AssocItem { + attrs: vec![], + id: ast::DUMMY_NODE_ID, + span: def_span, + vis: ast::Visibility { + node: ast::VisibilityKind::Inherited, + span: def_span, + }, + ident: Ident::new(sym::REASON, def_span), + kind: ast::AssocItemKind::Const( + ast::Defaultness::Final, + ecx.ty( + def_span, + ast::TyKind::Rptr( + Some(ecx.lifetime( + def_span, + Ident::new(kw::StaticLifetime, def_span), + )), + ecx.ty_mt( + ecx.ty_ident(def_span, Ident::new(sym::str, def_span)), + ast::Mutability::Not, + ), + ), + ), + Some(ecx.expr_lit(def_span, reason.kind.clone())), + ), + tokens: None, + }; + + vec![P(item)] + } else { + vec![] + }; + + let mut impl_generics = generics.clone(); + for param in impl_generics.params.iter_mut() { + match &mut param.kind { + ast::GenericParamKind::Type { default } => { + // Delete defaults as they're not usable in impls. + *default = None; + } + + ast::GenericParamKind::Lifetime + | ast::GenericParamKind::Const { ty: _ } => {} + } + } + let new_impl = ast::ItemKind::Impl { + unsafety: ast::Unsafe::No, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + constness: ast::Const::No, + generics: impl_generics, + of_trait: Some(ecx.trait_ref(ecx.path( + def_span, + vec![ + Ident::new(kw::DollarCrate, def_span), + Ident::new(sym::marker, def_span), + Ident::new(sym::MustUse, def_span), + ], + ))), + self_ty: ecx.ty_path( + ecx.path_all( + def_span, + false, + vec![ast_item.ident], + generics + .params + .iter() + .map(|param| match ¶m.kind { + ast::GenericParamKind::Lifetime => ast::GenericArg::Lifetime( + ecx.lifetime(def_span, param.ident), + ), + ast::GenericParamKind::Type { default: _ } => { + ast::GenericArg::Type(ecx.ty_ident(def_span, param.ident)) + } + ast::GenericParamKind::Const { ty: _ } => { + ast::GenericArg::Const( + ecx.const_ident(def_span, param.ident), + ) + } + }) + .collect(), + ), + ), + items: impl_items, + }; + + // Copy some important attributes from the original item, just like the built-in + // derives. + let attrs = ast_item + .attrs + .iter() + .filter(|a| { + [sym::allow, sym::warn, sym::deny, sym::forbid, sym::stable, sym::unstable] + .contains(&a.name_or_empty()) + }) + .cloned() + .chain(iter::once( + ecx.attribute(ecx.meta_word(def_span, sym::automatically_derived)), + )) + .collect(); + + let new_impl = + Annotatable::Item(ecx.item(def_span, Ident::invalid(), attrs, new_impl)); + + return vec![item, new_impl]; + } + + ast::ItemKind::Trait(_, _, _, _, _) => { + // Generate a blanket `impl MustUse for T` impl. + // FIXME(jschievink): This currently doesn't work due to overlapping impls. Even + // with specialization, you couldn't implement 2 `#[must_use]` traits for the same + // type. + // Technically, we could permit overlapping impls here, since it cannot lead to + // unsoundness. At worst, the lint will only print one of the applicable messages + // (though it could attempt to collect messages from all impls that are known to + // apply). + } + + ast::ItemKind::TraitAlias(_, _) + | ast::ItemKind::Impl { .. } + | ast::ItemKind::MacCall(..) + | ast::ItemKind::MacroDef(..) + | ast::ItemKind::ExternCrate(..) + | ast::ItemKind::Use(..) + | ast::ItemKind::Static(..) + | ast::ItemKind::Const(..) + | ast::ItemKind::Fn(..) + | ast::ItemKind::Mod(..) + | ast::ItemKind::ForeignMod(..) + | ast::ItemKind::GlobalAsm(..) + | ast::ItemKind::TyAlias(..) => {} + } + } + vec![item] } diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 20a3141ffdf45..69e5a1f1dfa67 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -251,7 +251,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults { let descr_pre = &format!("{}boxed ", descr_pre); check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) } - ty::Adt(def, _) => check_must_use_def(cx, def.did, span, descr_pre, descr_post), ty::Opaque(def, _) => { let mut has_emitted = false; for (predicate, _) in cx.tcx.predicates_of(def).predicates { diff --git a/src/librustc_middle/middle/stability.rs b/src/librustc_middle/middle/stability.rs index 54c05bca3bd2b..d2b56257b3d6d 100644 --- a/src/librustc_middle/middle/stability.rs +++ b/src/librustc_middle/middle/stability.rs @@ -201,7 +201,7 @@ pub fn early_report_deprecation( lint: &'static Lint, span: Span, ) { - if span.in_derive_expansion() { + if span.in_expansion_ignoring_deprecation() { return; } @@ -217,7 +217,7 @@ fn late_report_deprecation( span: Span, hir_id: HirId, ) { - if span.in_derive_expansion() { + if span.in_expansion_ignoring_deprecation() { return; } diff --git a/src/librustc_span/lib.rs b/src/librustc_span/lib.rs index 060ad604369fb..d9c0e77c77a44 100644 --- a/src/librustc_span/lib.rs +++ b/src/librustc_span/lib.rs @@ -13,6 +13,7 @@ #![feature(nll)] #![feature(optin_builtin_traits)] #![feature(specialization)] +#![feature(or_patterns)] use rustc_data_structures::AtomicRef; use rustc_macros::HashStable_Generic; @@ -286,9 +287,16 @@ impl Span { self.ctxt() != SyntaxContext::root() } - /// Returns `true` if `span` originates in a derive-macro's expansion. - pub fn in_derive_expansion(self) -> bool { - matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _)) + /// Returns `true` if `span` originates in a macro expansion that should ignore `#[deprecated]` + /// items. + /// + /// This is used to avoid undesired warnings when a type is marked as `#[deprecated]`. + pub fn in_expansion_ignoring_deprecation(self) -> bool { + match self.ctxt().outer_expn_data().kind { + ExpnKind::Macro(MacroKind::Derive, _) => true, + ExpnKind::Macro(MacroKind::Attr, sym::must_use) => true, + _ => false, + } } #[inline] diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index f9f159d87e9b6..e395e8c240661 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -470,6 +470,7 @@ symbols! { movbe_target_feature, mul_with_overflow, must_use, + MustUse, naked, naked_functions, name, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 0a682857b1825..4fd68cd3f65a6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -506,6 +506,18 @@ impl Attributes { let other_attrs = attrs .iter() .filter_map(|attr| { + // We want to render `#[must_use]`, but that's a macro that expands to + // `#[rustc_must_use]` (and possibly a `MustUse` impl), so turn that back into + // `#[must_use]` here. + if attr.name_or_empty().as_str() == "rustc_must_use" { + let mut attr = attr.clone(); + if let ast::AttrKind::Normal(item) = &mut attr.kind { + item.path = ast::Path::from_ident(Ident::new(sym::must_use, DUMMY_SP)); + } + + return Some(attr); + } + if let Some(value) = attr.doc_str() { let (value, mk_fragment): (_, fn(_, _, _) -> _) = if attr.is_doc_comment() { (strip_doc_comment_decoration(&value.as_str()), DocFragment::SugaredDoc) diff --git a/src/test/ui/lint/must_use-default-ty-param.rs b/src/test/ui/lint/must_use-default-ty-param.rs new file mode 100644 index 0000000000000..8eb7bbb8b033a --- /dev/null +++ b/src/test/ui/lint/must_use-default-ty-param.rs @@ -0,0 +1,14 @@ +//! Tests that the lowering of `#[must_use]` compiles in presence of defaulted type parameters. + +// check-pass + +#![deny(unused_must_use)] + +trait Tr { + type Assoc; +} + +#[must_use] +struct Generic::Assoc>(T, U); + +fn main() {} diff --git a/src/test/ui/lint/must_use-forbid-deprecated.rs b/src/test/ui/lint/must_use-forbid-deprecated.rs new file mode 100644 index 0000000000000..cdc140b3ae4e8 --- /dev/null +++ b/src/test/ui/lint/must_use-forbid-deprecated.rs @@ -0,0 +1,11 @@ +//! Tests that the lowering of `#[must_use]` compiles in presence of `#![forbid(deprecated)]`. + +// check-pass + +#![deny(unused_must_use)] +#![forbid(deprecated)] + +#[must_use] +struct S; + +fn main() {} diff --git a/src/test/ui/lint/must_use-tuple.rs b/src/test/ui/lint/must_use-tuple.rs index f6b579a7f35cf..91dbc76fb0327 100644 --- a/src/test/ui/lint/must_use-tuple.rs +++ b/src/test/ui/lint/must_use-tuple.rs @@ -5,13 +5,13 @@ fn foo() -> (Result<(), ()>, ()) { } fn main() { - (Ok::<(), ()>(()),); //~ ERROR unused `std::result::Result` + (Ok::<(), ()>(()),); //~ ERROR unused `std::result::Result (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); - //~^ ERROR unused `std::result::Result` - //~^^ ERROR unused `std::result::Result` + //~^ ERROR unused `std::result::Result + //~| ERROR unused `std::result::Result - foo(); //~ ERROR unused `std::result::Result` + foo(); //~ ERROR unused `std::result::Result - ((Err::<(), ()>(()), ()), ()); //~ ERROR unused `std::result::Result` + ((Err::<(), ()>(()), ()), ()); //~ ERROR unused `std::result::Result } diff --git a/src/test/ui/lint/must_use-tuple.stderr b/src/test/ui/lint/must_use-tuple.stderr index de3c6f46c6867..847b9d20f5e4d 100644 --- a/src/test/ui/lint/must_use-tuple.stderr +++ b/src/test/ui/lint/must_use-tuple.stderr @@ -1,4 +1,4 @@ -error: unused `std::result::Result` in tuple element 0 that must be used +error: unused `std::result::Result<(), ()>` in tuple element 0 that must be used --> $DIR/must_use-tuple.rs:8:6 | LL | (Ok::<(), ()>(()),); @@ -11,7 +11,7 @@ LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ = note: this `Result` may be an `Err` variant, which should be handled -error: unused `std::result::Result` in tuple element 0 that must be used +error: unused `std::result::Result<(), ()>` in tuple element 0 that must be used --> $DIR/must_use-tuple.rs:10:6 | LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); @@ -19,7 +19,7 @@ LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); | = note: this `Result` may be an `Err` variant, which should be handled -error: unused `std::result::Result` in tuple element 2 that must be used +error: unused `std::result::Result<(), ()>` in tuple element 2 that must be used --> $DIR/must_use-tuple.rs:10:27 | LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); @@ -27,7 +27,7 @@ LL | (Ok::<(), ()>(()), 0, Ok::<(), ()>(()), 5); | = note: this `Result` may be an `Err` variant, which should be handled -error: unused `std::result::Result` in tuple element 0 that must be used +error: unused `std::result::Result<(), ()>` in tuple element 0 that must be used --> $DIR/must_use-tuple.rs:14:5 | LL | foo(); @@ -35,7 +35,7 @@ LL | foo(); | = note: this `Result` may be an `Err` variant, which should be handled -error: unused `std::result::Result` in tuple element 0 that must be used +error: unused `std::result::Result<(), ()>` in tuple element 0 that must be used --> $DIR/must_use-tuple.rs:16:6 | LL | ((Err::<(), ()>(()), ()), ()); diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr index a694c887085f0..99f63f1b3c0c5 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.stderr +++ b/src/test/ui/macros/must-use-in-macro-55516.stderr @@ -1,4 +1,4 @@ -warning: unused `std::result::Result` that must be used +warning: unused `std::result::Result<(), std::fmt::Error>` that must be used --> $DIR/must-use-in-macro-55516.rs:9:5 | LL | write!(&mut example, "{}", 42);