From 8bbb2d057d1084368412f5236dfad8990ef98e49 Mon Sep 17 00:00:00 2001 From: Danuel Date: Mon, 1 Feb 2021 23:35:53 +0900 Subject: [PATCH] Fixed #[inline] to be warned in fields, arms, macro defs Add visitors for checking #[inline] Add visitors for checking #[inline] with struct field Fix test for #[inline] Add visitors for checking #[inline] with #[macro_export] macro Add visitors for checking #[inline] without #[macro_export] macro Add use alias with Visitor Fix lint error Reduce unnecessary variable Co-authored-by: LingMan Change error to warning Add warning for checking field, arm with #[allow_internal_unstable] Add name resolver Formatting Formatting Fix error fixture Add checking field, arm, macro def --- compiler/rustc_hir/src/target.rs | 6 + compiler/rustc_middle/src/hir/map/mod.rs | 18 + compiler/rustc_passes/src/check_attr.rs | 308 +++++++++++++++--- src/test/ui/attr-usage-inline.rs | 16 + src/test/ui/attr-usage-inline.stderr | 8 +- src/test/ui/internal/internal-unstable.rs | 13 + src/test/ui/internal/internal-unstable.stderr | 10 +- .../ui/proc-macro/ambiguous-builtin-attrs.rs | 4 +- .../proc-macro/ambiguous-builtin-attrs.stderr | 11 +- 9 files changed, 341 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 2774cc9c08e16..6dbcfb963ee0e 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -38,12 +38,14 @@ pub enum Target { Enum, Variant, Struct, + Field, Union, Trait, TraitAlias, Impl, Expression, Statement, + Arm, AssocConst, Method(MethodKind), AssocTy, @@ -51,6 +53,7 @@ pub enum Target { ForeignStatic, ForeignTy, GenericParam(GenericParamKind), + MacroDef, } impl Display for Target { @@ -73,12 +76,14 @@ impl Display for Target { Target::Enum => "enum", Target::Variant => "enum variant", Target::Struct => "struct", + Target::Field => "struct field", Target::Union => "union", Target::Trait => "trait", Target::TraitAlias => "trait alias", Target::Impl => "item", Target::Expression => "expression", Target::Statement => "statement", + Target::Arm => "match arm", Target::AssocConst => "associated const", Target::Method(_) => "method", Target::AssocTy => "associated type", @@ -90,6 +95,7 @@ impl Display for Target { GenericParamKind::Lifetime => "lifetime parameter", GenericParamKind::Const => "const parameter", }, + Target::MacroDef => "macro def", } ) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 26b35e87ac491..412d5b5082be3 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -8,6 +8,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, Definitions}; use rustc_hir::intravisit; +use rustc_hir::intravisit::Visitor; use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::*; use rustc_index::vec::IndexVec; @@ -494,6 +495,15 @@ impl<'hir> Map<'hir> { } } + pub fn visit_exported_macros_in_krate(&self, visitor: &mut V) + where + V: Visitor<'hir>, + { + for id in self.krate().exported_macros { + visitor.visit_macro_def(self.expect_macro_def(id.hir_id)); + } + } + /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. pub fn get(&self, id: HirId) -> Node<'hir> { self.find(id).unwrap_or_else(|| bug!("couldn't find hir id {} in the HIR map", id)) @@ -802,6 +812,13 @@ impl<'hir> Map<'hir> { } } + pub fn expect_macro_def(&self, id: HirId) -> &'hir MacroDef<'hir> { + match self.find(id) { + Some(Node::MacroDef(macro_def)) => macro_def, + _ => bug!("expected macro def, found {}", self.node_to_string(id)), + } + } + pub fn expect_expr(&self, id: HirId) -> &'hir Expr<'hir> { match self.find(id) { Some(Node::Expr(expr)) => expr, @@ -821,6 +838,7 @@ impl<'hir> Map<'hir> { Node::GenericParam(param) => param.name.ident().name, Node::Binding(&Pat { kind: PatKind::Binding(_, _, l, _), .. }) => l.name, Node::Ctor(..) => self.name(self.get_parent_item(id)), + Node::MacroDef(md) => md.ident.name, _ => return None, }) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ac73ba7062e76..0e3a722e082f2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -70,27 +70,27 @@ impl CheckAttrVisitor<'tcx> { is_valid &= if self.tcx.sess.check_name(attr, sym::inline) { self.check_inline(hir_id, attr, span, target) } else if self.tcx.sess.check_name(attr, sym::non_exhaustive) { - self.check_non_exhaustive(attr, span, target) + self.check_non_exhaustive(hir_id, attr, span, target) } else if self.tcx.sess.check_name(attr, sym::marker) { - self.check_marker(attr, span, target) + self.check_marker(hir_id, attr, span, target) } else if self.tcx.sess.check_name(attr, sym::target_feature) { self.check_target_feature(hir_id, attr, span, target) } else if self.tcx.sess.check_name(attr, sym::track_caller) { - self.check_track_caller(&attr.span, attrs, span, target) + self.check_track_caller(hir_id, &attr.span, attrs, span, target) } else if self.tcx.sess.check_name(attr, sym::doc) { self.check_doc_attrs(attr, hir_id, target) } else if self.tcx.sess.check_name(attr, sym::no_link) { - self.check_no_link(&attr, span, target) + self.check_no_link(hir_id, &attr, span, target) } else if self.tcx.sess.check_name(attr, sym::export_name) { - self.check_export_name(&attr, span, target) + self.check_export_name(hir_id, &attr, span, target) } else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) { self.check_rustc_args_required_const(&attr, span, target, item) } else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) { - self.check_allow_internal_unstable(&attr, span, target, &attrs) + self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs) } else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) { self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target) } else if self.tcx.sess.check_name(attr, sym::naked) { - self.check_naked(attr, span, target) + self.check_naked(hir_id, attr, span, target) } else { // lint-only checks if self.tcx.sess.check_name(attr, sym::cold) { @@ -118,6 +118,41 @@ impl CheckAttrVisitor<'tcx> { self.check_used(attrs, target); } + fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build(&format!( + "`#[{}]` is ignored on struct fields, match arms and macro defs", + sym, + )) + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .note( + "see issue #80564 \ + for more information", + ) + .emit(); + }); + } + + fn inline_attr_str_error_without_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) { + self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { + lint.build(&format!("`#[{}]` is ignored on struct fields and match arms", sym)) + .warn( + "this was previously accepted by the compiler but is \ + being phased out; it will become a hard error in \ + a future release!", + ) + .note( + "see issue #80564 \ + for more information", + ) + .emit(); + }); + } + /// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid. fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool { match target { @@ -150,6 +185,11 @@ impl CheckAttrVisitor<'tcx> { }); true } + // FIXME(#80564): Same for fields, arms, and macro defs + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "inline"); + true + } _ => { struct_span_err!( self.tcx.sess, @@ -165,10 +205,18 @@ impl CheckAttrVisitor<'tcx> { } /// Checks if `#[naked]` is applied to a function definition. - fn check_naked(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + fn check_naked(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool { match target { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[allow_internal_unstable]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "naked"); + true + } _ => { self.tcx .sess @@ -186,6 +234,7 @@ impl CheckAttrVisitor<'tcx> { /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. fn check_track_caller( &self, + hir_id: HirId, attr_span: &Span, attrs: &'hir [Attribute], span: &Span, @@ -203,6 +252,16 @@ impl CheckAttrVisitor<'tcx> { false } Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[track_caller]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + for attr in attrs { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller"); + } + true + } _ => { struct_span_err!( self.tcx.sess, @@ -218,9 +277,23 @@ impl CheckAttrVisitor<'tcx> { } /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. Returns `true` if valid. - fn check_non_exhaustive(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + fn check_non_exhaustive( + &self, + hir_id: HirId, + attr: &Attribute, + span: &Span, + target: Target, + ) -> bool { match target { Target::Struct | Target::Enum | Target::Variant => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[non_exhaustive]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "non_exhaustive"); + true + } _ => { struct_span_err!( self.tcx.sess, @@ -236,9 +309,17 @@ impl CheckAttrVisitor<'tcx> { } /// Checks if the `#[marker]` attribute on an `item` is valid. Returns `true` if valid. - fn check_marker(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + fn check_marker(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool { match target { Target::Trait => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[marker]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "marker"); + true + } _ => { self.tcx .sess @@ -276,6 +357,14 @@ impl CheckAttrVisitor<'tcx> { }); true } + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[target_feature]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "target_feature"); + true + } _ => { self.tcx .sess @@ -464,6 +553,13 @@ impl CheckAttrVisitor<'tcx> { fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { match target { Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => {} + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[cold]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "cold"); + } _ => { // FIXME: #[cold] was previously allowed on non-functions and some crates used // this, so only emit a warning. @@ -485,6 +581,13 @@ impl CheckAttrVisitor<'tcx> { fn check_link_name(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { match target { Target::ForeignFn | Target::ForeignStatic => {} + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[link_name]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name"); + } _ => { // FIXME: #[cold] was previously allowed on non-functions/statics and some crates // used this, so only emit a warning. @@ -517,23 +620,49 @@ impl CheckAttrVisitor<'tcx> { } /// Checks if `#[no_link]` is applied to an `extern crate`. Returns `true` if valid. - fn check_no_link(&self, attr: &Attribute, span: &Span, target: Target) -> bool { - if target == Target::ExternCrate { - true - } else { - self.tcx - .sess - .struct_span_err(attr.span, "attribute should be applied to an `extern crate` item") - .span_label(*span, "not an `extern crate` item") - .emit(); - false + fn check_no_link(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) -> bool { + match target { + Target::ExternCrate => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[no_link]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_link"); + true + } + _ => { + self.tcx + .sess + .struct_span_err( + attr.span, + "attribute should be applied to an `extern crate` item", + ) + .span_label(*span, "not an `extern crate` item") + .emit(); + false + } } } /// Checks if `#[export_name]` is applied to a function or static. Returns `true` if valid. - fn check_export_name(&self, attr: &Attribute, span: &Span, target: Target) -> bool { + fn check_export_name( + &self, + hir_id: HirId, + attr: &Attribute, + span: &Span, + target: Target, + ) -> bool { match target { Target::Static | Target::Fn | Target::Method(..) => true, + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[export_name]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "export_name"); + true + } _ => { self.tcx .sess @@ -625,6 +754,13 @@ impl CheckAttrVisitor<'tcx> { fn check_link_section(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { match target { Target::Static | Target::Fn | Target::Method(..) => {} + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[link_section]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_section"); + } _ => { // FIXME: #[link_section] was previously allowed on non-functions/statics and some // crates used this, so only emit a warning. @@ -646,6 +782,13 @@ impl CheckAttrVisitor<'tcx> { fn check_no_mangle(&self, hir_id: HirId, attr: &Attribute, span: &Span, target: Target) { match target { Target::Static | Target::Fn | Target::Method(..) => {} + // FIXME(#80564): We permit struct fields, match arms and macro defs to have an + // `#[no_mangle]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "no_mangle"); + } _ => { // FIXME: #[no_mangle] was previously allowed on non-functions/statics and some // crates used this, so only emit a warning. @@ -828,27 +971,46 @@ impl CheckAttrVisitor<'tcx> { /// (Allows proc_macro functions) fn check_allow_internal_unstable( &self, + hir_id: HirId, attr: &Attribute, span: &Span, target: Target, attrs: &[Attribute], ) -> bool { debug!("Checking target: {:?}", target); - if target == Target::Fn { - for attr in attrs { - if self.tcx.sess.is_proc_macro_attr(attr) { - debug!("Is proc macro attr"); - return true; + match target { + Target::Fn => { + for attr in attrs { + if self.tcx.sess.is_proc_macro_attr(attr) { + debug!("Is proc macro attr"); + return true; + } } + debug!("Is not proc macro attr"); + false + } + Target::MacroDef => true, + // FIXME(#80564): We permit struct fields and match arms to have an + // `#[allow_internal_unstable]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm => { + self.inline_attr_str_error_without_macro_def( + hir_id, + attr, + "allow_internal_unstable", + ); + true + } + _ => { + self.tcx + .sess + .struct_span_err(attr.span, "attribute should be applied to a macro") + .span_label(*span, "not a macro") + .emit(); + false } - debug!("Is not proc macro attr"); } - self.tcx - .sess - .struct_span_err(attr.span, "attribute should be applied to a macro") - .span_label(*span, "not a macro") - .emit(); - false } /// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros. @@ -860,17 +1022,29 @@ impl CheckAttrVisitor<'tcx> { span: &Span, target: Target, ) -> bool { - if let Target::Fn | Target::Method(_) = target { - if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id)) { - return true; + match target { + Target::Fn | Target::Method(_) + if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id)) => + { + true + } + // FIXME(#80564): We permit struct fields and match arms to have an + // `#[allow_internal_unstable]` attribute with just a lint, because we previously + // erroneously allowed it and some crates used it accidentally, to to be compatible + // with crates depending on them, we can't throw an error here. + Target::Field | Target::Arm | Target::MacroDef => { + self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable"); + true + } + _ => { + self.tcx + .sess + .struct_span_err(attr.span, "attribute should be applied to `const fn`") + .span_label(*span, "not a `const fn`") + .emit(); + false } } - self.tcx - .sess - .struct_span_err(attr.span, "attribute should be applied to `const fn`") - .span_label(*span, "not a `const fn`") - .emit(); - false } } @@ -911,6 +1085,33 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { intravisit::walk_trait_item(self, trait_item) } + fn visit_struct_field(&mut self, struct_field: &'tcx hir::StructField<'tcx>) { + self.check_attributes( + struct_field.hir_id, + &struct_field.attrs, + &struct_field.span, + Target::Field, + None, + ); + intravisit::walk_struct_field(self, struct_field); + } + + fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) { + self.check_attributes(arm.hir_id, &arm.attrs, &arm.span, Target::Arm, None); + intravisit::walk_arm(self, arm); + } + + fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) { + self.check_attributes( + macro_def.hir_id, + ¯o_def.attrs, + ¯o_def.span, + Target::MacroDef, + None, + ); + intravisit::walk_macro_def(self, macro_def); + } + fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) { let target = Target::from_foreign_item(f_item); self.check_attributes( @@ -999,11 +1200,28 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { } } +fn check_invalid_macro_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { + for attr in attrs { + if tcx.sess.check_name(attr, sym::inline) { + struct_span_err!( + tcx.sess, + attr.span, + E0518, + "attribute should be applied to function or closure", + ) + .span_label(attr.span, "not a function or closure") + .emit(); + } + } +} + fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { - tcx.hir() - .visit_item_likes_in_module(module_def_id, &mut CheckAttrVisitor { tcx }.as_deep_visitor()); + let check_attr_visitor = &mut CheckAttrVisitor { tcx }; + tcx.hir().visit_item_likes_in_module(module_def_id, &mut check_attr_visitor.as_deep_visitor()); + tcx.hir().visit_exported_macros_in_krate(check_attr_visitor); + check_invalid_macro_level_attr(tcx, tcx.hir().krate().non_exported_macro_attrs); if module_def_id.is_top_level_module() { - CheckAttrVisitor { tcx }.check_attributes( + check_attr_visitor.check_attributes( CRATE_HIR_ID, tcx.hir().krate_attrs(), &DUMMY_SP, diff --git a/src/test/ui/attr-usage-inline.rs b/src/test/ui/attr-usage-inline.rs index 1996f4a692c18..674c12454cdaa 100644 --- a/src/test/ui/attr-usage-inline.rs +++ b/src/test/ui/attr-usage-inline.rs @@ -6,4 +6,20 @@ fn f() {} #[inline] //~ ERROR: attribute should be applied to function or closure struct S; +struct I { + #[inline] + i: u8, +} + +#[macro_export] +#[inline] +macro_rules! m_e { + () => {}; +} + +#[inline] //~ ERROR: attribute should be applied to function or closure +macro_rules! m { + () => {}; +} + fn main() {} diff --git a/src/test/ui/attr-usage-inline.stderr b/src/test/ui/attr-usage-inline.stderr index d8d7f6adb82b5..22a0bf47e2026 100644 --- a/src/test/ui/attr-usage-inline.stderr +++ b/src/test/ui/attr-usage-inline.stderr @@ -6,6 +6,12 @@ LL | #[inline] LL | struct S; | --------- not a function or closure -error: aborting due to previous error +error[E0518]: attribute should be applied to function or closure + --> $DIR/attr-usage-inline.rs:20:1 + | +LL | #[inline] + | ^^^^^^^^^ not a function or closure + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0518`. diff --git a/src/test/ui/internal/internal-unstable.rs b/src/test/ui/internal/internal-unstable.rs index 94bd6aab23bff..b8987d3e13c65 100644 --- a/src/test/ui/internal/internal-unstable.rs +++ b/src/test/ui/internal/internal-unstable.rs @@ -1,10 +1,17 @@ // aux-build:internal_unstable.rs #![feature(allow_internal_unstable)] +#[allow(dead_code)] #[macro_use] extern crate internal_unstable; +struct Baz { + #[allow_internal_unstable] + //^ WARN `#[allow_internal_unstable]` is ignored on struct fields and match arms + baz: u8, +} + macro_rules! foo { ($e: expr, $f: expr) => {{ $e; @@ -40,4 +47,10 @@ fn main() { println!("{:?}", internal_unstable::unstable()); //~ ERROR use of unstable bar!(internal_unstable::unstable()); //~ ERROR use of unstable + + match true { + #[allow_internal_unstable] + //^ WARN `#[allow_internal_unstable]` is ignored on struct fields and match arms + _ => {} + } } diff --git a/src/test/ui/internal/internal-unstable.stderr b/src/test/ui/internal/internal-unstable.stderr index 2e6360c75c42a..a92ca4957b573 100644 --- a/src/test/ui/internal/internal-unstable.stderr +++ b/src/test/ui/internal/internal-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'function' - --> $DIR/internal-unstable.rs:34:25 + --> $DIR/internal-unstable.rs:41:25 | LL | pass_through_allow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | pass_through_allow!(internal_unstable::unstable()); = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' - --> $DIR/internal-unstable.rs:36:27 + --> $DIR/internal-unstable.rs:43:27 | LL | pass_through_noallow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | pass_through_noallow!(internal_unstable::unstable()); = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' - --> $DIR/internal-unstable.rs:40:22 + --> $DIR/internal-unstable.rs:47:22 | LL | println!("{:?}", internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | println!("{:?}", internal_unstable::unstable()); = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' - --> $DIR/internal-unstable.rs:42:10 + --> $DIR/internal-unstable.rs:49:10 | LL | bar!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | bar!(internal_unstable::unstable()); = help: add `#![feature(function)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'function' - --> $DIR/internal-unstable.rs:12:9 + --> $DIR/internal-unstable.rs:19:9 | LL | internal_unstable::unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs index 5f45f6892d2e3..a6e9ed14ff13e 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -21,7 +21,9 @@ fn non_macro_expanded_location<#[repr(C)] T>() { //~^ ERROR `repr` is ambiguous //~| ERROR attribute should be applied to a struct, enum, or union match 0u8 { - #[repr(C)] //~ ERROR `repr` is ambiguous + #[repr(C)] + //~^ ERROR `repr` is ambiguous + //~| ERROR attribute should be applied to a struct, enum, or union _ => {} } } diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr index dfd60dc92cc35..15935ebebebdd 100644 --- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `NonExistent` in this scope - --> $DIR/ambiguous-builtin-attrs.rs:32:5 + --> $DIR/ambiguous-builtin-attrs.rs:34:5 | LL | NonExistent; | ^^^^^^^^^^^ not found in this scope @@ -94,6 +94,15 @@ error[E0517]: attribute should be applied to a struct, enum, or union LL | fn non_macro_expanded_location<#[repr(C)] T>() { | ^ - not a struct, enum, or union +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/ambiguous-builtin-attrs.rs:24:16 + | +LL | #[repr(C)] + | ^ +... +LL | _ => {} + | ------- not a struct, enum, or union + error: aborting due to 8 previous errors Some errors have detailed explanations: E0425, E0517, E0659.