1 use crate::{LateContext, LateLintPass, LintContext};
3 use rustc_errors::DelayDm;
8 /// The `multiple_supertrait_upcastable` lint detects when an object-safe trait has multiple
17 /// #[warn(multiple_supertrait_upcastable)]
25 /// To support upcasting with multiple supertraits, we need to store multiple vtables and this
26 /// can result in extra space overhead, even if no code actually uses upcasting.
27 /// This lint allows users to identify when such scenarios occur and to decide whether the
28 /// additional overhead is justified.
29 pub MULTIPLE_SUPERTRAIT_UPCASTABLE,
31 "detect when an object-safe trait has multiple supertraits",
32 @feature_gate = sym::multiple_supertrait_upcastable;
35 declare_lint_pass!(MultipleSupertraitUpcastable => [MULTIPLE_SUPERTRAIT_UPCASTABLE]);
37 impl<'tcx> LateLintPass<'tcx> for MultipleSupertraitUpcastable {
38 fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
39 let def_id = item.owner_id.to_def_id();
40 if let hir::ItemKind::Trait(_, _, _, _, _) = item.kind
41 && cx.tcx.is_object_safe(def_id)
43 let direct_super_traits_iter = cx.tcx
44 .super_predicates_of(def_id)
47 .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred());
48 if direct_super_traits_iter.count() > 1 {
50 MULTIPLE_SUPERTRAIT_UPCASTABLE,
51 cx.tcx.def_span(def_id),
54 "`{}` is object-safe and has multiple supertraits",