mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Reintroduce multiple_supertrait_upcastable lint
This commit is contained in:
parent
94e59cb6e2
commit
66f3ab90a1
@ -100,6 +100,8 @@ lint_cstring_ptr = getting the inner pointer of a temporary `CString`
|
||||
.note = pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||
.help = for more information, see https://doc.rust-lang.org/reference/destructors.html
|
||||
|
||||
lint_multple_supertrait_upcastable = `{$ident}` is object-safe and has multiple supertraits
|
||||
|
||||
lint_identifier_non_ascii_char = identifier contains non-ASCII characters
|
||||
|
||||
lint_identifier_uncommon_codepoints = identifier contains uncommon Unicode codepoints
|
||||
|
@ -160,6 +160,8 @@ declare_features! (
|
||||
(active, intrinsics, "1.0.0", None, None),
|
||||
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
|
||||
(active, lang_items, "1.0.0", None, None),
|
||||
/// Allows the `multiple_supertrait_upcastable` lint.
|
||||
(active, multiple_supertrait_upcastable, "CURRENT_RUSTC_VERSION", None, None),
|
||||
/// Allows using `#[omit_gdb_pretty_printer_section]`.
|
||||
(active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
|
||||
/// Allows using `#[prelude_import]` on glob `use` items.
|
||||
|
@ -64,6 +64,7 @@ mod let_underscore;
|
||||
mod levels;
|
||||
mod lints;
|
||||
mod methods;
|
||||
mod multiple_supertrait_upcastable;
|
||||
mod non_ascii_idents;
|
||||
mod non_fmt_panic;
|
||||
mod nonstandard_style;
|
||||
@ -98,6 +99,7 @@ use hidden_unicode_codepoints::*;
|
||||
use internal::*;
|
||||
use let_underscore::*;
|
||||
use methods::*;
|
||||
use multiple_supertrait_upcastable::*;
|
||||
use non_ascii_idents::*;
|
||||
use non_fmt_panic::NonPanicFmt;
|
||||
use nonstandard_style::*;
|
||||
@ -232,6 +234,7 @@ late_lint_methods!(
|
||||
InvalidAtomicOrdering: InvalidAtomicOrdering,
|
||||
NamedAsmLabels: NamedAsmLabels,
|
||||
OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
|
||||
MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
|
||||
]
|
||||
]
|
||||
);
|
||||
|
@ -917,6 +917,13 @@ pub struct CStringPtr {
|
||||
pub unwrap: Span,
|
||||
}
|
||||
|
||||
// multiple_supertrait_upcastable.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_multple_supertrait_upcastable)]
|
||||
pub struct MultipleSupertraitUpcastable {
|
||||
pub ident: Ident,
|
||||
}
|
||||
|
||||
// non_ascii_idents.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_identifier_non_ascii_char)]
|
||||
|
60
compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
Normal file
60
compiler/rustc_lint/src/multiple_supertrait_upcastable.rs
Normal file
@ -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
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -955,6 +955,7 @@ symbols! {
|
||||
mul,
|
||||
mul_assign,
|
||||
mul_with_overflow,
|
||||
multiple_supertrait_upcastable,
|
||||
must_not_suspend,
|
||||
must_use,
|
||||
naked,
|
||||
|
@ -87,6 +87,7 @@
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(explicit_outlives_requirements)]
|
||||
#![cfg_attr(not(bootstrap), warn(multiple_supertrait_upcastable))]
|
||||
//
|
||||
// Library features:
|
||||
#![feature(alloc_layout_extra)]
|
||||
@ -195,6 +196,7 @@
|
||||
#![feature(c_unwind)]
|
||||
#![feature(with_negative_coherence)]
|
||||
#![cfg_attr(test, feature(panic_update_hook))]
|
||||
#![cfg_attr(not(bootstrap), feature(multiple_supertrait_upcastable))]
|
||||
//
|
||||
// Rustdoc features:
|
||||
#![feature(doc_cfg)]
|
||||
|
@ -28,6 +28,7 @@ use crate::fmt::{Debug, Display};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
|
||||
#[rustc_has_incoherent_inherent_impls]
|
||||
#[cfg_attr(not(bootstrap), allow(multiple_supertrait_upcastable))]
|
||||
pub trait Error: Debug + Display {
|
||||
/// The lower-level source of this error, if any.
|
||||
///
|
||||
|
@ -95,6 +95,7 @@
|
||||
#![warn(missing_docs)]
|
||||
#![allow(explicit_outlives_requirements)]
|
||||
#![allow(incomplete_features)]
|
||||
#![cfg_attr(not(bootstrap), warn(multiple_supertrait_upcastable))]
|
||||
//
|
||||
// Library features:
|
||||
#![feature(const_align_offset)]
|
||||
@ -235,6 +236,7 @@
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(asm_const)]
|
||||
#![feature(const_transmute_copy)]
|
||||
#![cfg_attr(not(bootstrap), feature(multiple_supertrait_upcastable))]
|
||||
//
|
||||
// Target features:
|
||||
#![feature(arm_target_feature)]
|
||||
|
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
|
||||
#![deny(multiple_supertrait_upcastable)]
|
||||
//~^ WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
//~| WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
//~| WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
#![warn(multiple_supertrait_upcastable)]
|
||||
//~^ WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
//~| WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
//~| WARNING unknown lint: `multiple_supertrait_upcastable`
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,57 @@
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:1
|
||||
|
|
||||
LL | #![deny(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
= note: `#[warn(unknown_lints)]` on by default
|
||||
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:7:1
|
||||
|
|
||||
LL | #![warn(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:1
|
||||
|
|
||||
LL | #![deny(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:7:1
|
||||
|
|
||||
LL | #![warn(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:1
|
||||
|
|
||||
LL | #![deny(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
|
||||
warning: unknown lint: `multiple_supertrait_upcastable`
|
||||
--> $DIR/feature-gate-multiple_supertrait_upcastable.rs:7:1
|
||||
|
|
||||
LL | #![warn(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the `multiple_supertrait_upcastable` lint is unstable
|
||||
= help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable
|
||||
|
||||
warning: 6 warnings emitted
|
||||
|
@ -0,0 +1,10 @@
|
||||
#![feature(multiple_supertrait_upcastable)]
|
||||
#![deny(multiple_supertrait_upcastable)]
|
||||
|
||||
trait A {}
|
||||
trait B {}
|
||||
|
||||
trait C: A + B {}
|
||||
//~^ ERROR `C` is object-safe and has multiple supertraits
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,14 @@
|
||||
error: `C` is object-safe and has multiple supertraits
|
||||
--> $DIR/multiple_supertrait_upcastable.rs:7:1
|
||||
|
|
||||
LL | trait C: A + B {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/multiple_supertrait_upcastable.rs:2:9
|
||||
|
|
||||
LL | #![deny(multiple_supertrait_upcastable)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
Loading…
Reference in New Issue
Block a user