diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_attr_data_structures/src/attributes.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/attributes/semantics.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_attr_parsing/src/context.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/concat_bytes.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/errors.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/expand.rs | 92 | ||||
| -rw-r--r-- | compiler/rustc_hir/src/hir.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 8 |
10 files changed, 120 insertions, 59 deletions
diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 9ebf4c1793d..066e3e9eceb 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -233,8 +233,13 @@ pub enum AttributeKind { /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), + + /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). + MayDangle(Span), + /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), + /// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations). Repr(ThinVec<(ReprAttr, Span)>), diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 78a696afa27..1bb5edba326 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -34,6 +34,7 @@ pub(crate) mod deprecation; pub(crate) mod inline; pub(crate) mod lint_helpers; pub(crate) mod repr; +pub(crate) mod semantics; pub(crate) mod stability; pub(crate) mod transparency; pub(crate) mod util; diff --git a/compiler/rustc_attr_parsing/src/attributes/semantics.rs b/compiler/rustc_attr_parsing/src/attributes/semantics.rs new file mode 100644 index 00000000000..071574a5612 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/semantics.rs @@ -0,0 +1,19 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::{Symbol, sym}; + +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct MayDangleParser; +impl<S: Stage> SingleAttributeParser<S> for MayDangleParser { + const PATH: &[Symbol] = &[sym::may_dangle]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> { + Some(AttributeKind::MayDangle(cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8311fccacd8..1bcf500459d 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -21,6 +21,7 @@ use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::lint_helpers::AsPtrParser; use crate::attributes::repr::{AlignParser, ReprParser}; +use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, }; @@ -110,6 +111,7 @@ attribute_parsers!( Single<ConstStabilityIndirectParser>, Single<DeprecationParser>, Single<InlineParser>, + Single<MayDangleParser>, Single<OptimizeParser>, Single<RustcForceInlineParser>, Single<TransparencyParser>, diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index d32e6f1558e..c5d1f2ad2de 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -104,6 +104,8 @@ builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals .byte_char = try using a byte character .byte_str = try using a byte string + .c_str = try using a null-terminated byte string + .c_str_note = concatenating C strings is ambiguous about including the '\0' .number_array = try wrapping the number in an array builtin_macros_concat_bytes_missing_literal = expected a byte literal diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 456f2b9ab31..92d011fb9d1 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -1,6 +1,6 @@ use rustc_ast::ptr::P; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{ExprKind, LitIntType, LitKind, UintTy, token}; +use rustc_ast::{ExprKind, LitIntType, LitKind, StrStyle, UintTy, token}; use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult}; use rustc_session::errors::report_lit_error; use rustc_span::{ErrorGuaranteed, Span}; @@ -21,15 +21,32 @@ fn invalid_type_err( let snippet = cx.sess.source_map().span_to_snippet(span).ok(); let dcx = cx.dcx(); match LitKind::from_token_lit(token_lit) { - Ok(LitKind::CStr(_, _)) => { + Ok(LitKind::CStr(_, style)) => { // Avoid ambiguity in handling of terminal `NUL` by refusing to // concatenate C string literals as bytes. - dcx.emit_err(errors::ConcatCStrLit { span }) + let sugg = if let Some(mut as_bstr) = snippet + && style == StrStyle::Cooked + && as_bstr.starts_with('c') + && as_bstr.ends_with('"') + { + // Suggest`c"foo"` -> `b"foo\0"` if we can + as_bstr.replace_range(0..1, "b"); + as_bstr.pop(); + as_bstr.push_str(r#"\0""#); + Some(ConcatBytesInvalidSuggestion::CStrLit { span, as_bstr }) + } else { + // No suggestion for a missing snippet, raw strings, or if for some reason we have + // a span that doesn't match `c"foo"` (possible if a proc macro assigns a span + // that doesn't actually point to a C string). + None + }; + // We can only provide a suggestion if we have a snip and it is not a raw string + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "C string", sugg, cs_note: Some(()) }) } Ok(LitKind::Char(_)) => { let sugg = snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet }); - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg }) + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg, cs_note: None }) } Ok(LitKind::Str(_, _)) => { // suggestion would be invalid if we are nested @@ -38,18 +55,21 @@ fn invalid_type_err( } else { None }; - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg }) + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg, cs_note: None }) } Ok(LitKind::Float(_, _)) => { - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None }) - } - Ok(LitKind::Bool(_)) => { - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None }) + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None, cs_note: None }) } + Ok(LitKind::Bool(_)) => dcx.emit_err(ConcatBytesInvalid { + span, + lit_kind: "boolean", + sugg: None, + cs_note: None, + }), Ok(LitKind::Int(_, _)) if !is_nested => { let sugg = snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span, snippet }); - dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg }) + dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg, cs_note: None }) } Ok(LitKind::Int(val, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::U8))) => { assert!(val.get() > u8::MAX.into()); // must be an error diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 3a2e96a5e5a..b7ecfd2285c 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -215,6 +215,8 @@ pub(crate) struct ConcatBytesInvalid { pub(crate) lit_kind: &'static str, #[subdiagnostic] pub(crate) sugg: Option<ConcatBytesInvalidSuggestion>, + #[note(builtin_macros_c_str_note)] + pub(crate) cs_note: Option<()>, } #[derive(Subdiagnostic)] @@ -239,6 +241,13 @@ pub(crate) enum ConcatBytesInvalidSuggestion { span: Span, snippet: String, }, + #[note(builtin_macros_c_str_note)] + #[suggestion(builtin_macros_c_str, code = "{as_bstr}", applicability = "machine-applicable")] + CStrLit { + #[primary_span] + span: Span, + as_bstr: String, + }, #[suggestion( builtin_macros_number_array, code = "[{snippet}]", diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 37010700fab..3ba40859d45 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -86,7 +86,7 @@ macro_rules! ast_fragments { } } - fn make_from<'a>(self, result: Box<dyn MacResult + 'a>) -> Option<AstFragment> { + fn make_from(self, result: Box<dyn MacResult + '_>) -> Option<AstFragment> { match self { AstFragmentKind::OptExpr => result.make_expr().map(Some).map(AstFragment::OptExpr), @@ -136,7 +136,7 @@ macro_rules! ast_fragments { T::fragment_to_output(self) } - pub(crate) fn mut_visit_with<F: MutVisitor>(&mut self, vis: &mut F) { + pub(crate) fn mut_visit_with(&mut self, vis: &mut impl MutVisitor) { match self { AstFragment::OptExpr(opt_expr) => { if let Some(expr) = opt_expr.take() { @@ -316,9 +316,9 @@ impl AstFragmentKind { } } - pub(crate) fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>( + pub(crate) fn expect_from_annotatables( self, - items: I, + items: impl IntoIterator<Item = Annotatable>, ) -> AstFragment { let mut items = items.into_iter(); match self { @@ -1218,10 +1218,10 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { fn descr() -> &'static str { unreachable!() } - fn walk_flat_map<V: MutVisitor>(self, _visitor: &mut V) -> Self::OutputTy { + fn walk_flat_map(self, _collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { unreachable!() } - fn walk<V: MutVisitor>(&mut self, _visitor: &mut V) { + fn walk(&mut self, _collector: &mut InvocationCollector<'_, '_>) { unreachable!() } fn is_mac_call(&self) -> bool { @@ -1276,8 +1276,8 @@ impl InvocationCollectorNode for P<ast::Item> { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_items() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_item(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_item(collector, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ItemKind::MacCall(..)) @@ -1431,8 +1431,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag> fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_trait_items() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Trait) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Trait) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1472,8 +1472,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag> fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_impl_items() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false }) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: false }) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1513,8 +1513,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItem fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_trait_impl_items() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true }) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_assoc_item(collector, self.wrapped, AssocCtxt::Impl { of_trait: true }) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1551,8 +1551,8 @@ impl InvocationCollectorNode for P<ast::ForeignItem> { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_foreign_items() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_foreign_item(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_foreign_item(collector, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ForeignItemKind::MacCall(..)) @@ -1573,8 +1573,8 @@ impl InvocationCollectorNode for ast::Variant { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_variants() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_variant(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_variant(collector, self) } } @@ -1586,8 +1586,8 @@ impl InvocationCollectorNode for ast::WherePredicate { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_where_predicates() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_where_predicate(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_where_predicate(collector, self) } } @@ -1599,8 +1599,8 @@ impl InvocationCollectorNode for ast::FieldDef { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_field_defs() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_field_def(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_field_def(collector, self) } } @@ -1612,8 +1612,8 @@ impl InvocationCollectorNode for ast::PatField { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_pat_fields() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_pat_field(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_pat_field(collector, self) } } @@ -1625,8 +1625,8 @@ impl InvocationCollectorNode for ast::ExprField { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_expr_fields() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_expr_field(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_expr_field(collector, self) } } @@ -1638,8 +1638,8 @@ impl InvocationCollectorNode for ast::Param { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_params() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_param(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_param(collector, self) } } @@ -1651,8 +1651,8 @@ impl InvocationCollectorNode for ast::GenericParam { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_generic_params() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_generic_param(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_generic_param(collector, self) } } @@ -1664,8 +1664,8 @@ impl InvocationCollectorNode for ast::Arm { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_arms() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_arm(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_arm(collector, self) } } @@ -1677,8 +1677,8 @@ impl InvocationCollectorNode for ast::Stmt { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_stmts() } - fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_stmt(visitor, self) + fn walk_flat_map(self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_flat_map_stmt(collector, self) } fn is_mac_call(&self) -> bool { match &self.kind { @@ -1751,8 +1751,8 @@ impl InvocationCollectorNode for ast::Crate { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_crate() } - fn walk<V: MutVisitor>(&mut self, visitor: &mut V) { - walk_crate(visitor, self) + fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) { + walk_crate(collector, self) } fn expand_cfg_false( &mut self, @@ -1777,8 +1777,8 @@ impl InvocationCollectorNode for ast::Ty { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_ty() } - fn walk<V: MutVisitor>(&mut self, visitor: &mut V) { - walk_ty(visitor, self) + fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) { + walk_ty(collector, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ast::TyKind::MacCall(..)) @@ -1800,8 +1800,8 @@ impl InvocationCollectorNode for ast::Pat { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_pat() } - fn walk<V: MutVisitor>(&mut self, visitor: &mut V) { - walk_pat(visitor, self) + fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) { + walk_pat(collector, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, PatKind::MacCall(..)) @@ -1826,8 +1826,8 @@ impl InvocationCollectorNode for ast::Expr { fn descr() -> &'static str { "an expression" } - fn walk<V: MutVisitor>(&mut self, visitor: &mut V) { - walk_expr(visitor, self) + fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) { + walk_expr(collector, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ExprKind::MacCall(..)) @@ -1850,8 +1850,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> { fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_opt_expr() } - fn walk_flat_map<V: MutVisitor>(mut self, visitor: &mut V) -> Self::OutputTy { - walk_expr(visitor, &mut self.wrapped); + fn walk_flat_map(mut self, collector: &mut InvocationCollector<'_, '_>) -> Self::OutputTy { + walk_expr(collector, &mut self.wrapped); Some(self.wrapped) } fn is_mac_call(&self) -> bool { @@ -1885,8 +1885,8 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, MethodReceiverTag> fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { AstNodeWrapper::new(fragment.make_method_receiver_expr(), MethodReceiverTag) } - fn walk<V: MutVisitor>(&mut self, visitor: &mut V) { - walk_expr(visitor, &mut self.wrapped) + fn walk(&mut self, collector: &mut InvocationCollector<'_, '_>) { + walk_expr(collector, &mut self.wrapped) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, ast::ExprKind::MacCall(..)) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 556f50a85af..1a526d5bce0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1302,6 +1302,7 @@ impl AttributeExt for Attribute { // FIXME: should not be needed anymore when all attrs are parsed Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span, Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span, + Attribute::Parsed(AttributeKind::MayDangle(span)) => *span, a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"), } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5fb9514e5ca..d0630383477 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -163,6 +163,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) } + &Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { + self.check_may_dangle(hir_id, attr_span) + } Attribute::Unparsed(_) => { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { @@ -236,7 +239,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::must_use, ..] => self.check_must_use(hir_id, attr, target), - [sym::may_dangle, ..] => self.check_may_dangle(hir_id, attr), [sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), [sym::rustc_allow_incoherent_impl, ..] => { self.check_allow_incoherent_impl(attr, span, target) @@ -1619,7 +1621,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl. - fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) { + fn check_may_dangle(&self, hir_id: HirId, attr_span: Span) { if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id) && matches!( param.kind, @@ -1636,7 +1638,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { return; } - self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span() }); + self.dcx().emit_err(errors::InvalidMayDangle { attr_span }); } /// Checks if `#[cold]` is applied to a non-function. |
