From e98b0e8ee7d3ab6273625049e3e23118a0f15813 Mon Sep 17 00:00:00 2001 From: hdelc Date: Sat, 30 Jul 2022 17:45:09 -0400 Subject: [PATCH 1/5] Prevent ICE for doc_alias on match arm, statement, expression --- compiler/rustc_passes/src/check_attr.rs | 3 +++ .../rustdoc/check-doc-alias-attr-location.rs | 8 +++++++- .../check-doc-alias-attr-location.stderr | 20 ++++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index fde12b9eee6b..2fcd85b2a531 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -619,6 +619,9 @@ impl CheckAttrVisitor<'_> { } // we check the validity of params elsewhere Target::Param => return false, + Target::Expression => Some("expression"), + Target::Statement => Some("statement"), + Target::Arm => Some("match arm"), _ => None, } { tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location }); diff --git a/src/test/ui/rustdoc/check-doc-alias-attr-location.rs b/src/test/ui/rustdoc/check-doc-alias-attr-location.rs index 4738e5116b42..10609e5d8f4d 100644 --- a/src/test/ui/rustdoc/check-doc-alias-attr-location.rs +++ b/src/test/ui/rustdoc/check-doc-alias-attr-location.rs @@ -21,6 +21,12 @@ impl Foo for Bar { type X = i32; fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { //~^ ERROR - 0 + #[doc(alias = "stmt")] //~ ERROR + let x = 0; + #[doc(alias = "expr")] //~ ERROR + match x { + #[doc(alias = "arm")] //~ ERROR + _ => 0 + } } } diff --git a/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr b/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr index 650a82a23a98..19b2dd1e0842 100644 --- a/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -28,5 +28,23 @@ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation blo LL | #[doc(alias = "assoc")] | ^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: `#[doc(alias = "...")]` isn't allowed on statement + --> $DIR/check-doc-alias-attr-location.rs:24:15 + | +LL | #[doc(alias = "stmt")] + | ^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on expression + --> $DIR/check-doc-alias-attr-location.rs:26:15 + | +LL | #[doc(alias = "expr")] + | ^^^^^^^^^^^^^^ + +error: `#[doc(alias = "...")]` isn't allowed on match arm + --> $DIR/check-doc-alias-attr-location.rs:28:19 + | +LL | #[doc(alias = "arm")] + | ^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors From 6b37a795815af3cc4b8cd0b9a13108c060a9e214 Mon Sep 17 00:00:00 2001 From: hdelc Date: Tue, 2 Aug 2022 09:39:50 -0400 Subject: [PATCH 2/5] Refactor `Display` impl for `Target` to `Target::name` method --- compiler/rustc_hir/src/target.rs | 90 ++++++++++++++++---------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 96dd00ec5cff..622a234cd9f1 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -60,51 +60,7 @@ pub enum Target { impl Display for Target { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{}", - match *self { - Target::ExternCrate => "extern crate", - Target::Use => "use", - Target::Static => "static item", - Target::Const => "constant item", - Target::Fn => "function", - Target::Closure => "closure", - Target::Mod => "module", - Target::ForeignMod => "foreign module", - Target::GlobalAsm => "global asm", - Target::TyAlias => "type alias", - Target::OpaqueTy => "opaque type", - 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(kind) => match kind { - MethodKind::Inherent => "inherent method", - MethodKind::Trait { body: false } => "required trait method", - MethodKind::Trait { body: true } => "provided trait method", - }, - Target::AssocTy => "associated type", - Target::ForeignFn => "foreign function", - Target::ForeignStatic => "foreign static item", - Target::ForeignTy => "foreign type", - Target::GenericParam(kind) => match kind { - GenericParamKind::Type => "type parameter", - GenericParamKind::Lifetime => "lifetime parameter", - GenericParamKind::Const => "const parameter", - }, - Target::MacroDef => "macro def", - Target::Param => "function param", - } - ) + write!(f, "{}", Self::name(&self)) } } @@ -185,4 +141,48 @@ impl Target { hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const), } } + + pub fn name(&self) -> &str { + match *self { + Target::ExternCrate => "extern crate", + Target::Use => "use", + Target::Static => "static item", + Target::Const => "constant item", + Target::Fn => "function", + Target::Closure => "closure", + Target::Mod => "module", + Target::ForeignMod => "foreign module", + Target::GlobalAsm => "global asm", + Target::TyAlias => "type alias", + Target::OpaqueTy => "opaque type", + 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(kind) => match kind { + MethodKind::Inherent => "inherent method", + MethodKind::Trait { body: false } => "required trait method", + MethodKind::Trait { body: true } => "provided trait method", + }, + Target::AssocTy => "associated type", + Target::ForeignFn => "foreign function", + Target::ForeignStatic => "foreign static item", + Target::ForeignTy => "foreign type", + Target::GenericParam(kind) => match kind { + GenericParamKind::Type => "type parameter", + GenericParamKind::Lifetime => "lifetime parameter", + GenericParamKind::Const => "const parameter", + }, + Target::MacroDef => "macro def", + Target::Param => "function param", + } + } } From c643007a562004c0954bb6d4077caa19b1b6ed1c Mon Sep 17 00:00:00 2001 From: hdelc Date: Tue, 2 Aug 2022 10:05:11 -0400 Subject: [PATCH 3/5] Add exhaustive location checking for `doc_alias` attribute --- compiler/rustc_passes/src/check_attr.rs | 28 +++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2fcd85b2a531..4ff706ddfc30 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -619,10 +619,30 @@ impl CheckAttrVisitor<'_> { } // we check the validity of params elsewhere Target::Param => return false, - Target::Expression => Some("expression"), - Target::Statement => Some("statement"), - Target::Arm => Some("match arm"), - _ => None, + Target::Expression | Target::Statement | Target::Arm => Some(target.name()), + Target::ExternCrate + | Target::Use + | Target::Static + | Target::Const + | Target::Fn + | Target::Closure + | Target::Mod + | Target::GlobalAsm + | Target::TyAlias + | Target::OpaqueTy + | Target::Enum + | Target::Variant + | Target::Struct + | Target::Field + | Target::Union + | Target::Trait + | Target::TraitAlias + | Target::Method(..) + | Target::ForeignFn + | Target::ForeignStatic + | Target::ForeignTy + | Target::GenericParam(..) + | Target::MacroDef => None, } { tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location }); return false; From 1e8abe7da2ea02af86e840716e241ca0fec653f2 Mon Sep 17 00:00:00 2001 From: hdelc Date: Tue, 2 Aug 2022 16:30:09 -0400 Subject: [PATCH 4/5] Make `Target::name` method pass by copy --- compiler/rustc_hir/src/target.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 622a234cd9f1..178e381f5a32 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -60,7 +60,7 @@ pub enum Target { impl Display for Target { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", Self::name(&self)) + write!(f, "{}", Self::name(*self)) } } @@ -142,8 +142,8 @@ impl Target { } } - pub fn name(&self) -> &str { - match *self { + pub fn name(self) -> &'static str { + match self { Target::ExternCrate => "extern crate", Target::Use => "use", Target::Static => "static item", From 2be00947bfbb7e31cd6a5b6cf1e9e2f0bc1c4da6 Mon Sep 17 00:00:00 2001 From: hdelc Date: Tue, 2 Aug 2022 23:11:22 -0400 Subject: [PATCH 5/5] Add items to `DocAliasBadLocation` check error match arm - Added `Impl`, `Closure`, ForeignMod` targets - `Target::name` changed for `Target::Impl` - Error output for `Target::ForeignMod` changed to "foreign module" --- compiler/rustc_hir/src/target.rs | 2 +- compiler/rustc_passes/src/check_attr.rs | 10 ++++++---- .../rustdoc-ui/check-doc-alias-attr-location.stderr | 2 +- .../issue-43106-gating-of-builtin-attrs.stderr | 12 ++++++------ .../ui/lint/unused/unused_attributes-must_use.stderr | 4 ++-- .../ui/rustdoc/check-doc-alias-attr-location.stderr | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 178e381f5a32..6236dea10c88 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -162,7 +162,7 @@ impl Target { Target::Union => "union", Target::Trait => "trait", Target::TraitAlias => "trait alias", - Target::Impl => "item", + Target::Impl => "implementation block", Target::Expression => "expression", Target::Statement => "statement", Target::Arm => "match arm", diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4ff706ddfc30..5b7d44e41cf6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -596,8 +596,6 @@ impl CheckAttrVisitor<'_> { let span = meta.span(); if let Some(location) = match target { - Target::Impl => Some("implementation block"), - Target::ForeignMod => Some("extern block"), Target::AssocTy => { let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); let containing_item = self.tcx.hir().expect_item(parent_hir_id); @@ -619,13 +617,17 @@ impl CheckAttrVisitor<'_> { } // we check the validity of params elsewhere Target::Param => return false, - Target::Expression | Target::Statement | Target::Arm => Some(target.name()), + Target::Expression + | Target::Statement + | Target::Arm + | Target::ForeignMod + | Target::Closure + | Target::Impl => Some(target.name()), Target::ExternCrate | Target::Use | Target::Static | Target::Const | Target::Fn - | Target::Closure | Target::Mod | Target::GlobalAsm | Target::TyAlias diff --git a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr index 175626f49dca..85c9516236c9 100644 --- a/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr +++ b/src/test/rustdoc-ui/check-doc-alias-attr-location.stderr @@ -1,4 +1,4 @@ -error: `#[doc(alias = "...")]` isn't allowed on extern block +error: `#[doc(alias = "...")]` isn't allowed on foreign module --> $DIR/check-doc-alias-attr-location.rs:7:7 | LL | #[doc(alias = "foo")] diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 5d6796b49448..310d1f720eb7 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -212,7 +212,7 @@ note: the lint level is defined here LL | #![warn(unused_attributes, unknown_lints)] | ^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on items +warning: `#[automatically_derived]` only has an effect on implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:1 | LL | #[automatically_derived] @@ -515,25 +515,25 @@ warning: `#[path]` only has an effect on modules LL | #[path = "3800"] impl S { } | ^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on items +warning: `#[automatically_derived]` only has an effect on implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:17 | LL | mod inner { #![automatically_derived] } | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on items +warning: `#[automatically_derived]` only has an effect on implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5 | LL | #[automatically_derived] fn f() { } | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on items +warning: `#[automatically_derived]` only has an effect on implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:5 | LL | #[automatically_derived] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: `#[automatically_derived]` only has an effect on items +warning: `#[automatically_derived]` only has an effect on implementation blocks --> $DIR/issue-43106-gating-of-builtin-attrs.rs:278:5 | LL | #[automatically_derived] type T = S; @@ -923,7 +923,7 @@ warning: `#[must_use]` has no effect when applied to a type alias LL | #[must_use] type T = S; | ^^^^^^^^^^^ -warning: `#[must_use]` has no effect when applied to an item +warning: `#[must_use]` has no effect when applied to an implementation block --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:5 | LL | #[must_use] impl S { } diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr index 27269580e52e..317d81c591d5 100644 --- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr +++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr @@ -45,7 +45,7 @@ error: `#[must_use]` has no effect when applied to a static item LL | #[must_use] | ^^^^^^^^^^^ -error: `#[must_use]` has no effect when applied to an item +error: `#[must_use]` has no effect when applied to an implementation block --> $DIR/unused_attributes-must_use.rs:33:1 | LL | #[must_use] @@ -69,7 +69,7 @@ error: `#[must_use]` has no effect when applied to a type parameter LL | fn qux<#[must_use] T>(_: T) {} | ^^^^^^^^^^^ -error: `#[must_use]` has no effect when applied to an item +error: `#[must_use]` has no effect when applied to an implementation block --> $DIR/unused_attributes-must_use.rs:79:1 | LL | #[must_use] diff --git a/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr b/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr index 19b2dd1e0842..23c93a4ed8bd 100644 --- a/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr +++ b/src/test/ui/rustdoc/check-doc-alias-attr-location.stderr @@ -4,7 +4,7 @@ error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X { | ^^^^^^^^^^^^^^^^^^^^^ -error: `#[doc(alias = "...")]` isn't allowed on extern block +error: `#[doc(alias = "...")]` isn't allowed on foreign module --> $DIR/check-doc-alias-attr-location.rs:9:7 | LL | #[doc(alias = "foo")]