Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #93541

Closed
wants to merge 21 commits into from
Closed
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b94da2b
Enable combining +crt-static and relocation-model=pic on x86_64-unkno…
bossmc Jun 16, 2021
6a88311
Check for -static-pie support before testing support
bossmc Nov 1, 2021
bae0da8
Implement data and vtable getters for `RawWaker`
oxalica Dec 12, 2021
d9b98f9
Eliminate duplicate codes of is_single_fp_element
woodenarrow Dec 17, 2021
368a83d
Configure panic hook backtrace behavior
Mark-Simulacrum Jan 26, 2022
746b3d8
Update compiler_builtins to fix duplicate symbols in `armv7-linux-and…
dcsommer Jan 28, 2022
7fcf774
update `FutureIncompatibilityReason`
lcnr Jan 27, 2022
ea62469
implement lint for suspicious auto trait impls
lcnr Jan 27, 2022
94b0a7b
silence lint in clippy
lcnr Feb 1, 2022
a1a30f7
add a rustc::query_stability lint
lcnr Jan 5, 2022
6970547
rustfmt is broken, manually reduce line length
lcnr Jan 19, 2022
4bbe970
review + rebase
lcnr Feb 1, 2022
7ebd48d
remove `TyS::same_type`
lcnr Jan 25, 2022
fd67672
Rollup merge of #86374 - bossmc:enable-static-pie-for-gnu, r=nagisa
matthiaskrgr Feb 1, 2022
9710096
Rollup merge of #91828 - oxalica:feat/waker-getters, r=dtolnay
matthiaskrgr Feb 1, 2022
9872329
Rollup merge of #92021 - woodenarrow:br_single_fp_element, r=Mark-Sim…
matthiaskrgr Feb 1, 2022
508fb37
Rollup merge of #92584 - lcnr:query-stable-lint, r=estebank
matthiaskrgr Feb 1, 2022
da8911e
Rollup merge of #93101 - Mark-Simulacrum:library-backtrace, r=yaahc
matthiaskrgr Feb 1, 2022
2707e49
Rollup merge of #93267 - lcnr:auto-trait-lint, r=nikomatsakis
matthiaskrgr Feb 1, 2022
2c3e750
Rollup merge of #93290 - lcnr:same_type, r=jackh726
matthiaskrgr Feb 1, 2022
fe62a2f
Rollup merge of #93436 - dcsommer:master, r=Mark-Simulacrum
matthiaskrgr Feb 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_index/src/bit_set.rs
Original file line number Diff line number Diff line change
@@ -938,6 +938,12 @@ pub struct GrowableBitSet<T: Idx> {
bit_set: BitSet<T>,
}

impl<T: Idx> Default for GrowableBitSet<T> {
fn default() -> Self {
GrowableBitSet::new_empty()
}
}

impl<T: Idx> GrowableBitSet<T> {
/// Ensure that the set can hold at least `min_domain_size` elements.
pub fn ensure(&mut self, min_domain_size: usize) {
43 changes: 43 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -1793,6 +1793,10 @@ declare_lint! {
Warn,
"detects name collision with an existing but unstable method",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::Custom(
"once this associated item is added to the standard library, \
the ambiguity may cause an error or change in behavior!"
),
reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
// Note: this item represents future incompatibility of all unstable functions in the
// standard library, and thus should never be removed or changed to an error.
@@ -2335,6 +2339,10 @@ declare_lint! {
Warn,
"reservation of a two-phased borrow conflicts with other shared borrows",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::Custom(
"this borrowing pattern was not meant to be accepted, \
and may become a hard error in the future"
),
reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>",
};
}
@@ -3046,6 +3054,7 @@ declare_lint_pass! {
DEREF_INTO_DYN_SUPERTRAIT,
DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
DUPLICATE_MACRO_ATTRIBUTES,
SUSPICIOUS_AUTO_TRAIT_IMPLS,
]
}

@@ -3622,3 +3631,37 @@ declare_lint! {
Warn,
"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
/// are currently unsound and quite subtle and and will be modified in the future.
/// This change will cause the automatic implementation to be disabled in more
/// cases, potentially breaking some code.
pub SUSPICIOUS_AUTO_TRAIT_IMPLS,
Warn,
"the rules governing auto traits will change in the future",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
reference: "issue #93367 <https://github.com/rust-lang/rust/issues/93367>",
};
}
5 changes: 5 additions & 0 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -163,12 +163,17 @@ pub enum FutureIncompatibilityReason {
/// This will be an error in a future release, and
/// Cargo should create a report even for dependencies
FutureReleaseErrorReportNow,
/// Code that changes meaning in some way in a
/// future release.
FutureReleaseSemanticsChange,
/// Previously accepted code that will become an
/// error in the provided edition
EditionError(Edition),
/// Code that changes meaning in some way in
/// the provided edition
EditionSemanticsChange(Edition),
/// A custom reason.
Custom(&'static str),
}

impl FutureIncompatibilityReason {
47 changes: 22 additions & 25 deletions compiler/rustc_middle/src/lint.rs
Original file line number Diff line number Diff line change
@@ -221,7 +221,6 @@ pub fn struct_lint_level<'s, 'd>(
decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b>) + 'd>,
) {
// Check for future incompatibility lints and issue a stronger warning.
let lint_id = LintId::of(lint);
let future_incompatible = lint.future_incompatible;

let has_future_breakage = future_incompatible.map_or(
@@ -345,31 +344,29 @@ pub fn struct_lint_level<'s, 'd>(
err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn });

if let Some(future_incompatible) = future_incompatible {
let explanation = if lint_id == LintId::of(builtin::UNSTABLE_NAME_COLLISIONS) {
"once this associated item is added to the standard library, the ambiguity may \
cause an error or change in behavior!"
.to_owned()
} else if lint_id == LintId::of(builtin::MUTABLE_BORROW_RESERVATION_CONFLICT) {
"this borrowing pattern was not meant to be accepted, and may become a hard error \
in the future"
.to_owned()
} else if let FutureIncompatibilityReason::EditionError(edition) =
future_incompatible.reason
{
let current_edition = sess.edition();
format!(
"this is accepted in the current edition (Rust {}) but is a hard error in Rust {}!",
current_edition, edition
)
} else if let FutureIncompatibilityReason::EditionSemanticsChange(edition) =
future_incompatible.reason
{
format!("this changes meaning in Rust {}", edition)
} else {
"this was previously accepted by the compiler but is being phased out; \
it will become a hard error in a future release!"
.to_owned()
let explanation = match future_incompatible.reason {
FutureIncompatibilityReason::FutureReleaseError
| FutureIncompatibilityReason::FutureReleaseErrorReportNow => {
"this was previously accepted by the compiler but is being phased out; \
it will become a hard error in a future release!"
.to_owned()
}
FutureIncompatibilityReason::FutureReleaseSemanticsChange => {
"this will change its meaning in a future release!".to_owned()
}
FutureIncompatibilityReason::EditionError(edition) => {
let current_edition = sess.edition();
format!(
"this is accepted in the current edition (Rust {}) but is a hard error in Rust {}!",
current_edition, edition
)
}
FutureIncompatibilityReason::EditionSemanticsChange(edition) => {
format!("this changes meaning in Rust {}", edition)
}
FutureIncompatibilityReason::Custom(reason) => reason.to_owned(),
};

if future_incompatible.explain_reason {
err.warn(&explanation);
}
17 changes: 17 additions & 0 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
@@ -144,6 +144,23 @@ impl<'tcx> TyCtxt<'tcx> {
});
}

pub fn non_blanket_impls_for_ty(
self,
def_id: DefId,
self_ty: Ty<'tcx>,
) -> impl Iterator<Item = DefId> + 'tcx {
let impls = self.trait_impls_of(def_id);
if let Some(simp) =
fast_reject::simplify_type(self, self_ty, SimplifyParams::No, StripReferences::No)
{
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
return impls.iter().copied();
}
}

[].iter().copied()
}

/// Applies function to every impl that could possibly match the self type `self_ty` and returns
/// the first non-none value.
pub fn find_map_relevant_impl<T, F: FnMut(DefId) -> Option<T>>(
213 changes: 210 additions & 3 deletions compiler/rustc_typeck/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
//! Orphan checker: every impl either implements a trait defined in this
//! crate or pertains to a type defined in this crate.
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_index::bit_set::GrowableBitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::def_id::LocalDefId;
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
use rustc_middle::ty::{self, ImplPolarity, Ty, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_session::lint;
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
use rustc_trait_selection::traits;
use std::ops::ControlFlow;

pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] {
let mut errors = Vec::new();
for (_trait, impls_of_trait) in tcx.all_local_trait_impls(()) {
for (&trait_def_id, impls_of_trait) in tcx.all_local_trait_impls(()) {
for &impl_of_trait in impls_of_trait {
match orphan_check_impl(tcx, impl_of_trait) {
Ok(()) => {}
Err(ErrorReported) => errors.push(impl_of_trait),
}
}

if tcx.trait_is_auto(trait_def_id) {
lint_auto_trait_impls(tcx, trait_def_id, impls_of_trait);
}
}
tcx.arena.alloc_slice(&errors)
}
@@ -265,3 +274,201 @@ fn emit_orphan_check_error<'tcx>(

Err(ErrorReported)
}

#[derive(Default)]
struct AreUniqueParamsVisitor {
seen: GrowableBitSet<u32>,
}

#[derive(Copy, Clone)]
enum NotUniqueParam<'tcx> {
DuplicateParam(GenericArg<'tcx>),
NotParam(GenericArg<'tcx>),
}

impl<'tcx> TypeVisitor<'tcx> for AreUniqueParamsVisitor {
type BreakTy = NotUniqueParam<'tcx>;
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Param(p) => {
if self.seen.insert(p.index) {
ControlFlow::CONTINUE
} else {
ControlFlow::Break(NotUniqueParam::DuplicateParam(t.into()))
}
}
_ => ControlFlow::Break(NotUniqueParam::NotParam(t.into())),
}
}
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match r {
ty::ReEarlyBound(p) => {
if self.seen.insert(p.index) {
ControlFlow::CONTINUE
} else {
ControlFlow::Break(NotUniqueParam::DuplicateParam(r.into()))
}
}
_ => ControlFlow::Break(NotUniqueParam::NotParam(r.into())),
}
}
fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match c.val {
ty::ConstKind::Param(p) => {
if self.seen.insert(p.index) {
ControlFlow::CONTINUE
} else {
ControlFlow::Break(NotUniqueParam::DuplicateParam(c.into()))
}
}
_ => ControlFlow::Break(NotUniqueParam::NotParam(c.into())),
}
}
}

/// Lint impls of auto traits if they are likely to have
/// unsound or surprising effects on auto impls.
fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDefId]) {
let mut non_covering_impls = Vec::new();
for &impl_def_id in impls {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
if trait_ref.references_error() {
return;
}

if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
return;
}

assert_eq!(trait_ref.substs.len(), 1);
let self_ty = trait_ref.self_ty();
let (self_type_did, substs) = match self_ty.kind() {
ty::Adt(def, substs) => (def.did, substs),
_ => {
// 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.
continue;
}
};

// Impls which completely cover a given root type are fine as they
// disable auto impls entirely. So only lint if the substs
// are not a permutation of the identity substs.
match substs.visit_with(&mut AreUniqueParamsVisitor::default()) {
ControlFlow::Continue(()) => {} // ok
ControlFlow::Break(arg) => {
// 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_def_id, self_ty) {
// ok
} else {
non_covering_impls.push((impl_def_id, self_type_did, arg));
}
}
}
}

for &(impl_def_id, self_type_did, arg) in &non_covering_impls {
tcx.struct_span_lint_hir(
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
tcx.hir().local_def_id_to_hir_id(impl_def_id),
tcx.def_span(impl_def_id),
|err| {
let mut err = err.build(&format!(
"cross-crate traits with a default impl, like `{}`, \
should not be specialized",
tcx.def_path_str(trait_def_id),
));
let item_span = tcx.def_span(self_type_did);
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
err.span_note(
item_span,
&format!(
"try using the same sequence of generic parameters as the {} definition",
self_descr,
),
);
match arg {
NotUniqueParam::DuplicateParam(arg) => {
err.note(&format!("`{}` is mentioned multiple times", arg));
}
NotUniqueParam::NotParam(arg) => {
err.note(&format!("`{}` is not a generic parameter", arg));
}
}
err.emit();
},
);
}
}

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<'tcx> for DisableAutoTraitVisitor<'tcx> {
type BreakTy = ();
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
let tcx = self.tcx;
if t != self.self_ty_root {
for impl_def_id in tcx.non_blanket_impls_for_ty(self.trait_def_id, t) {
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 t.kind() {
ty::Adt(def, substs) => {
// @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, substs)) {
ty.visit_with(self)?;
}
}

ControlFlow::CONTINUE
}
_ => t.super_visit_with(self),
}
}
}

let self_ty_root = match self_ty.kind() {
ty::Adt(def, _) => tcx.mk_adt(def, InternalSubsts::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()
}
34 changes: 34 additions & 0 deletions src/test/ui/auto-traits/suspicious-impls-lint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#![deny(suspicious_auto_trait_impls)]

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

fn main() {}
52 changes: 52 additions & 0 deletions src/test/ui/auto-traits/suspicious-impls-lint.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
error: cross-crate traits with a default impl, like `Send`, should not be specialized
--> $DIR/suspicious-impls-lint.rs:7:1
|
LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/suspicious-impls-lint.rs:1:9
|
LL | #![deny(suspicious_auto_trait_impls)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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: try using the same sequence of generic parameters as the struct definition
--> $DIR/suspicious-impls-lint.rs:6:1
|
LL | struct MayImplementSendErr<T>(T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `&T` is not a generic parameter

error: cross-crate traits with a default impl, like `Send`, should not be specialized
--> $DIR/suspicious-impls-lint.rs:19: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: try using the same sequence of generic parameters as the struct definition
--> $DIR/suspicious-impls-lint.rs:18:1
|
LL | struct ContainsVec<T>(Vec<T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `i32` is not a generic parameter

error: cross-crate traits with a default impl, like `Send`, should not be specialized
--> $DIR/suspicious-impls-lint.rs:30: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: try using the same sequence of generic parameters as the struct definition
--> $DIR/suspicious-impls-lint.rs:29:1
|
LL | struct TwoParamsSame<T, U>(T, U);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `T` is mentioned multiple times

error: aborting due to 3 previous errors

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// aux-build:tdticc_coherence_lib.rs
#![allow(suspicious_auto_trait_impls)]

// Test that we do not consider associated types to be sendable without
// some applicable trait bound (and we don't ICE).
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:13:1
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:14:1
|
LL | impl DefaultedTrait for (A,) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^----
@@ -10,7 +10,7 @@ LL | impl DefaultedTrait for (A,) { }
= 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
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:16:1
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:17:1
|
LL | impl !DefaultedTrait for (B,) { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^----
@@ -21,13 +21,13 @@ LL | impl !DefaultedTrait for (B,) { }
= 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
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:20:1
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
|
LL | impl DefaultedTrait for Box<C> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate

error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:21:1
--> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:22:1
|
LL | impl DefaultedTrait for lib::Something<C> { }
| ^^^^^^^^^^^^^^^^^^^^^^^^-----------------
1 change: 1 addition & 0 deletions src/tools/clippy/tests/ui/non_send_fields_in_send_ty.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![warn(clippy::non_send_fields_in_send_ty)]
#![allow(suspicious_auto_trait_impls)]
#![feature(extern_types)]

use std::cell::UnsafeCell;
52 changes: 26 additions & 26 deletions src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr
Original file line number Diff line number Diff line change
@@ -1,167 +1,167 @@
error: some fields in `RingBuffer<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:16:1
--> $DIR/non_send_fields_in_send_ty.rs:17:1
|
LL | unsafe impl<T> Send for RingBuffer<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
note: it is not safe to send field `data` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:11:5
--> $DIR/non_send_fields_in_send_ty.rs:12:5
|
LL | data: Vec<UnsafeCell<T>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
= help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`

error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:24:1
--> $DIR/non_send_fields_in_send_ty.rs:25:1
|
LL | unsafe impl<T> Send for MvccRwLock<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `lock` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:21:5
--> $DIR/non_send_fields_in_send_ty.rs:22:5
|
LL | lock: Mutex<Box<T>>,
| ^^^^^^^^^^^^^^^^^^^
= 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
--> $DIR/non_send_fields_in_send_ty.rs:32:1
--> $DIR/non_send_fields_in_send_ty.rs:33:1
|
LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `head` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:29:5
--> $DIR/non_send_fields_in_send_ty.rs:30:5
|
LL | head: Arc<RC>,
| ^^^^^^^^^^^^^
= 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
--> $DIR/non_send_fields_in_send_ty.rs:48:1
--> $DIR/non_send_fields_in_send_ty.rs:49:1
|
LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `context` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:44:5
--> $DIR/non_send_fields_in_send_ty.rs:45:5
|
LL | context: T,
| ^^^^^^^^^^
= help: add `T: Send` bound in `Send` impl

error: some fields in `NoGeneric` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:55:1
--> $DIR/non_send_fields_in_send_ty.rs:56:1
|
LL | unsafe impl Send for NoGeneric {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `rc_is_not_send` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:52:5
--> $DIR/non_send_fields_in_send_ty.rs:53:5
|
LL | rc_is_not_send: Rc<String>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`

