diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 070551c0b7b0a..3156f17e0c4c5 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -492,6 +492,7 @@ define_dep_nodes!( <'tcx> [] AdtDefOfItem(DefId), [] ImplTraitRef(DefId), [] ImplPolarity(DefId), + [] Issue33140SelfTy(DefId), [] FnSignature(DefId), [] CoerceUnsizedInfo(DefId), diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 1a9f1ada111bd..b42d742b7f841 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -56,6 +56,8 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::{OverlapError, specialization_graph, translate_substs}; pub use self::specialize::find_associated_item; +pub use self::specialize::specialization_graph::FutureCompatOverlapError; +pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; pub use self::engine::{TraitEngine, TraitEngineExt}; pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs}; pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 9ad974d8e084a..6db6fe31fba70 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -2260,7 +2260,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ImplCandidate(victim_def) => { let tcx = self.tcx().global_tcx(); return tcx.specializes((other_def, victim_def)) - || tcx.impls_are_allowed_to_overlap(other_def, victim_def); + || tcx.impls_are_allowed_to_overlap( + other_def, victim_def).is_some(); } ParamCandidate(ref cand) => { // Prefer the impl to a global where clause candidate. diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 5ab54b2c99d42..e5ed16e755860 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -14,11 +14,10 @@ pub mod specialization_graph; use hir::def_id::DefId; use infer::{InferCtxt, InferOk}; use lint; -use traits::coherence; +use traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use syntax_pos::DUMMY_SP; -use traits::{self, ObligationCause, TraitEngine}; use traits::select::IntercrateAmbiguityCause; use ty::{self, TyCtxt, TypeFoldable}; use ty::subst::{Subst, Substs}; @@ -27,6 +26,7 @@ use super::{SelectionContext, FulfillmentContext}; use super::util::impl_trait_ref_and_oblig; /// Information pertinent to an overlapping impl error. +#[derive(Debug)] pub struct OverlapError { pub with_impl: DefId, pub trait_desc: String, @@ -310,8 +310,9 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>( let insert_result = sg.insert(tcx, impl_def_id); // Report error if there was one. let (overlap, used_to_be_allowed) = match insert_result { - Err(overlap) => (Some(overlap), false), - Ok(opt_overlap) => (opt_overlap, true) + Err(overlap) => (Some(overlap), None), + Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)), + Ok(None) => (None, None) }; if let Some(overlap) = overlap { @@ -321,14 +322,20 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>( String::new(), |ty| { format!(" for type `{}`", ty) }), - if used_to_be_allowed { " (E0119)" } else { "" } + if used_to_be_allowed.is_some() { " (E0119)" } else { "" } ); let impl_span = tcx.sess.source_map().def_span( tcx.span_of_impl(impl_def_id).unwrap() ); - let mut err = if used_to_be_allowed { + let mut err = if let Some(kind) = used_to_be_allowed { + let lint = match kind { + FutureCompatOverlapErrorKind::Issue43355 => + lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS, + FutureCompatOverlapErrorKind::Issue33140 => + lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS, + }; tcx.struct_span_lint_node( - lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS, + lint, tcx.hir().as_local_node_id(impl_def_id).unwrap(), impl_span, &msg) diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index c22adeb55a269..e5780a26a1918 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -58,10 +58,22 @@ struct Children { blanket_impls: Vec, } +#[derive(Copy, Clone, Debug)] +pub enum FutureCompatOverlapErrorKind { + Issue43355, + Issue33140, +} + +#[derive(Debug)] +pub struct FutureCompatOverlapError { + pub error: OverlapError, + pub kind: FutureCompatOverlapErrorKind +} + /// The result of attempting to insert an impl into a group of children. enum Inserted { /// The impl was inserted as a new child in this group of children. - BecameNewSibling(Option), + BecameNewSibling(Option), /// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc. ReplaceChildren(Vec), @@ -162,7 +174,19 @@ impl<'a, 'gcx, 'tcx> Children { impl_def_id, traits::IntercrateMode::Issue43355, |overlap| { - if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { + if let Some(overlap_kind) = + tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) + { + match overlap_kind { + ty::ImplOverlapKind::Permitted => {} + ty::ImplOverlapKind::Issue33140 => { + last_lint = Some(FutureCompatOverlapError { + error: overlap_error(overlap), + kind: FutureCompatOverlapErrorKind::Issue33140 + }); + } + } + return Ok((false, false)); } @@ -190,13 +214,23 @@ impl<'a, 'gcx, 'tcx> Children { replace_children.push(possible_sibling); } else { - if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { + if let None = tcx.impls_are_allowed_to_overlap( + impl_def_id, possible_sibling) + { + // do future-compat checks for overlap. Have issue #33140 + // errors overwrite issue #43355 errors when both are present. + traits::overlapping_impls( tcx, possible_sibling, impl_def_id, traits::IntercrateMode::Fixed, - |overlap| last_lint = Some(overlap_error(overlap)), + |overlap| { + last_lint = Some(FutureCompatOverlapError { + error: overlap_error(overlap), + kind: FutureCompatOverlapErrorKind::Issue43355 + }); + }, || (), ); } @@ -263,7 +297,7 @@ impl<'a, 'gcx, 'tcx> Graph { pub fn insert(&mut self, tcx: TyCtxt<'a, 'gcx, 'tcx>, impl_def_id: DefId) - -> Result, OverlapError> { + -> Result, OverlapError> { assert!(impl_def_id.is_local()); let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d40dd830e9fb9..aa3ff5e4a2dc2 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2637,6 +2637,45 @@ impl<'gcx> ::std::ops::Deref for Attributes<'gcx> { } } +#[derive(Debug, PartialEq, Eq)] +pub enum ImplOverlapKind { + /// These impls are always allowed to overlap. + Permitted, + /// 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: + /// + /// ``` + /// 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 +} + impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> { self.typeck_tables_of(self.hir().body_owner_def_id(body)) @@ -2788,8 +2827,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated #[marker] and prevents item overrides. - pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool { - if self.features().overlapping_marker_traits { + pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) + -> Option + { + let is_legit = if self.features().overlapping_marker_traits { let trait1_is_empty = self.impl_trait_ref(def_id1) .map_or(false, |trait_ref| { self.associated_item_def_ids(trait_ref.def_id).is_empty() @@ -2811,6 +2852,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { && is_marker_impl(def_id2) } else { false + }; + + if is_legit { + debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted)", + def_id1, def_id2); + Some(ImplOverlapKind::Permitted) + } 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 } } @@ -3203,6 +3267,59 @@ fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } +/// If `def_id` is an issue 33140 hack impl, return its self type. Otherwise +/// return None. +/// +/// See ImplOverlapKind::Issue33140 for more details. +fn issue33140_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> Option> +{ + 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) == hir::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.sty { + ty::Dynamic(ref data, ty::ReStatic) => 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 + } +} + pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); @@ -3221,6 +3338,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { crate_hash, trait_impls_of: trait_def::trait_impls_of_provider, instance_def_size_estimate, + issue33140_self_ty, ..*providers }; } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 4d026b97233ee..99dd3569491bc 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -202,6 +202,8 @@ define_queries! { <'tcx> [] fn impl_trait_ref: ImplTraitRef(DefId) -> Option>, [] fn impl_polarity: ImplPolarity(DefId) -> hir::ImplPolarity, + + [] fn issue33140_self_ty: Issue33140SelfTy(DefId) -> Option>, }, TypeChecking { diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 6887f480f72e0..9a1ab559688a8 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1275,6 +1275,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); } DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); } DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); } + DepKind::Issue33140SelfTy => { force!(issue33140_self_ty, def_id!()); } DepKind::FnSignature => { force!(fn_sig, def_id!()); } DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); } DepKind::ItemVariances => { force!(variances_of, def_id!()); } diff --git a/src/test/run-pass/issues/issue-33140.rs b/src/test/run-pass/issues/issue-33140.rs deleted file mode 100644 index 4d91af2fb19ca..0000000000000 --- a/src/test/run-pass/issues/issue-33140.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![allow(order_dependent_trait_objects)] - -trait Trait { - fn xyz() -> bool; -} - -impl Trait for dyn Send + Sync { - fn xyz() -> bool { false } -} - -impl Trait for dyn Sync + Send { - fn xyz() -> bool { true } -} - -trait Trait2 { - fn uvw() -> bool; -} - -impl Trait2 for dyn Send + Sync { - fn uvw() -> bool { false } -} - -impl Trait2 for dyn Sync + Send + Sync { - fn uvw() -> bool { true } -} - -struct Foo(T); -impl Foo { - fn abc() -> bool { - false - } -} - -impl Foo { - fn abc() -> bool { - true - } -} - -fn main() { - assert_eq!(::xyz(), false); - assert_eq!(::xyz(), true); - assert_eq!(::uvw(), false); - assert_eq!(::uvw(), true); - assert_eq!(>::abc(), false); - assert_eq!(>::abc(), true); -} diff --git a/src/test/ui/issues/issue-33140-hack-boundaries.rs b/src/test/ui/issues/issue-33140-hack-boundaries.rs new file mode 100644 index 0000000000000..fbdef51c13255 --- /dev/null +++ b/src/test/ui/issues/issue-33140-hack-boundaries.rs @@ -0,0 +1,80 @@ +#![feature(optin_builtin_traits)] +#![allow(order_dependent_trait_objects)] + +// Check that the issue #33140 hack does not allow unintended things. + +// OK +trait Trait0 { +} + +impl Trait0 for dyn Send {} +impl Trait0 for dyn Send {} + +// Problem 1: associated types +trait Trait1 { + fn my_fn(&self) {} +} + +impl Trait1 for dyn Send {} +impl Trait1 for dyn Send {} +//~^ ERROR E0119 + +// Problem 2: negative impl +trait Trait2 { +} + +impl Trait2 for dyn Send {} +impl !Trait2 for dyn Send {} +//~^ ERROR E0119 + + +// Problem 3: type parameter +trait Trait3 { +} + +impl Trait3 for dyn Send {} +impl Trait3 for dyn Send {} +//~^ ERROR E0119 + +// Problem 4a: not a trait object - generic +trait Trait4a { +} + +impl Trait4a for T {} +impl Trait4a for dyn Send {} +//~^ ERROR E0119 + +// Problem 4b: not a trait object - misc +trait Trait4b { +} + +impl Trait4b for () {} +impl Trait4b for () {} +//~^ ERROR E0119 + +// Problem 4c: not a principal-less trait object +trait Trait4c { +} + +impl Trait4c for dyn Trait1 + Send {} +impl Trait4c for dyn Trait1 + Send {} +//~^ ERROR E0119 + +// Problem 4d: lifetimes +trait Trait4d { +} + +impl<'a> Trait4d for dyn Send + 'a {} +impl<'a> Trait4d for dyn Send + 'a {} +//~^ ERROR E0119 + + +// Problem 5: where-clauses +trait Trait5 { +} + +impl Trait5 for dyn Send {} +impl Trait5 for dyn Send where u32: Copy {} +//~^ ERROR E0119 + +fn main() {} diff --git a/src/test/ui/issues/issue-33140-hack-boundaries.stderr b/src/test/ui/issues/issue-33140-hack-boundaries.stderr new file mode 100644 index 0000000000000..95aaa55ba7c67 --- /dev/null +++ b/src/test/ui/issues/issue-33140-hack-boundaries.stderr @@ -0,0 +1,67 @@ +error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`: + --> $DIR/issue-33140-hack-boundaries.rs:19: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[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + 'static)`: + --> $DIR/issue-33140-hack-boundaries.rs:27:1 + | +LL | impl Trait2 for dyn Send {} + | ------------------------ first implementation here +LL | impl !Trait2 for dyn Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` + +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:36:1 + | +LL | impl Trait3 for dyn Send {} + | ---------------------------------- first implementation here +LL | impl Trait3 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:44:1 + | +LL | impl 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:52: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:60: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:68: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:77: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 + +For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.rs b/src/test/ui/issues/issue-33140-traitobject-crate.rs new file mode 100644 index 0000000000000..2b644817df115 --- /dev/null +++ b/src/test/ui/issues/issue-33140-traitobject-crate.rs @@ -0,0 +1,101 @@ +// compile-pass + +#![warn(order_dependent_trait_objects)] + +// Check that traitobject 0.1.0 compiles + +//! # traitobject +//! +//! Unsafe helpers for working with raw TraitObjects. + +/// A trait implemented for all trait objects. +/// +/// Implementations for all traits in std are provided. +pub unsafe trait Trait {} + +unsafe impl Trait for ::std::any::Any + Send { } +unsafe impl Trait for ::std::any::Any + Sync { } +unsafe impl Trait for ::std::any::Any + Send + Sync { } +unsafe impl Trait for ::std::borrow::Borrow + Send { } +unsafe impl Trait for ::std::borrow::Borrow + Sync { } +unsafe impl Trait for ::std::borrow::Borrow + Send + Sync { } +unsafe impl Trait for ::std::borrow::BorrowMut + Send { } +unsafe impl Trait for ::std::borrow::BorrowMut + Sync { } +unsafe impl Trait for ::std::borrow::BorrowMut + Send + Sync { } +unsafe impl Trait for ::std::convert::AsMut + Send { } +unsafe impl Trait for ::std::convert::AsMut + Sync { } +unsafe impl Trait for ::std::convert::AsMut + Send + Sync { } +unsafe impl Trait for ::std::convert::AsRef + Send { } +unsafe impl Trait for ::std::convert::AsRef + Sync { } +unsafe impl Trait for ::std::convert::AsRef + Send + Sync { } +unsafe impl Trait for ::std::error::Error + Send { } +unsafe impl Trait for ::std::error::Error + Sync { } +unsafe impl Trait for ::std::error::Error + Send + Sync { } +unsafe impl Trait for ::std::fmt::Binary + Send { } +unsafe impl Trait for ::std::fmt::Binary + Sync { } +unsafe impl Trait for ::std::fmt::Binary + Send + Sync { } +unsafe impl Trait for ::std::fmt::Debug + Send { } +unsafe impl Trait for ::std::fmt::Debug + Sync { } +unsafe impl Trait for ::std::fmt::Debug + Send + Sync { } +unsafe impl Trait for ::std::fmt::Display + Send { } +unsafe impl Trait for ::std::fmt::Display + Sync { } +unsafe impl Trait for ::std::fmt::Display + Send + Sync { } +unsafe impl Trait for ::std::fmt::LowerExp + Send { } +unsafe impl Trait for ::std::fmt::LowerExp + Sync { } +unsafe impl Trait for ::std::fmt::LowerExp + Send + Sync { } +unsafe impl Trait for ::std::fmt::LowerHex + Send { } +unsafe impl Trait for ::std::fmt::LowerHex + Sync { } +unsafe impl Trait for ::std::fmt::LowerHex + Send + Sync { } +unsafe impl Trait for ::std::fmt::Octal + Send { } +unsafe impl Trait for ::std::fmt::Octal + Sync { } +unsafe impl Trait for ::std::fmt::Octal + Send + Sync { } +unsafe impl Trait for ::std::fmt::Pointer + Send { } +unsafe impl Trait for ::std::fmt::Pointer + Sync { } +unsafe impl Trait for ::std::fmt::Pointer + Send + Sync { } +unsafe impl Trait for ::std::fmt::UpperExp + Send { } +unsafe impl Trait for ::std::fmt::UpperExp + Sync { } +unsafe impl Trait for ::std::fmt::UpperExp + Send + Sync { } +unsafe impl Trait for ::std::fmt::UpperHex + Send { } +unsafe impl Trait for ::std::fmt::UpperHex + Sync { } +unsafe impl Trait for ::std::fmt::UpperHex + Send + Sync { } +unsafe impl Trait for ::std::fmt::Write + Send { } +unsafe impl Trait for ::std::fmt::Write + Sync { } +unsafe impl Trait for ::std::fmt::Write + Send + Sync { } +unsafe impl Trait for ::std::hash::Hasher + Send { } +unsafe impl Trait for ::std::hash::Hasher + Sync { } +unsafe impl Trait for ::std::hash::Hasher + Send + Sync { } +unsafe impl Trait for ::std::io::BufRead + Send { } +unsafe impl Trait for ::std::io::BufRead + Sync { } +unsafe impl Trait for ::std::io::BufRead + Send + Sync { } +unsafe impl Trait for ::std::io::Read + Send { } +unsafe impl Trait for ::std::io::Read + Sync { } +unsafe impl Trait for ::std::io::Read + Send + Sync { } +unsafe impl Trait for ::std::io::Seek + Send { } +unsafe impl Trait for ::std::io::Seek + Sync { } +unsafe impl Trait for ::std::io::Seek + Send + Sync { } +unsafe impl Trait for ::std::io::Write + Send { } +unsafe impl Trait for ::std::io::Write + Sync { } +unsafe impl Trait for ::std::io::Write + Send + Sync { } +unsafe impl Trait for ::std::iter::IntoIterator { } +unsafe impl Trait for ::std::iter::Iterator + Send { } +unsafe impl Trait for ::std::iter::Iterator + Sync { } +unsafe impl Trait for ::std::iter::Iterator + Send + Sync { } +unsafe impl Trait for ::std::marker::Send + Send { } +unsafe impl Trait for ::std::marker::Send + Sync { } +unsafe impl Trait for ::std::marker::Send + Send + Sync { } +unsafe impl Trait for ::std::marker::Sync + Send { } +unsafe impl Trait for ::std::marker::Sync + Sync { } +unsafe impl Trait for ::std::marker::Sync + Send + Sync { } +unsafe impl Trait for ::std::ops::Drop + Send { } +unsafe impl Trait for ::std::ops::Drop + Sync { } +unsafe impl Trait for ::std::ops::Drop + Send + Sync { } +unsafe impl Trait for ::std::string::ToString + Send { } +unsafe impl Trait for ::std::string::ToString + Sync { } +unsafe impl Trait for ::std::string::ToString + Send + Sync { } +fn assert_trait() {} + +fn main() { + assert_trait::(); + assert_trait::(); + assert_trait::(); +} diff --git a/src/test/ui/issues/issue-33140-traitobject-crate.stderr b/src/test/ui/issues/issue-33140-traitobject-crate.stderr new file mode 100644 index 0000000000000..28193b0eeb992 --- /dev/null +++ b/src/test/ui/issues/issue-33140-traitobject-crate.stderr @@ -0,0 +1,39 @@ +warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119) + --> $DIR/issue-33140-traitobject-crate.rs:85:1 + | +LL | unsafe impl Trait for ::std::marker::Send + Sync { } + | ------------------------------------------------ first implementation here +LL | unsafe impl Trait for ::std::marker::Send + Send + Sync { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)` + | +note: lint level 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 + +warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119) + --> $DIR/issue-33140-traitobject-crate.rs:86:1 + | +LL | unsafe impl Trait for ::std::marker::Send + Send + Sync { } + | ------------------------------------------------------- first implementation here +LL | unsafe impl Trait for ::std::marker::Sync + Send { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + '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 + +warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119) + --> $DIR/issue-33140-traitobject-crate.rs:88:1 + | +LL | unsafe impl Trait for ::std::marker::Sync + Send { } + | ------------------------------------------------ first implementation here +LL | unsafe impl Trait for ::std::marker::Sync + Sync { } +LL | unsafe impl Trait for ::std::marker::Sync + Send + Sync { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + '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 + diff --git a/src/test/ui/issues/issue-33140.rs b/src/test/ui/issues/issue-33140.rs index 8d19248d5e0ea..930e24218ac72 100644 --- a/src/test/ui/issues/issue-33140.rs +++ b/src/test/ui/issues/issue-33140.rs @@ -1,5 +1,3 @@ -#![deny(order_dependent_trait_objects)] - trait Trait { fn xyz() -> bool; } @@ -10,7 +8,6 @@ impl Trait for dyn Send + Sync { impl Trait for dyn Sync + Send { //~^ ERROR conflicting implementations -//~| hard error fn xyz() -> bool { true } } @@ -24,14 +21,12 @@ impl Trait2 for dyn Send + Sync { impl Trait2 for dyn Sync + Send + Sync { //~^ ERROR conflicting implementations -//~| hard error fn uvw() -> bool { true } } struct Foo(T); impl Foo { fn abc() -> bool { //~ ERROR duplicate definitions with name `abc` - //~| hard error false } } diff --git a/src/test/ui/issues/issue-33140.stderr b/src/test/ui/issues/issue-33140.stderr index 520921a751239..6e63828f5f7f5 100644 --- a/src/test/ui/issues/issue-33140.stderr +++ b/src/test/ui/issues/issue-33140.stderr @@ -1,37 +1,25 @@ -error: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) - --> $DIR/issue-33140.rs:11:1 +error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: + --> $DIR/issue-33140.rs:9:1 | LL | impl Trait for dyn Send + Sync { | ------------------------------ first implementation here ... LL | impl Trait for dyn Sync + Send { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` - | -note: lint level defined here - --> $DIR/issue-33140.rs:1:9 - | -LL | #![deny(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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)` -error: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) - --> $DIR/issue-33140.rs:25:1 +error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: + --> $DIR/issue-33140.rs:22:1 | LL | impl Trait2 for dyn Send + Sync { | ------------------------------- first implementation here ... LL | impl Trait2 for dyn 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 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)` -error: duplicate definitions with name `abc` (E0592) - --> $DIR/issue-33140.rs:33:5 +error[E0592]: duplicate definitions with name `abc` + --> $DIR/issue-33140.rs:29:5 | LL | / fn abc() -> bool { //~ ERROR duplicate definitions with name `abc` -LL | | //~| hard error LL | | false LL | | } | |_____^ duplicate definitions for `abc` @@ -40,9 +28,8 @@ LL | / fn abc() -> bool { LL | | true LL | | } | |_____- other definition for `abc` - | - = 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 error: aborting due to 3 previous errors +Some errors occurred: E0119, E0592. +For more information about an error, try `rustc --explain E0119`.