diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
commit | 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 (patch) | |
tree | d325add32978dbdc1db975a438b3a77d571b1ab8 /compiler/rustc_lint/src/multiple_supertrait_upcastable.rs | |
parent | Releasing progress-linux version 1.68.2+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.tar.xz rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_lint/src/multiple_supertrait_upcastable.rs')
-rw-r--r-- | compiler/rustc_lint/src/multiple_supertrait_upcastable.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs new file mode 100644 index 000000000..c2ed0e19f --- /dev/null +++ b/compiler/rustc_lint/src/multiple_supertrait_upcastable.rs @@ -0,0 +1,60 @@ +use crate::{LateContext, LateLintPass, LintContext}; + +use rustc_hir as hir; +use rustc_span::sym; + +declare_lint! { + /// The `multiple_supertrait_upcastable` lint detects when an object-safe trait has multiple + /// supertraits. + /// + /// ### Example + /// + /// ```rust + /// trait A {} + /// trait B {} + /// + /// #[warn(multiple_supertrait_upcastable)] + /// trait C: A + B {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// To support upcasting with multiple supertraits, we need to store multiple vtables and this + /// can result in extra space overhead, even if no code actually uses upcasting. + /// This lint allows users to identify when such scenarios occur and to decide whether the + /// additional overhead is justified. + pub MULTIPLE_SUPERTRAIT_UPCASTABLE, + Allow, + "detect when an object-safe trait has multiple supertraits", + @feature_gate = sym::multiple_supertrait_upcastable; +} + +declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTABLE]); + +impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + let def_id = item.owner_id.to_def_id(); + // NOTE(nbdd0121): use `object_safety_violations` instead of `check_is_object_safe` because + // the latter will report `where_clause_object_safety` lint. + if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind + && cx.tcx.object_safety_violations(def_id).is_empty() + { + let direct_super_traits_iter = cx.tcx + .super_predicates_of(def_id) + .predicates + .into_iter() + .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred()); + if direct_super_traits_iter.count() > 1 { + cx.emit_spanned_lint( + MULTIPLE_SUPERTRAIT_UPCASTABLE, + cx.tcx.def_span(def_id), + crate::lints::MultipleSupertraitUpcastable { + ident: item.ident + }, + ); + } + } + } +} |