error: some fields in `MultiField<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:63:1
--> $DIR/non_send_fields_in_send_ty.rs:64:1
|
LL | unsafe impl<T> Send for MultiField<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:58:5
--> $DIR/non_send_fields_in_send_ty.rs:59:5
|
LL | field1: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field2` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:59:5
--> $DIR/non_send_fields_in_send_ty.rs:60:5
|
LL | field2: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl
note: it is not safe to send field `field3` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:60:5
--> $DIR/non_send_fields_in_send_ty.rs:61:5
|
LL | field3: T,
| ^^^^^^^^^
= help: add `T: Send` bound in `Send` impl

error: some fields in `MyOption<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:70:1
--> $DIR/non_send_fields_in_send_ty.rs:71:1
|
LL | unsafe impl<T> Send for MyOption<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:66:12
--> $DIR/non_send_fields_in_send_ty.rs:67:12
|
LL | MySome(T),
| ^
= help: add `T: Send` bound in `Send` impl

error: some fields in `MultiParam<A, B>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:82:1
--> $DIR/non_send_fields_in_send_ty.rs:83:1
|
LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `vec` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:79:5
--> $DIR/non_send_fields_in_send_ty.rs:80:5
|
LL | vec: Vec<(A, B)>,
| ^^^^^^^^^^^^^^^^
= 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
--> $DIR/non_send_fields_in_send_ty.rs:100:1
--> $DIR/non_send_fields_in_send_ty.rs:101:1
|
LL | unsafe impl Send for HeuristicTest {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field4` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:95:5
--> $DIR/non_send_fields_in_send_ty.rs:96:5
|
LL | field4: (*const NonSend, Rc<u8>),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use a thread-safe type that implements `Send`

error: some fields in `AttrTest3<T>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:119:1
--> $DIR/non_send_fields_in_send_ty.rs:120:1
|
LL | unsafe impl<T> Send for AttrTest3<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `0` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:114:11
--> $DIR/non_send_fields_in_send_ty.rs:115:11
|
LL | Enum2(T),
| ^
= help: add `T: Send` bound in `Send` impl

error: some fields in `Complex<P, u32>` are not safe to be sent to another thread
--> $DIR/non_send_fields_in_send_ty.rs:127:1
--> $DIR/non_send_fields_in_send_ty.rs:128:1
|
LL | unsafe impl<P> Send for Complex<P, u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field1` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:123:5
--> $DIR/non_send_fields_in_send_ty.rs:124:5
|
LL | field1: A,
| ^^^^^^^^^
= 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
--> $DIR/non_send_fields_in_send_ty.rs:130:1
--> $DIR/non_send_fields_in_send_ty.rs:131:1
|
LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: it is not safe to send field `field2` to another thread
--> $DIR/non_send_fields_in_send_ty.rs:124:5
--> $DIR/non_send_fields_in_send_ty.rs:125:5
|
LL | field2: B,
| ^^^^^^^^^