1 use crate::{LateContext, LateLintPass, LintContext};
7 /// The `multiple_supertrait_upcastable` lint detects when an object-safe trait has multiple
16 /// #[warn(multiple_supertrait_upcastable)]
24 /// To support upcasting with multiple supertraits, we need to store multiple vtables and this
25 /// can result in extra space overhead, even if no code actually uses upcasting.
26 /// This lint allows users to identify when such scenarios occur and to decide whether the
27 /// additional overhead is justified.
28 pub MULTIPLE_SUPERTRAIT_UPCASTABLE,
30 "detect when an object-safe trait has multiple supertraits",
31 @feature_gate = sym::multiple_supertrait_upcastable;
34 declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTABLE]);
36 impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
37 fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
38 let def_id = item.owner_id.to_def_id();
39 // NOTE(nbdd0121): use `object_safety_violations` instead of `check_is_object_safe` because
40 // the latter will report `where_clause_object_safety` lint.
41 if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind
42 && cx.tcx.object_safety_violations(def_id).is_empty()
44 let direct_super_traits_iter = cx.tcx
45 .super_predicates_of(def_id)
48 .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred());
49 if direct_super_traits_iter.count() > 1 {
51 MULTIPLE_SUPERTRAIT_UPCASTABLE,
52 cx.tcx.def_span(def_id),
53 crate::lints::MultipleSupertraitUpcastable {