diff options
Diffstat (limited to 'compiler/rustc_passes/src')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 161 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 29 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 8 |
3 files changed, 95 insertions, 103 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c1a212d7ab5..7aef60b7b91 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -18,7 +18,7 @@ use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, }; -use rustc_hir::attrs::{AttributeKind, InlineAttr, MirDialect, MirPhase, ReprAttr}; +use rustc_hir::attrs::{AttributeKind, InlineAttr, MirDialect, MirPhase, ReprAttr, SanitizerSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; @@ -167,7 +167,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Deprecation { .. }) => { self.check_deprecated(hir_id, attr, span, target) } - Attribute::Parsed(AttributeKind::TargetFeature(_, attr_span)) => { + Attribute::Parsed(AttributeKind::TargetFeature{ attr_span, ..}) => { self.check_target_feature(hir_id, *attr_span, target, attrs) } Attribute::Parsed(AttributeKind::RustcObjectLifetimeDefault) => { @@ -194,12 +194,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { self.check_may_dangle(hir_id, *attr_span) } - Attribute::Parsed(AttributeKind::MustUse { span, .. }) => { - self.check_must_use(hir_id, *span, target) - } &Attribute::Parsed(AttributeKind::CustomMir(dialect, phase, attr_span)) => { self.check_custom_mir(dialect, phase, attr_span) } + &Attribute::Parsed(AttributeKind::Sanitize { on_set, off_set, span: attr_span}) => { + self.check_sanitize(attr_span, on_set | off_set, span, target); + }, Attribute::Parsed( AttributeKind::BodyStability { .. } | AttributeKind::ConstStabilityIndirect @@ -249,7 +249,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::Coverage (..) | AttributeKind::ShouldPanic { .. } | AttributeKind::Coroutine(..) - | AttributeKind::Linkage(..), + | AttributeKind::Linkage(..) + | AttributeKind::MustUse { .. } + | AttributeKind::CrateName { .. } ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -260,9 +262,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::diagnostic, sym::on_unimplemented, ..] => { self.check_diagnostic_on_unimplemented(attr.span(), hir_id, target) } - [sym::sanitize, ..] => { - self.check_sanitize(attr, span, target) - } [sym::thread_local, ..] => self.check_thread_local(attr, span, target), [sym::doc, ..] => self.check_doc_attrs( attr, @@ -369,22 +368,49 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let builtin = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); if hir_id != CRATE_HIR_ID { - if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) - { - match style { - Some(ast::AttrStyle::Outer) => self.tcx.emit_node_span_lint( + match attr { + // FIXME(jdonszelmann) move to attribute parsing when validation gets better there + &Attribute::Parsed(AttributeKind::CrateName { + attr_span: span, style, .. + }) => match style { + ast::AttrStyle::Outer => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + span, errors::OuterCrateLevelAttr, ), - Some(ast::AttrStyle::Inner) | None => self.tcx.emit_node_span_lint( + ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + span, errors::InnerCrateLevelAttr, ), + }, + Attribute::Parsed(_) => { /* not crate-level */ } + Attribute::Unparsed(attr) => { + // FIXME(jdonszelmann): remove once all crate-level attrs are parsed and caught by + // the above + if let Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) = + attr.path + .segments + .first() + .and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)) + { + match attr.style { + ast::AttrStyle::Outer => self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::OuterCrateLevelAttr, + ), + ast::AttrStyle::Inner => self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::InnerCrateLevelAttr, + ), + } + } } } } @@ -485,42 +511,48 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// Checks that the `#[sanitize(..)]` attribute is applied to a /// function/closure/method, or to an impl block or module. - fn check_sanitize(&self, attr: &Attribute, target_span: Span, target: Target) { + fn check_sanitize( + &self, + attr_span: Span, + set: SanitizerSet, + target_span: Span, + target: Target, + ) { let mut not_fn_impl_mod = None; let mut no_body = None; - if let Some(list) = attr.meta_item_list() { - for item in list.iter() { - let MetaItemInner::MetaItem(set) = item else { - return; - }; - let segments = set.path.segments.iter().map(|x| x.ident.name).collect::<Vec<_>>(); - match target { - Target::Fn - | Target::Closure - | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) - | Target::Impl { .. } - | Target::Mod => return, - Target::Static if matches!(segments.as_slice(), [sym::address]) => return, - - // These are "functions", but they aren't allowed because they don't - // have a body, so the usual explanation would be confusing. - Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { - no_body = Some(target_span); - } + match target { + Target::Fn + | Target::Closure + | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) + | Target::Impl { .. } + | Target::Mod => return, + Target::Static + // if we mask out the address bits, i.e. *only* address was set, + // we allow it + if set & !(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS) + == SanitizerSet::empty() => + { + return; + } - _ => { - not_fn_impl_mod = Some(target_span); - } - } + // These are "functions", but they aren't allowed because they don't + // have a body, so the usual explanation would be confusing. + Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { + no_body = Some(target_span); + } + + _ => { + not_fn_impl_mod = Some(target_span); } - self.dcx().emit_err(errors::SanitizeAttributeNotAllowed { - attr_span: attr.span(), - not_fn_impl_mod, - no_body, - help: (), - }); } + + self.dcx().emit_err(errors::SanitizeAttributeNotAllowed { + attr_span, + not_fn_impl_mod, + no_body, + help: (), + }); } /// Checks if `#[naked]` is applied to a function definition. @@ -1263,41 +1295,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Warns against some misuses of `#[must_use]` - fn check_must_use(&self, hir_id: HirId, attr_span: Span, target: Target) { - if matches!( - target, - Target::Fn - | Target::Enum - | Target::Struct - | Target::Union - | Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent) - | Target::ForeignFn - // `impl Trait` in return position can trip - // `unused_must_use` if `Trait` is marked as - // `#[must_use]` - | Target::Trait - ) { - return; - } - - // `#[must_use]` can be applied to a trait method definition with a default body - if let Target::Method(MethodKind::Trait { body: true }) = target - && let parent_def_id = self.tcx.hir_get_parent_item(hir_id).def_id - && let containing_item = self.tcx.hir_expect_item(parent_def_id) - && let hir::ItemKind::Trait(..) = containing_item.kind - { - return; - } - - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr_span, - errors::MustUseNoEffect { target: target.plural_name(), attr_span }, - ); - } - /// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait. fn check_must_not_suspend(&self, attr: &Attribute, span: Span, target: Target) { match target { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 08d06402000..10cd9df4816 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -8,7 +8,6 @@ use std::mem; use hir::def_id::{LocalDefIdMap, LocalDefIdSet}; use rustc_abi::FieldIdx; use rustc_data_structures::fx::FxIndexSet; -use rustc_data_structures::unord::UnordSet; use rustc_errors::MultiSpan; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; @@ -79,7 +78,7 @@ struct MarkSymbolVisitor<'tcx> { worklist: Vec<(LocalDefId, ComesFromAllowExpect)>, tcx: TyCtxt<'tcx>, maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>, - scanned: UnordSet<(LocalDefId, ComesFromAllowExpect)>, + scanned: LocalDefIdSet, live_symbols: LocalDefIdSet, repr_unconditionally_treats_fields_as_live: bool, repr_has_repr_simd: bool, @@ -321,18 +320,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { fn mark_live_symbols(&mut self) { while let Some(work) = self.worklist.pop() { - if !self.scanned.insert(work) { - continue; - } - let (mut id, comes_from_allow_expect) = work; - // Avoid accessing the HIR for the synthesized associated type generated for RPITITs. - if self.tcx.is_impl_trait_in_trait(id.to_def_id()) { - self.live_symbols.insert(id); - continue; - } - // in the case of tuple struct constructors we want to check the item, // not the generated tuple struct constructor function if let DefKind::Ctor(..) = self.tcx.def_kind(id) { @@ -360,9 +349,23 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { // this "duplication" is essential as otherwise a function with `#[expect]` // called from a `pub fn` may be falsely reported as not live, falsely // triggering the `unfulfilled_lint_expectations` lint. - if comes_from_allow_expect != ComesFromAllowExpect::Yes { + match comes_from_allow_expect { + ComesFromAllowExpect::Yes => {} + ComesFromAllowExpect::No => { + self.live_symbols.insert(id); + } + } + + if !self.scanned.insert(id) { + continue; + } + + // Avoid accessing the HIR for the synthesized associated type generated for RPITITs. + if self.tcx.is_impl_trait_in_trait(id.to_def_id()) { self.live_symbols.insert(id); + continue; } + self.visit_node(self.tcx.hir_node_by_def_id(id)); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index ab46ac2dd8b..4fec6b0798a 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -358,14 +358,6 @@ pub(crate) struct BothFfiConstAndPure { pub attr_span: Span, } -#[derive(LintDiagnostic)] -#[diag(passes_must_use_no_effect)] -pub(crate) struct MustUseNoEffect { - pub target: &'static str, - #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] - pub attr_span: Span, -} - #[derive(Diagnostic)] #[diag(passes_must_not_suspend)] pub(crate) struct MustNotSuspend { |
