提交 0b511b7b 编写于 作者: A Ariel Ben-Yehuda

implement a hack to make traitobject 0.1.0 compile

上级 7eb444e4
......@@ -492,6 +492,7 @@ pub fn to_dep_node(self, tcx: TyCtxt<'_, '_, '_>, kind: DepKind) -> DepNode {
[] AdtDefOfItem(DefId),
[] ImplTraitRef(DefId),
[] ImplPolarity(DefId),
[] Issue33140SelfTy(DefId),
[] FnSignature(DefId),
[] CoerceUnsizedInfo(DefId),
......
......@@ -56,6 +56,8 @@
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,
......
......@@ -2260,7 +2260,8 @@ fn candidate_should_be_dropped_in_favor_of<'o>(
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.
......
......@@ -14,11 +14,10 @@
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::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)
......
......@@ -58,10 +58,22 @@ struct Children {
blanket_impls: Vec<DefId>,
}
#[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<OverlapError>),
BecameNewSibling(Option<FutureCompatOverlapError>),
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
ReplaceChildren(Vec<DefId>),
......@@ -162,7 +174,19 @@ fn insert(&mut self,
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 @@ fn insert(&mut self,
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 @@ pub fn new() -> Graph {
pub fn insert(&mut self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
impl_def_id: DefId)
-> Result<Option<OverlapError>, OverlapError> {
-> Result<Option<FutureCompatOverlapError>, OverlapError> {
assert!(impl_def_id.is_local());
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
......
......@@ -2637,6 +2637,45 @@ fn deref(&self) -> &[ast::Attribute] {
}
}
#[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 @@ pub fn associated_items(
/// 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<ImplOverlapKind>
{
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 @@ pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> boo
&& 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<Ty<'tcx>>
{
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
};
}
......
......@@ -202,6 +202,8 @@
[] fn impl_trait_ref: ImplTraitRef(DefId) -> Option<ty::TraitRef<'tcx>>,
[] fn impl_polarity: ImplPolarity(DefId) -> hir::ImplPolarity,
[] fn issue33140_self_ty: Issue33140SelfTy(DefId) -> Option<ty::Ty<'tcx>>,
},
TypeChecking {
......
......@@ -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!()); }
......
#![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: ?Sized>(T);
impl Foo<dyn Send + Sync> {
fn abc() -> bool {
false
}
}
impl Foo<dyn Sync + Send> {
fn abc() -> bool {
true
}
}
fn main() {
assert_eq!(<dyn Send+Sync>::xyz(), false);
assert_eq!(<dyn Sync+Send>::xyz(), true);
assert_eq!(<dyn Send+Sync>::uvw(), false);
assert_eq!(<dyn Sync+Send+Sync>::uvw(), true);
assert_eq!(<Foo<dyn Send+Sync>>::abc(), false);
assert_eq!(<Foo<dyn Sync+Send>>::abc(), true);
}
#![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<T: ?Sized> {
}
impl Trait3<dyn Sync> for dyn Send {}
impl Trait3<dyn Sync> for dyn Send {}
//~^ ERROR E0119
// Problem 4a: not a trait object - generic
trait Trait4a {
}
impl<T: ?Sized> 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() {}
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<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:44: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: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`.
// 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<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Send { }
unsafe impl<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Send + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Send { }
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Send + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Send { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Send + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + Send { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + Sync { }
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + 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<T, I> Trait for ::std::iter::IntoIterator<IntoIter=I, Item=T> { }
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + Send { }
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + Sync { }
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + 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<T: Trait + ?Sized>() {}
fn main() {
assert_trait::<dyn Send>();
assert_trait::<dyn Sync>();
assert_trait::<dyn Send + Sync>();
}
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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/56484>
#![deny(order_dependent_trait_objects)]
trait Trait {
fn xyz() -> bool;
}
......@@ -10,7 +8,6 @@ fn xyz() -> bool { false }
impl Trait for dyn Sync + Send {
//~^ ERROR conflicting implementations
//~| hard error
fn xyz() -> bool { true }
}
......@@ -24,14 +21,12 @@ fn uvw() -> bool { false }
impl Trait2 for dyn Sync + Send + Sync {
//~^ ERROR conflicting implementations
//~| hard error
fn uvw() -> bool { true }
}
struct Foo<T: ?Sized>(T);
impl Foo<dyn Send + Sync> {
fn abc() -> bool { //~ ERROR duplicate definitions with name `abc`
//~| hard error
false
}
}
......
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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/56484>
error: aborting due to 3 previous errors
Some errors occurred: E0119, E0592.
For more information about an error, try `rustc --explain E0119`.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册