Remove suspicious auto trait lint
This commit is contained in:
parent
eee9d2a773
commit
086463b227
23 changed files with 78 additions and 527 deletions
|
@ -1,20 +1,12 @@
|
||||||
//! Orphan checker: every impl either implements a trait defined in this
|
//! Orphan checker: every impl either implements a trait defined in this
|
||||||
//! crate or pertains to a type defined in this crate.
|
//! crate or pertains to a type defined in this crate.
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_errors::{DelayDm, ErrorGuaranteed};
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_middle::ty::util::CheckRegions;
|
use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_middle::ty::GenericArgs;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_middle::ty::{
|
|
||||||
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
|
||||||
TypeVisitor,
|
|
||||||
};
|
|
||||||
use rustc_session::lint;
|
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use std::ops::ControlFlow;
|
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
|
||||||
|
@ -26,12 +18,7 @@ pub(crate) fn orphan_check_impl(
|
||||||
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
|
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity();
|
||||||
trait_ref.error_reported()?;
|
trait_ref.error_reported()?;
|
||||||
|
|
||||||
let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
|
do_orphan_check_impl(tcx, trait_ref, impl_def_id)
|
||||||
if tcx.trait_is_auto(trait_ref.def_id) {
|
|
||||||
lint_auto_trait_impl(tcx, trait_ref, impl_def_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_orphan_check_impl<'tcx>(
|
fn do_orphan_check_impl<'tcx>(
|
||||||
|
@ -445,146 +432,3 @@ fn emit_orphan_check_error<'tcx>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lint impls of auto traits if they are likely to have
|
|
||||||
/// unsound or surprising effects on auto impls.
|
|
||||||
fn lint_auto_trait_impl<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
trait_ref: ty::TraitRef<'tcx>,
|
|
||||||
impl_def_id: LocalDefId,
|
|
||||||
) {
|
|
||||||
if trait_ref.args.len() != 1 {
|
|
||||||
tcx.dcx().span_delayed_bug(
|
|
||||||
tcx.def_span(impl_def_id),
|
|
||||||
"auto traits cannot have generic parameters",
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let self_ty = trait_ref.self_ty();
|
|
||||||
let (self_type_did, args) = match self_ty.kind() {
|
|
||||||
ty::Adt(def, args) => (def.did(), args),
|
|
||||||
_ => {
|
|
||||||
// FIXME: should also lint for stuff like `&i32` but
|
|
||||||
// considering that auto traits are unstable, that
|
|
||||||
// isn't too important for now as this only affects
|
|
||||||
// crates using `nightly`, and std.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Impls which completely cover a given root type are fine as they
|
|
||||||
// disable auto impls entirely. So only lint if the args
|
|
||||||
// are not a permutation of the identity args.
|
|
||||||
let Err(arg) = tcx.uses_unique_generic_params(args, CheckRegions::No) else {
|
|
||||||
// ok
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ideally:
|
|
||||||
//
|
|
||||||
// - compute the requirements for the auto impl candidate
|
|
||||||
// - check whether these are implied by the non covering impls
|
|
||||||
// - if not, emit the lint
|
|
||||||
//
|
|
||||||
// What we do here is a bit simpler:
|
|
||||||
//
|
|
||||||
// - badly check if an auto impl candidate definitely does not apply
|
|
||||||
// for the given simplified type
|
|
||||||
// - if so, do not lint
|
|
||||||
if fast_reject_auto_impl(tcx, trait_ref.def_id, self_ty) {
|
|
||||||
// ok
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tcx.node_span_lint(
|
|
||||||
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
|
||||||
tcx.local_def_id_to_hir_id(impl_def_id),
|
|
||||||
tcx.def_span(impl_def_id),
|
|
||||||
DelayDm(|| {
|
|
||||||
format!(
|
|
||||||
"cross-crate traits with a default impl, like `{}`, \
|
|
||||||
should not be specialized",
|
|
||||||
tcx.def_path_str(trait_ref.def_id),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
|lint| {
|
|
||||||
let item_span = tcx.def_span(self_type_did);
|
|
||||||
let self_descr = tcx.def_descr(self_type_did);
|
|
||||||
match arg {
|
|
||||||
ty::util::NotUniqueParam::DuplicateParam(arg) => {
|
|
||||||
lint.note(format!("`{arg}` is mentioned multiple times"));
|
|
||||||
}
|
|
||||||
ty::util::NotUniqueParam::NotParam(arg) => {
|
|
||||||
lint.note(format!("`{arg}` is not a generic parameter"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lint.span_note(
|
|
||||||
item_span,
|
|
||||||
format!(
|
|
||||||
"try using the same sequence of generic parameters as the {self_descr} definition",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {
|
|
||||||
struct DisableAutoTraitVisitor<'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
trait_def_id: DefId,
|
|
||||||
self_ty_root: Ty<'tcx>,
|
|
||||||
seen: FxHashSet<DefId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for DisableAutoTraitVisitor<'tcx> {
|
|
||||||
type BreakTy = ();
|
|
||||||
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
|
||||||
let tcx = self.tcx;
|
|
||||||
if ty != self.self_ty_root {
|
|
||||||
for impl_def_id in tcx.non_blanket_impls_for_ty(self.trait_def_id, ty) {
|
|
||||||
match tcx.impl_polarity(impl_def_id) {
|
|
||||||
ImplPolarity::Negative => return ControlFlow::Break(()),
|
|
||||||
ImplPolarity::Reservation => {}
|
|
||||||
// FIXME(@lcnr): That's probably not good enough, idk
|
|
||||||
//
|
|
||||||
// We might just want to take the rustdoc code and somehow avoid
|
|
||||||
// explicit impls for `Self`.
|
|
||||||
ImplPolarity::Positive => return ControlFlow::Continue(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match ty.kind() {
|
|
||||||
ty::Adt(def, args) if def.is_phantom_data() => args.visit_with(self),
|
|
||||||
ty::Adt(def, args) => {
|
|
||||||
// @lcnr: This is the only place where cycles can happen. We avoid this
|
|
||||||
// by only visiting each `DefId` once.
|
|
||||||
//
|
|
||||||
// This will be is incorrect in subtle cases, but I don't care :)
|
|
||||||
if self.seen.insert(def.did()) {
|
|
||||||
for ty in def.all_fields().map(|field| field.ty(tcx, args)) {
|
|
||||||
ty.visit_with(self)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
|
||||||
}
|
|
||||||
_ => ty.super_visit_with(self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let self_ty_root = match self_ty.kind() {
|
|
||||||
ty::Adt(def, _) => Ty::new_adt(tcx, *def, GenericArgs::identity_for_item(tcx, def.did())),
|
|
||||||
_ => unimplemented!("unexpected self ty {:?}", self_ty),
|
|
||||||
};
|
|
||||||
|
|
||||||
self_ty_root
|
|
||||||
.visit_with(&mut DisableAutoTraitVisitor {
|
|
||||||
tcx,
|
|
||||||
self_ty_root,
|
|
||||||
trait_def_id,
|
|
||||||
seen: FxHashSet::default(),
|
|
||||||
})
|
|
||||||
.is_break()
|
|
||||||
}
|
|
||||||
|
|
|
@ -524,6 +524,11 @@ fn register_builtins(store: &mut LintStore) {
|
||||||
"no longer needed, see RFC #3535 \
|
"no longer needed, see RFC #3535 \
|
||||||
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
|
<https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
|
||||||
);
|
);
|
||||||
|
store.register_removed(
|
||||||
|
"suspicious_auto_trait_impls",
|
||||||
|
"no longer needed, see #93367 \
|
||||||
|
<https://github.com/rust-lang/rust/issues/93367> for more information",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_internals(store: &mut LintStore) {
|
fn register_internals(store: &mut LintStore) {
|
||||||
|
|
|
@ -90,7 +90,6 @@ declare_lint_pass! {
|
||||||
SOFT_UNSTABLE,
|
SOFT_UNSTABLE,
|
||||||
STABLE_FEATURES,
|
STABLE_FEATURES,
|
||||||
STATIC_MUT_REFS,
|
STATIC_MUT_REFS,
|
||||||
SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
|
||||||
TEST_UNSTABLE_LINT,
|
TEST_UNSTABLE_LINT,
|
||||||
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
|
||||||
TRIVIAL_CASTS,
|
TRIVIAL_CASTS,
|
||||||
|
@ -4032,40 +4031,6 @@ declare_lint! {
|
||||||
"duplicated attribute"
|
"duplicated attribute"
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
|
||||||
/// The `suspicious_auto_trait_impls` lint checks for potentially incorrect
|
|
||||||
/// implementations of auto traits.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// struct Foo<T>(T);
|
|
||||||
///
|
|
||||||
/// unsafe impl<T> Send for Foo<*const T> {}
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// {{produces}}
|
|
||||||
///
|
|
||||||
/// ### Explanation
|
|
||||||
///
|
|
||||||
/// A type can implement auto traits, e.g. `Send`, `Sync` and `Unpin`,
|
|
||||||
/// in two different ways: either by writing an explicit impl or if
|
|
||||||
/// all fields of the type implement that auto trait.
|
|
||||||
///
|
|
||||||
/// The compiler disables the automatic implementation if an explicit one
|
|
||||||
/// exists for given type constructor. The exact rules governing this
|
|
||||||
/// were previously unsound, quite subtle, and have been recently modified.
|
|
||||||
/// This change caused the automatic implementation to be disabled in more
|
|
||||||
/// cases, potentially breaking some code.
|
|
||||||
pub SUSPICIOUS_AUTO_TRAIT_IMPLS,
|
|
||||||
Warn,
|
|
||||||
"the rules governing auto traits have recently changed resulting in potential breakage",
|
|
||||||
@future_incompatible = FutureIncompatibleInfo {
|
|
||||||
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
|
|
||||||
reference: "issue #93367 <https://github.com/rust-lang/rust/issues/93367>",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `deprecated_where_clause_location` lint detects when a where clause in front of the equals
|
/// The `deprecated_where_clause_location` lint detects when a where clause in front of the equals
|
||||||
/// in an associated type.
|
/// in an associated type.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![warn(clippy::non_send_fields_in_send_ty)]
|
#![warn(clippy::non_send_fields_in_send_ty)]
|
||||||
#![allow(suspicious_auto_trait_impls)]
|
|
||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
|
error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:17:1
|
--> $DIR/non_send_fields_in_send_ty.rs:16:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T> Send for RingBuffer<T> {}
|
LL | unsafe impl<T> Send for RingBuffer<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `data` to another thread
|
note: it is not safe to send field `data` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:12:5
|
--> $DIR/non_send_fields_in_send_ty.rs:11:5
|
||||||
|
|
|
|
||||||
LL | data: Vec<UnsafeCell<T>>,
|
LL | data: Vec<UnsafeCell<T>>,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -14,155 +14,155 @@ LL | data: Vec<UnsafeCell<T>>,
|
||||||
= help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`
|
= help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`
|
||||||
|
|
||||||
error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
|
error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:26:1
|
--> $DIR/non_send_fields_in_send_ty.rs:25:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T> Send for MvccRwLock<T> {}
|
LL | unsafe impl<T> Send for MvccRwLock<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `lock` to another thread
|
note: it is not safe to send field `lock` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:23:5
|
--> $DIR/non_send_fields_in_send_ty.rs:22:5
|
||||||
|
|
|
|
||||||
LL | lock: Mutex<Box<T>>,
|
LL | lock: Mutex<Box<T>>,
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
= help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
|
= help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
|
||||||
|
|
||||||
error: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
|
error: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:35:1
|
--> $DIR/non_send_fields_in_send_ty.rs:34:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
|
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `head` to another thread
|
note: it is not safe to send field `head` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:32:5
|
--> $DIR/non_send_fields_in_send_ty.rs:31:5
|
||||||
|
|
|
|
||||||
LL | head: Arc<RC>,
|
LL | head: Arc<RC>,
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
= help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
|
= help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
|
||||||
|
|
||||||
error: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
|
error: some fields in `DeviceHandle<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:52:1
|
--> $DIR/non_send_fields_in_send_ty.rs:51:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
|
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `context` to another thread
|
note: it is not safe to send field `context` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:48:5
|
--> $DIR/non_send_fields_in_send_ty.rs:47:5
|
||||||
|
|
|
|
||||||
LL | context: T,
|
LL | context: T,
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
|
|
||||||
error: some fields in `NoGeneric` are not safe to be sent to another thread
|
error: some fields in `NoGeneric` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:60:1
|
--> $DIR/non_send_fields_in_send_ty.rs:59:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl Send for NoGeneric {}
|
LL | unsafe impl Send for NoGeneric {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `rc_is_not_send` to another thread
|
note: it is not safe to send field `rc_is_not_send` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:57:5
|
--> $DIR/non_send_fields_in_send_ty.rs:56:5
|
||||||
|
|
|
|
||||||
LL | rc_is_not_send: Rc<String>,
|
LL | rc_is_not_send: Rc<String>,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: use a thread-safe type that implements `Send`
|
= help: use a thread-safe type that implements `Send`
|
||||||
|
|
||||||
error: some fields in `MultiField<T>` are not safe to be sent to another thread
|
error: some fields in `MultiField<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:69:1
|
--> $DIR/non_send_fields_in_send_ty.rs:68:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T> Send for MultiField<T> {}
|
LL | unsafe impl<T> Send for MultiField<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `field1` to another thread
|
note: it is not safe to send field `field1` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:64:5
|
--> $DIR/non_send_fields_in_send_ty.rs:63:5
|
||||||
|
|
|
|
||||||
LL | field1: T,
|
LL | field1: T,
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
note: it is not safe to send field `field2` to another thread
|
note: it is not safe to send field `field2` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:65:5
|
--> $DIR/non_send_fields_in_send_ty.rs:64:5
|
||||||
|
|
|
|
||||||
LL | field2: T,
|
LL | field2: T,
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
note: it is not safe to send field `field3` to another thread
|
note: it is not safe to send field `field3` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:66:5
|
--> $DIR/non_send_fields_in_send_ty.rs:65:5
|
||||||
|
|
|
|
||||||
LL | field3: T,
|
LL | field3: T,
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
|
|
||||||
error: some fields in `MyOption<T>` are not safe to be sent to another thread
|
error: some fields in `MyOption<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:77:1
|
--> $DIR/non_send_fields_in_send_ty.rs:76:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T> Send for MyOption<T> {}
|
LL | unsafe impl<T> Send for MyOption<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `0` to another thread
|
note: it is not safe to send field `0` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:73:12
|
--> $DIR/non_send_fields_in_send_ty.rs:72:12
|
||||||
|
|
|
|
||||||
LL | MySome(T),
|
LL | MySome(T),
|
||||||
| ^
|
| ^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
|
|
||||||
error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
|
error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:90:1
|
--> $DIR/non_send_fields_in_send_ty.rs:89:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
|
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `vec` to another thread
|
note: it is not safe to send field `vec` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:87:5
|
--> $DIR/non_send_fields_in_send_ty.rs:86:5
|
||||||
|
|
|
|
||||||
LL | vec: Vec<(A, B)>,
|
LL | vec: Vec<(A, B)>,
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
= help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
|
= help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
|
||||||
|
|
||||||
error: some fields in `HeuristicTest` are not safe to be sent to another thread
|
error: some fields in `HeuristicTest` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:109:1
|
--> $DIR/non_send_fields_in_send_ty.rs:108:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl Send for HeuristicTest {}
|
LL | unsafe impl Send for HeuristicTest {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `field4` to another thread
|
note: it is not safe to send field `field4` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:104:5
|
--> $DIR/non_send_fields_in_send_ty.rs:103:5
|
||||||
|
|
|
|
||||||
LL | field4: (*const NonSend, Rc<u8>),
|
LL | field4: (*const NonSend, Rc<u8>),
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= help: use a thread-safe type that implements `Send`
|
= help: use a thread-safe type that implements `Send`
|
||||||
|
|
||||||
error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
|
error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:129:1
|
--> $DIR/non_send_fields_in_send_ty.rs:128:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<T> Send for AttrTest3<T> {}
|
LL | unsafe impl<T> Send for AttrTest3<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `0` to another thread
|
note: it is not safe to send field `0` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:124:11
|
--> $DIR/non_send_fields_in_send_ty.rs:123:11
|
||||||
|
|
|
|
||||||
LL | Enum2(T),
|
LL | Enum2(T),
|
||||||
| ^
|
| ^
|
||||||
= help: add `T: Send` bound in `Send` impl
|
= help: add `T: Send` bound in `Send` impl
|
||||||
|
|
||||||
error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
|
error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:138:1
|
--> $DIR/non_send_fields_in_send_ty.rs:137:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<P> Send for Complex<P, u32> {}
|
LL | unsafe impl<P> Send for Complex<P, u32> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `field1` to another thread
|
note: it is not safe to send field `field1` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:134:5
|
--> $DIR/non_send_fields_in_send_ty.rs:133:5
|
||||||
|
|
|
|
||||||
LL | field1: A,
|
LL | field1: A,
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= help: add `P: Send` bound in `Send` impl
|
= help: add `P: Send` bound in `Send` impl
|
||||||
|
|
||||||
error: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread
|
error: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:142:1
|
--> $DIR/non_send_fields_in_send_ty.rs:141:1
|
||||||
|
|
|
|
||||||
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
|
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: it is not safe to send field `field2` to another thread
|
note: it is not safe to send field `field2` to another thread
|
||||||
--> $DIR/non_send_fields_in_send_ty.rs:135:5
|
--> $DIR/non_send_fields_in_send_ty.rs:134:5
|
||||||
|
|
|
|
||||||
LL | field2: B,
|
LL | field2: B,
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
|
@ -502,10 +502,6 @@ pub const DEFAULT_LINTS: &[Lint] = &[
|
||||||
label: "stable_features",
|
label: "stable_features",
|
||||||
description: r##"stable features found in `#[feature]` directive"##,
|
description: r##"stable features found in `#[feature]` directive"##,
|
||||||
},
|
},
|
||||||
Lint {
|
|
||||||
label: "suspicious_auto_trait_impls",
|
|
||||||
description: r##"the rules governing auto traits have recently changed resulting in potential breakage"##,
|
|
||||||
},
|
|
||||||
Lint {
|
Lint {
|
||||||
label: "suspicious_double_ref_op",
|
label: "suspicious_double_ref_op",
|
||||||
description: r##"suspicious call of trait method on `&&T`"##,
|
description: r##"suspicious call of trait method on `&&T`"##,
|
||||||
|
@ -778,7 +774,6 @@ pub const DEFAULT_LINT_GROUPS: &[LintGroup] = &[
|
||||||
"repr_transparent_external_private_fields",
|
"repr_transparent_external_private_fields",
|
||||||
"semicolon_in_expressions_from_macros",
|
"semicolon_in_expressions_from_macros",
|
||||||
"soft_unstable",
|
"soft_unstable",
|
||||||
"suspicious_auto_trait_impls",
|
|
||||||
"uninhabited_static",
|
"uninhabited_static",
|
||||||
"unstable_name_collisions",
|
"unstable_name_collisions",
|
||||||
"unstable_syntax_pre_expansion",
|
"unstable_syntax_pre_expansion",
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![deny(suspicious_auto_trait_impls)]
|
|
||||||
|
|
||||||
auto trait Trait<P> {} //~ ERROR auto traits cannot have generic parameters
|
auto trait Trait<P> {} //~ ERROR auto traits cannot have generic parameters
|
||||||
//~^ ERROR auto traits are experimental and possibly buggy
|
//~^ ERROR auto traits are experimental and possibly buggy
|
||||||
impl<P> Trait<P> for () {}
|
impl<P> Trait<P> for () {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0567]: auto traits cannot have generic parameters
|
error[E0567]: auto traits cannot have generic parameters
|
||||||
--> $DIR/issue-117789.rs:3:17
|
--> $DIR/issue-117789.rs:1:17
|
||||||
|
|
|
|
||||||
LL | auto trait Trait<P> {}
|
LL | auto trait Trait<P> {}
|
||||||
| -----^^^ help: remove the parameters
|
| -----^^^ help: remove the parameters
|
||||||
|
@ -7,7 +7,7 @@ LL | auto trait Trait<P> {}
|
||||||
| auto trait cannot have generic parameters
|
| auto trait cannot have generic parameters
|
||||||
|
|
||||||
error[E0658]: auto traits are experimental and possibly buggy
|
error[E0658]: auto traits are experimental and possibly buggy
|
||||||
--> $DIR/issue-117789.rs:3:1
|
--> $DIR/issue-117789.rs:1:1
|
||||||
|
|
|
|
||||||
LL | auto trait Trait<P> {}
|
LL | auto trait Trait<P> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![allow(suspicious_auto_trait_impls)]
|
|
||||||
// Tests that we don't incorrectly allow overlap between a builtin auto trait
|
// Tests that we don't incorrectly allow overlap between a builtin auto trait
|
||||||
// impl and a user written one. See #83857 for more details
|
// impl and a user written one. See #83857 for more details
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
||||||
--> $DIR/issue-83857-ub.rs:22:38
|
--> $DIR/issue-83857-ub.rs:21:38
|
||||||
|
|
|
|
||||||
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo<T, U>` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc`
|
= help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc`
|
||||||
note: required for `Foo<T, U>` to implement `WithAssoc`
|
note: required for `Foo<T, U>` to implement `WithAssoc`
|
||||||
--> $DIR/issue-83857-ub.rs:15:15
|
--> $DIR/issue-83857-ub.rs:14:15
|
||||||
|
|
|
|
||||||
LL | impl<T: Send> WithAssoc for T {
|
LL | impl<T: Send> WithAssoc for T {
|
||||||
| ---- ^^^^^^^^^ ^
|
| ---- ^^^^^^^^^ ^
|
||||||
|
@ -18,7 +18,7 @@ LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i
|
||||||
| +++++++++++++++++++++
|
| +++++++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
||||||
--> $DIR/issue-83857-ub.rs:22:80
|
--> $DIR/issue-83857-ub.rs:21:80
|
||||||
|
|
|
|
||||||
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i32) {
|
||||||
| ________________________________________________________________________________^
|
| ________________________________________________________________________________^
|
||||||
|
@ -31,7 +31,7 @@ LL | | }
|
||||||
|
|
|
|
||||||
= help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc`
|
= help: the trait `Send` is not implemented for `Foo<T, U>`, which is required by `Foo<T, U>: WithAssoc`
|
||||||
note: required for `Foo<T, U>` to implement `WithAssoc`
|
note: required for `Foo<T, U>` to implement `WithAssoc`
|
||||||
--> $DIR/issue-83857-ub.rs:15:15
|
--> $DIR/issue-83857-ub.rs:14:15
|
||||||
|
|
|
|
||||||
LL | impl<T: Send> WithAssoc for T {
|
LL | impl<T: Send> WithAssoc for T {
|
||||||
| ---- ^^^^^^^^^ ^
|
| ---- ^^^^^^^^^ ^
|
||||||
|
@ -43,7 +43,7 @@ LL | fn generic<T, U>(v: Foo<T, U>, f: fn(<Foo<T, U> as WithAssoc>::Output) -> i
|
||||||
| +++++++++++++++++++++
|
| +++++++++++++++++++++
|
||||||
|
|
||||||
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
error[E0277]: `Foo<T, U>` cannot be sent between threads safely
|
||||||
--> $DIR/issue-83857-ub.rs:25:11
|
--> $DIR/issue-83857-ub.rs:24:11
|
||||||
|
|
|
|
||||||
LL | f(foo(v));
|
LL | f(foo(v));
|
||||||
| --- ^ `Foo<T, U>` cannot be sent between threads safely
|
| --- ^ `Foo<T, U>` cannot be sent between threads safely
|
||||||
|
@ -52,7 +52,7 @@ LL | f(foo(v));
|
||||||
|
|
|
|
||||||
= help: the trait `Send` is not implemented for `Foo<T, U>`
|
= help: the trait `Send` is not implemented for `Foo<T, U>`
|
||||||
note: required by a bound in `foo`
|
note: required by a bound in `foo`
|
||||||
--> $DIR/issue-83857-ub.rs:29:11
|
--> $DIR/issue-83857-ub.rs:28:11
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output {
|
LL | fn foo<T: Send>(x: T) -> <T as WithAssoc>::Output {
|
||||||
| ^^^^ required by this bound in `foo`
|
| ^^^^ required by this bound in `foo`
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
#![deny(suspicious_auto_trait_impls)]
|
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
struct MayImplementSendOk<T>(T);
|
|
||||||
unsafe impl<T: Send> Send for MayImplementSendOk<T> {} // ok
|
|
||||||
|
|
||||||
struct MayImplementSendErr<T>(T);
|
|
||||||
unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
struct ContainsNonSendDirect<T>(*const T);
|
|
||||||
unsafe impl<T: Send> Send for ContainsNonSendDirect<&T> {} // ok
|
|
||||||
|
|
||||||
struct ContainsPtr<T>(*const T);
|
|
||||||
struct ContainsIndirectNonSend<T>(ContainsPtr<T>);
|
|
||||||
unsafe impl<T: Send> Send for ContainsIndirectNonSend<&T> {} // ok
|
|
||||||
|
|
||||||
struct ContainsVec<T>(Vec<T>);
|
|
||||||
unsafe impl Send for ContainsVec<i32> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
struct TwoParams<T, U>(T, U);
|
|
||||||
unsafe impl<T: Send, U: Send> Send for TwoParams<T, U> {} // ok
|
|
||||||
|
|
||||||
struct TwoParamsFlipped<T, U>(T, U);
|
|
||||||
unsafe impl<T: Send, U: Send> Send for TwoParamsFlipped<U, T> {} // ok
|
|
||||||
|
|
||||||
struct TwoParamsSame<T, U>(T, U);
|
|
||||||
unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
pub struct WithPhantomDataNonSend<T, U>(PhantomData<*const T>, U);
|
|
||||||
unsafe impl<T> Send for WithPhantomDataNonSend<T, i8> {} // ok
|
|
||||||
|
|
||||||
pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
|
|
||||||
unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
pub struct WithLifetime<'a, T>(&'a (), T);
|
|
||||||
unsafe impl<T> Send for WithLifetime<'static, T> {} // ok
|
|
||||||
unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,82 +0,0 @@
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:9:1
|
|
||||||
|
|
|
||||||
LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `&T` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:8:1
|
|
||||||
|
|
|
||||||
LL | struct MayImplementSendErr<T>(T);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:1:9
|
|
||||||
|
|
|
||||||
LL | #![deny(suspicious_auto_trait_impls)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:21:1
|
|
||||||
|
|
|
||||||
LL | unsafe impl Send for ContainsVec<i32> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `i32` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:20:1
|
|
||||||
|
|
|
||||||
LL | struct ContainsVec<T>(Vec<T>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:32:1
|
|
||||||
|
|
|
||||||
LL | unsafe impl<T: Send> Send for TwoParamsSame<T, T> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `T` is mentioned multiple times
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:31:1
|
|
||||||
|
|
|
||||||
LL | struct TwoParamsSame<T, U>(T, U);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:40:1
|
|
||||||
|
|
|
||||||
LL | unsafe impl<T> Send for WithPhantomDataSend<*const T, i8> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `*const T` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:39:1
|
|
||||||
|
|
|
||||||
LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Sync`, should not be specialized
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:46:1
|
|
||||||
|
|
|
||||||
LL | unsafe impl<T> Sync for WithLifetime<'static, Vec<T>> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `Vec<T>` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-impls-lint.rs:44:1
|
|
||||||
|
|
|
||||||
LL | pub struct WithLifetime<'a, T>(&'a (), T);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#![feature(negative_impls)]
|
|
||||||
#![deny(suspicious_auto_trait_impls)]
|
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
struct ContainsVec<T>(Vec<T>);
|
|
||||||
impl !Send for ContainsVec<u32> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
|
|
||||||
impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
pub struct WithLifetime<'a, T>(&'a (), T);
|
|
||||||
impl<T> !Sync for WithLifetime<'static, Option<T>> {}
|
|
||||||
//~^ ERROR
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -1,52 +0,0 @@
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:7:1
|
|
||||||
|
|
|
||||||
LL | impl !Send for ContainsVec<u32> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `u32` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:6:1
|
|
||||||
|
|
|
||||||
LL | struct ContainsVec<T>(Vec<T>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:2:9
|
|
||||||
|
|
|
||||||
LL | #![deny(suspicious_auto_trait_impls)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:12:1
|
|
||||||
|
|
|
||||||
LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `*const T` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:11:1
|
|
||||||
|
|
|
||||||
LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: cross-crate traits with a default impl, like `Sync`, should not be specialized
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:17:1
|
|
||||||
|
|
|
||||||
LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `Option<T>` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/suspicious-negative-impls-lint.rs:16:1
|
|
||||||
|
|
|
||||||
LL | pub struct WithLifetime<'a, T>(&'a (), T);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
|
@ -13,7 +13,5 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
|
||||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||||
|
|
||||||
impl !Send for TestType<i32> {}
|
impl !Send for TestType<i32> {}
|
||||||
//~^ WARNING
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -16,23 +16,7 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||||
|
|
||||||
warning: cross-crate traits with a default impl, like `Send`, should not be specialized
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1
|
|
||||||
|
|
|
||||||
LL | impl !Send for TestType<i32> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `i32` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
|
|
||||||
|
|
|
||||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: `#[warn(suspicious_auto_trait_impls)]` on by default
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0119, E0751.
|
Some errors have detailed explanations: E0119, E0751.
|
||||||
For more information about an error, try `rustc --explain E0119`.
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
|
|
|
@ -18,7 +18,5 @@ impl TheTrait<isize> for TheType { }
|
||||||
//~^ ERROR not all trait items implemented
|
//~^ ERROR not all trait items implemented
|
||||||
|
|
||||||
impl !Send for Vec<isize> {} //~ ERROR E0117
|
impl !Send for Vec<isize> {} //~ ERROR E0117
|
||||||
//~^ WARNING
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -21,19 +21,6 @@ LL | impl !Send for Vec<isize> { }
|
||||||
|
|
|
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
warning: cross-crate traits with a default impl, like `Send`, should not be specialized
|
|
||||||
--> $DIR/coherence-orphan.rs:20:1
|
|
||||||
|
|
|
||||||
LL | impl !Send for Vec<isize> { }
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `isize` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
|
||||||
= note: `#[warn(suspicious_auto_trait_impls)]` on by default
|
|
||||||
|
|
||||||
error[E0046]: not all trait items implemented, missing: `the_fn`
|
error[E0046]: not all trait items implemented, missing: `the_fn`
|
||||||
--> $DIR/coherence-orphan.rs:10:1
|
--> $DIR/coherence-orphan.rs:10:1
|
||||||
|
|
|
|
||||||
|
@ -58,7 +45,7 @@ LL | impl TheTrait<isize> for TheType { }
|
||||||
|
|
|
|
||||||
= help: implement the missing item: `fn the_fn(&self) { todo!() }`
|
= help: implement the missing item: `fn the_fn(&self) { todo!() }`
|
||||||
|
|
||||||
error: aborting due to 5 previous errors; 1 warning emitted
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0117.
|
Some errors have detailed explanations: E0046, E0117.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
|
|
@ -15,16 +15,20 @@ struct Test;
|
||||||
|
|
||||||
trait Fold<F> {}
|
trait Fold<F> {}
|
||||||
|
|
||||||
impl<T, F> Fold<F> for Cons<T> // 0
|
impl<T, F> Fold<F> for Cons<T>
|
||||||
|
// 0
|
||||||
where
|
where
|
||||||
T: Fold<Nil>,
|
T: Fold<Nil>,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, F> Fold<F> for Cons<T> // 1
|
impl<T, F> Fold<F> for Cons<T>
|
||||||
|
// 1
|
||||||
where
|
where
|
||||||
T: Fold<F>,
|
T: Fold<F>,
|
||||||
private::Is<T>: private::NotNil,
|
private::Is<T>: private::NotNil,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<F> Fold<F> for Test {} // 2
|
impl<F> Fold<F> for Test {} // 2
|
||||||
|
|
||||||
|
@ -34,7 +38,6 @@ mod private {
|
||||||
pub struct Is<T>(T);
|
pub struct Is<T>(T);
|
||||||
pub auto trait NotNil {}
|
pub auto trait NotNil {}
|
||||||
|
|
||||||
#[allow(suspicious_auto_trait_impls)]
|
|
||||||
impl !NotNil for Is<Nil> {}
|
impl !NotNil for Is<Nil> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,5 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
|
||||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||||
|
|
||||||
impl !Send for TestType<i32> {}
|
impl !Send for TestType<i32> {}
|
||||||
//~^ WARNING
|
|
||||||
//~| WARNING this will change its meaning
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -16,23 +16,7 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||||
|
|
||||||
warning: cross-crate traits with a default impl, like `Send`, should not be specialized
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/issue-106755.rs:17:1
|
|
||||||
|
|
|
||||||
LL | impl !Send for TestType<i32> {}
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this will change its meaning in a future release!
|
|
||||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
|
||||||
= note: `i32` is not a generic parameter
|
|
||||||
note: try using the same sequence of generic parameters as the struct definition
|
|
||||||
--> $DIR/issue-106755.rs:9:1
|
|
||||||
|
|
|
||||||
LL | struct TestType<T>(::std::marker::PhantomData<T>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: `#[warn(suspicious_auto_trait_impls)]` on by default
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 1 warning emitted
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0119, E0751.
|
Some errors have detailed explanations: E0119, E0751.
|
||||||
For more information about an error, try `rustc --explain E0119`.
|
For more information about an error, try `rustc --explain E0119`.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//@ aux-build:tdticc_coherence_lib.rs
|
//@ aux-build:tdticc_coherence_lib.rs
|
||||||
#![allow(suspicious_auto_trait_impls)]
|
|
||||||
|
|
||||||
// Test that we do not consider associated types to be sendable without
|
// Test that we do not consider associated types to be sendable without
|
||||||
// some applicable trait bound (and we don't ICE).
|
// some applicable trait bound (and we don't ICE).
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||||
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:14:1
|
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:13:1
|
||||||
|
|
|
|
||||||
LL | impl DefaultedTrait for (A,) {}
|
LL | impl DefaultedTrait for (A,) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^----
|
| ^^^^^^^^^^^^^^^^^^^^^^^^----
|
||||||
|
@ -10,7 +10,7 @@ LL | impl DefaultedTrait for (A,) { }
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||||
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:17:1
|
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:16:1
|
||||||
|
|
|
|
||||||
LL | impl !DefaultedTrait for (B,) {}
|
LL | impl !DefaultedTrait for (B,) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^----
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^----
|
||||||
|
@ -21,13 +21,13 @@ LL | impl !DefaultedTrait for (B,) { }
|
||||||
= note: define and implement a trait or new type instead
|
= note: define and implement a trait or new type instead
|
||||||
|
|
||||||
error[E0321]: cross-crate traits with a default impl, like `DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate
|
error[E0321]: cross-crate traits with a default impl, like `DefaultedTrait`, can only be implemented for a struct/enum type defined in the current crate
|
||||||
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
|
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:20:1
|
||||||
|
|
|
|
||||||
LL | impl DefaultedTrait for Box<C> {}
|
LL | impl DefaultedTrait for Box<C> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate
|
||||||
|
|
||||||
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
|
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
|
||||||
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:22:1
|
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
|
||||||
|
|
|
|
||||||
LL | impl DefaultedTrait for lib::Something<C> {}
|
LL | impl DefaultedTrait for lib::Something<C> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^-----------------
|
| ^^^^^^^^^^^^^^^^^^^^^^^^-----------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue