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

make incoherent_auto_trait_objects a hard error #102474

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
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
36 changes: 0 additions & 36 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -1426,41 +1426,6 @@ declare_lint! {
};
}

declare_lint! {
/// The `order_dependent_trait_objects` lint detects a trait coherency
/// violation that would allow creating two trait impls for the same
/// dynamic trait object involving marker traits.
///
/// ### Example
///
/// ```rust,compile_fail
/// pub trait Trait {}
///
/// impl Trait for dyn Send + Sync { }
/// impl Trait for dyn Sync + Send { }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// A previous bug caused the compiler to interpret traits with different
/// orders (such as `Send + Sync` and `Sync + Send`) as distinct types
/// when they were intended to be treated the same. This allowed code to
/// define separate trait implementations when there should be a coherence
/// error. This is a [future-incompatible] lint to transition this to a
/// hard error in the future. See [issue #56484] for more details.
///
/// [issue #56484]: https://github.com/rust-lang/rust/issues/56484
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
Deny,
"trait-object types were treated as different depending on marker-trait order",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
};
}

declare_lint! {
/// The `coherence_leak_check` lint detects conflicting implementations of
/// a trait that are only distinguished by the old leak-check code.
@@ -3302,7 +3267,6 @@ declare_lint_pass! {
PATTERNS_IN_FNS_WITHOUT_BODY,
MISSING_FRAGMENT_SPECIFIER,
LATE_BOUND_LIFETIME_ARGUMENTS,
ORDER_DEPENDENT_TRAIT_OBJECTS,
COHERENCE_LEAK_CHECK,
DEPRECATED,
UNUSED_UNSAFE,
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -722,10 +722,6 @@ rustc_queries! {
separate_provide_extern
}

query issue33140_self_ty(key: DefId) -> Option<ty::Ty<'tcx>> {
desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
}

/// Maps a `DefId` of a type to a list of its inherent impls.
/// Contains implementations of methods that are inherent to a type.
/// Methods in these implementations don't need to be exported.
67 changes: 7 additions & 60 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
@@ -2109,45 +2109,9 @@ impl<'tcx> FieldDef {

pub type Attributes<'tcx> = impl Iterator<Item = &'tcx ast::Attribute>;
#[derive(Debug, PartialEq, Eq)]
pub enum ImplOverlapKind {
/// These impls are always allowed to overlap.
Permitted {
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
marker: bool,
},
/// These impls are allowed to overlap, but that raises
/// an issue #33140 future-compatibility warning.
///
/// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
/// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
///
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
/// that difference, making what reduces to the following set of impls:
///
/// ```compile_fail,(E0119)
/// trait Trait {}
/// impl Trait for dyn Send + Sync {}
/// impl Trait for dyn Sync + Send {}
/// ```
///
/// Obviously, once we made these types be identical, that code causes a coherence
/// error and a fairly big headache for us. However, luckily for us, the trait
/// `Trait` used in this case is basically a marker trait, and therefore having
/// overlapping impls for it is sound.
///
/// To handle this, we basically regard the trait as a marker trait, with an additional
/// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
/// it has the following restrictions:
///
/// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
/// positive impls.
/// 2. The trait-ref of both impls must be equal.
/// 3. The trait-ref of both impls must be a trait object type consisting only of
/// marker traits.
/// 4. Neither of the impls can have any where-clauses.
///
/// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
Issue33140,
pub struct PermittedImplOverlap {
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
pub marker: bool,
}

impl<'tcx> TyCtxt<'tcx> {
@@ -2229,13 +2193,13 @@ impl<'tcx> TyCtxt<'tcx> {
self,
def_id1: DefId,
def_id2: DefId,
) -> Option<ImplOverlapKind> {
) -> Option<PermittedImplOverlap> {
// If either trait impl references an error, they're allowed to overlap,
// as one of them essentially doesn't exist.
if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
|| self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
{
return Some(ImplOverlapKind::Permitted { marker: false });
return Some(PermittedImplOverlap { marker: false });
}

match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
@@ -2245,7 +2209,7 @@ impl<'tcx> TyCtxt<'tcx> {
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
def_id1, def_id2
);
return Some(ImplOverlapKind::Permitted { marker: false });
return Some(PermittedImplOverlap { marker: false });
}
(ImplPolarity::Positive, ImplPolarity::Negative)
| (ImplPolarity::Negative, ImplPolarity::Positive) => {
@@ -2273,25 +2237,8 @@ impl<'tcx> TyCtxt<'tcx> {
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
def_id1, def_id2
);
Some(ImplOverlapKind::Permitted { marker: true })
Some(PermittedImplOverlap { marker: true })
} else {
if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
if self_ty1 == self_ty2 {
debug!(
"impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
def_id1, def_id2
);
return Some(ImplOverlapKind::Issue33140);
} else {
debug!(
"impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
def_id1, def_id2, self_ty1, self_ty2
);
}
}
}

debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2);
None
}
1 change: 0 additions & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -63,7 +63,6 @@ pub use self::project::{normalize, normalize_projection_type, normalize_to};
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
pub use self::structural_match::{
search_for_adt_const_param_violation, search_for_structural_match_violation,
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
@@ -1752,7 +1752,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {

if other.evaluation.must_apply_considering_regions() {
match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
Some(ty::PermittedImplOverlap { marker: true }) => {
// Subtle: If the predicate we are evaluating has inference
// variables, do *not* allow discarding candidates due to
// marker trait impls.
72 changes: 26 additions & 46 deletions compiler/rustc_trait_selection/src/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
@@ -15,14 +15,13 @@ use specialization_graph::GraphExt;
use crate::errors::NegativePositiveConflict;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
use crate::traits::{self, coherence, ObligationCause};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, ImplSubject, TyCtxt};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
use rustc_span::{Span, DUMMY_SP};

use super::util;
@@ -260,9 +259,9 @@ pub(super) fn specialization_graph_provider(
let insert_result = sg.insert(tcx, impl_def_id.to_def_id(), overlap_mode);
// Report error if there was one.
let (overlap, used_to_be_allowed) = match insert_result {
Err(overlap) => (Some(overlap), None),
Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)),
Ok(None) => (None, None),
Err(overlap) => (Some(overlap), false),
Ok(Some(overlap)) => (Some(overlap.error), overlap.used_to_be_allowed),
Ok(None) => (None, false),
};

if let Some(overlap) = overlap {
@@ -286,7 +285,7 @@ fn report_overlap_conflict(
tcx: TyCtxt<'_>,
overlap: OverlapError,
impl_def_id: LocalDefId,
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
used_to_be_allowed: bool,
sg: &mut specialization_graph::Graph,
) {
let impl_polarity = tcx.impl_polarity(impl_def_id.to_def_id());
@@ -342,7 +341,7 @@ fn report_conflicting_impls(
tcx: TyCtxt<'_>,
overlap: OverlapError,
impl_def_id: LocalDefId,
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
used_to_be_allowed: bool,
sg: &mut specialization_graph::Graph,
) {
let impl_span = tcx.def_span(impl_def_id);
@@ -353,21 +352,16 @@ fn report_conflicting_impls(
fn decorate<G: EmissionGuarantee>(
tcx: TyCtxt<'_>,
overlap: OverlapError,
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
impl_span: Span,
err: LintDiagnosticBuilder<'_, G>,
) -> G {
let msg = format!(
"conflicting implementations of trait `{}`{}{}",
"conflicting implementations of trait `{}`{}",
overlap.trait_desc,
overlap
.self_desc
.clone()
.map_or_else(String::new, |ty| { format!(" for type `{}`", ty) }),
match used_to_be_allowed {
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
_ => "",
}
);
let mut err = err.build(&msg);
match tcx.span_of_impl(overlap.with_impl) {
@@ -401,39 +395,25 @@ fn report_conflicting_impls(
err.emit()
}

match used_to_be_allowed {
None => {
let reported = if overlap.with_impl.is_local()
|| tcx.orphan_check_impl(impl_def_id).is_ok()
{
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
Some(decorate(
tcx,
overlap,
used_to_be_allowed,
impl_span,
LintDiagnosticBuilder::new(err),
))
} else {
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
};
sg.has_errored = reported;
}
Some(kind) => {
let lint = match kind {
FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS,
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
};
tcx.struct_span_lint_hir(
lint,
tcx.hir().local_def_id_to_hir_id(impl_def_id),
impl_span,
|ldb| {
decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb);
},
);
}
};
if used_to_be_allowed {
tcx.struct_span_lint_hir(
COHERENCE_LEAK_CHECK,
tcx.hir().local_def_id_to_hir_id(impl_def_id),
impl_span,
|ldb| {
decorate(tcx, overlap, impl_span, ldb);
},
);
} else {
let reported = if overlap.with_impl.is_local() || tcx.orphan_check_impl(impl_def_id).is_ok()
{
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
Some(decorate(tcx, overlap, impl_span, LintDiagnosticBuilder::new(err)))
} else {
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
};
sg.has_errored = reported;
}
}

/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
Original file line number Diff line number Diff line change
@@ -8,16 +8,10 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitable};

pub use rustc_middle::traits::specialization_graph::*;

#[derive(Copy, Clone, Debug)]
pub enum FutureCompatOverlapErrorKind {
Issue33140,
LeakCheck,
}

#[derive(Debug)]
pub struct FutureCompatOverlapError {
pub error: OverlapError,
pub kind: FutureCompatOverlapErrorKind,
pub used_to_be_allowed: bool,
}

/// The result of attempting to insert an impl into a group of children.
@@ -146,10 +140,7 @@ impl ChildrenExt<'_> for Children {
if should_err {
Err(error)
} else {
*last_lint = Some(FutureCompatOverlapError {
error,
kind: FutureCompatOverlapErrorKind::LeakCheck,
});
*last_lint = Some(FutureCompatOverlapError { error, used_to_be_allowed: true });

Ok((false, false))
}
@@ -167,13 +158,7 @@ impl ChildrenExt<'_> for Children {
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
{
match overlap_kind {
ty::ImplOverlapKind::Permitted { marker: _ } => {}
ty::ImplOverlapKind::Issue33140 => {
*last_lint_mut = Some(FutureCompatOverlapError {
error: create_overlap_error(overlap),
kind: FutureCompatOverlapErrorKind::Issue33140,
});
}
ty::PermittedImplOverlap { marker: _ } => {}
}

return Ok((false, false));
49 changes: 0 additions & 49 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -353,54 +353,6 @@ fn instance_def_size_estimate<'tcx>(
}
}

/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
///
/// See [`ty::ImplOverlapKind::Issue33140`] for more details.
fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
debug!("issue33140_self_ty({:?})", def_id);

let trait_ref = tcx
.impl_trait_ref(def_id)
.unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id));

debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref);

let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive
&& tcx.associated_item_def_ids(trait_ref.def_id).is_empty();

// Check whether these impls would be ok for a marker trait.
if !is_marker_like {
debug!("issue33140_self_ty - not marker-like!");
return None;
}

// impl must be `impl Trait for dyn Marker1 + Marker2 + ...`
if trait_ref.substs.len() != 1 {
debug!("issue33140_self_ty - impl has substs!");
return None;
}

let predicates = tcx.predicates_of(def_id);
if predicates.parent.is_some() || !predicates.predicates.is_empty() {
debug!("issue33140_self_ty - impl has predicates {:?}!", predicates);
return None;
}

let self_ty = trait_ref.self_ty();
let self_ty_matches = match self_ty.kind() {
ty::Dynamic(ref data, re, _) if re.is_static() => data.principal().is_none(),
_ => false,
};

if self_ty_matches {
debug!("issue33140_self_ty - MATCHES!");
Some(self_ty)
} else {
debug!("issue33140_self_ty - non-matching self type");
None
}
}

/// Check if a function is async.
fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {
let node = tcx.hir().get_by_def_id(def_id.expect_local());
@@ -470,7 +422,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
param_env,
param_env_reveal_all_normalized,
instance_def_size_estimate,
issue33140_self_ty,
impl_defaultness,
conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
..*providers
19 changes: 0 additions & 19 deletions src/test/ui/lint/lint-incoherent-auto-trait-objects.rs

This file was deleted.

39 changes: 0 additions & 39 deletions src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr

This file was deleted.

8 changes: 5 additions & 3 deletions src/test/ui/traits/issue-33140-hack-boundaries.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#![feature(negative_impls)]
#![allow(order_dependent_trait_objects)]

// Check that the issue #33140 hack does not allow unintended things.
// Previously checked that the issue #33140 hack does not allow unintended things.
//
// Now just tests that we correctly detect overlap for trait objects.

// OK
// previously OK
trait Trait0 {}

impl Trait0 for dyn Send {}
impl Trait0 for dyn Send {}
//~^ ERROR E0119

// Problem 1: associated types
trait Trait1 {
26 changes: 17 additions & 9 deletions src/test/ui/traits/issue-33140-hack-boundaries.stderr
Original file line number Diff line number Diff line change
@@ -1,68 +1,76 @@
error[E0119]: conflicting implementations of trait `Trait0` for type `(dyn std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:11:1
|
LL | impl Trait0 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait0 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`

error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:18:1
--> $DIR/issue-33140-hack-boundaries.rs:20:1
|
LL | impl Trait1 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait1 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`

error[E0751]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
--> $DIR/issue-33140-hack-boundaries.rs:25:1
--> $DIR/issue-33140-hack-boundaries.rs:27:1
|
LL | impl Trait2 for dyn Send {}
| ------------------------ positive implementation here
LL | impl !Trait2 for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here

error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:32:1
--> $DIR/issue-33140-hack-boundaries.rs:34:1
|
LL | impl Trait3<dyn Sync> for dyn Send {}
| ---------------------------------- first implementation here
LL | impl Trait3<dyn Sync> for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`

error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:39:1
--> $DIR/issue-33140-hack-boundaries.rs:41:1
|
LL | impl<T: ?Sized> Trait4a for T {}
| ----------------------------- first implementation here
LL | impl Trait4a for dyn Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`

error[E0119]: conflicting implementations of trait `Trait4b` for type `()`
--> $DIR/issue-33140-hack-boundaries.rs:46:1
--> $DIR/issue-33140-hack-boundaries.rs:48:1
|
LL | impl Trait4b for () {}
| ------------------- first implementation here
LL | impl Trait4b for () {}
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`

error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:53:1
--> $DIR/issue-33140-hack-boundaries.rs:55:1
|
LL | impl Trait4c for dyn Trait1 + Send {}
| ---------------------------------- first implementation here
LL | impl Trait4c for dyn Trait1 + Send {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`

error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`
--> $DIR/issue-33140-hack-boundaries.rs:60:1
--> $DIR/issue-33140-hack-boundaries.rs:62:1
|
LL | impl<'a> Trait4d for dyn Send + 'a {}
| ---------------------------------- first implementation here
LL | impl<'a> Trait4d for dyn Send + 'a {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`

error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`
--> $DIR/issue-33140-hack-boundaries.rs:67:1
--> $DIR/issue-33140-hack-boundaries.rs:69:1
|
LL | impl Trait5 for dyn Send {}
| ------------------------ first implementation here
LL | impl Trait5 for dyn Send where u32: Copy {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`

error: aborting due to 8 previous errors
error: aborting due to 9 previous errors

Some errors have detailed explanations: E0119, E0751.
For more information about an error, try `rustc --explain E0119`.
12 changes: 3 additions & 9 deletions src/test/ui/traits/object/issue-33140-traitobject-crate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// check-pass

#![warn(order_dependent_trait_objects)]
#![allow(dyn_drop)]

// Check that traitobject 0.1.0 compiles
@@ -84,15 +81,12 @@ unsafe impl<T> Trait for dyn (::std::iter::Iterator<Item=T>) + Send + Sync { }
unsafe impl Trait for dyn (::std::marker::Send) + Send { }
unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
//~^ WARNING conflicting implementations of trait `Trait` for type
//~| WARNING this was previously accepted by the compiler but is being phased out
//~^ ERROR conflicting implementations of trait `Trait` for type
unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
//~^ WARNING conflicting implementations of trait `Trait` for type
//~| WARNING this was previously accepted by the compiler but is being phased out
//~^ ERROR conflicting implementations of trait `Trait` for type
unsafe impl Trait for dyn (::std::marker::Sync) + Sync { }
unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
//~^ WARNING conflicting implementations of trait `Trait` for type
//~| WARNING this was previously accepted by the compiler but is being phased out
//~^ ERROR conflicting implementations of trait `Trait` for type
unsafe impl Trait for dyn (::std::ops::Drop) + Send { }
unsafe impl Trait for dyn (::std::ops::Drop) + Sync { }
unsafe impl Trait for dyn (::std::ops::Drop) + Send + Sync { }
35 changes: 11 additions & 24 deletions src/test/ui/traits/object/issue-33140-traitobject-crate.stderr
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:86:1
error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
--> $DIR/issue-33140-traitobject-crate.rs:83:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
|
note: the lint level is defined here
--> $DIR/issue-33140-traitobject-crate.rs:3:9
|
LL | #![warn(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:89:1
error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
--> $DIR/issue-33140-traitobject-crate.rs:85:1
|
LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { }
| ------------------------------------------------------------- first implementation here
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
--> $DIR/issue-33140-traitobject-crate.rs:93:1
error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`
--> $DIR/issue-33140-traitobject-crate.rs:88:1
|
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send { }
LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { }
| ------------------------------------------------------ first implementation here
...
LL | unsafe impl Trait for dyn (::std::marker::Sync) + Send + Sync { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>

warning: 3 warnings emitted
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0119`.