Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0b511b7

Browse files
committedJan 3, 2019
implement a hack to make traitobject 0.1.0 compile
1 parent 7eb444e commit 0b511b7

15 files changed

+478
-90
lines changed
 

‎src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ define_dep_nodes!( <'tcx>
492492
[] AdtDefOfItem(DefId),
493493
[] ImplTraitRef(DefId),
494494
[] ImplPolarity(DefId),
495+
[] Issue33140SelfTy(DefId),
495496
[] FnSignature(DefId),
496497
[] CoerceUnsizedInfo(DefId),
497498

‎src/librustc/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
5656
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
5757
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
5858
pub use self::specialize::find_associated_item;
59+
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
60+
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
5961
pub use self::engine::{TraitEngine, TraitEngineExt};
6062
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
6163
pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds,

‎src/librustc/traits/select.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2260,7 +2260,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22602260
ImplCandidate(victim_def) => {
22612261
let tcx = self.tcx().global_tcx();
22622262
return tcx.specializes((other_def, victim_def))
2263-
|| tcx.impls_are_allowed_to_overlap(other_def, victim_def);
2263+
|| tcx.impls_are_allowed_to_overlap(
2264+
other_def, victim_def).is_some();
22642265
}
22652266
ParamCandidate(ref cand) => {
22662267
// Prefer the impl to a global where clause candidate.

‎src/librustc/traits/specialize/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ pub mod specialization_graph;
1414
use hir::def_id::DefId;
1515
use infer::{InferCtxt, InferOk};
1616
use lint;
17-
use traits::coherence;
17+
use traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
1818
use rustc_data_structures::fx::FxHashSet;
1919
use rustc_data_structures::sync::Lrc;
2020
use syntax_pos::DUMMY_SP;
21-
use traits::{self, ObligationCause, TraitEngine};
2221
use traits::select::IntercrateAmbiguityCause;
2322
use ty::{self, TyCtxt, TypeFoldable};
2423
use ty::subst::{Subst, Substs};
@@ -27,6 +26,7 @@ use super::{SelectionContext, FulfillmentContext};
2726
use super::util::impl_trait_ref_and_oblig;
2827

2928
/// Information pertinent to an overlapping impl error.
29+
#[derive(Debug)]
3030
pub struct OverlapError {
3131
pub with_impl: DefId,
3232
pub trait_desc: String,
@@ -310,8 +310,9 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
310310
let insert_result = sg.insert(tcx, impl_def_id);
311311
// Report error if there was one.
312312
let (overlap, used_to_be_allowed) = match insert_result {
313-
Err(overlap) => (Some(overlap), false),
314-
Ok(opt_overlap) => (opt_overlap, true)
313+
Err(overlap) => (Some(overlap), None),
314+
Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)),
315+
Ok(None) => (None, None)
315316
};
316317

317318
if let Some(overlap) = overlap {
@@ -321,14 +322,20 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
321322
String::new(), |ty| {
322323
format!(" for type `{}`", ty)
323324
}),
324-
if used_to_be_allowed { " (E0119)" } else { "" }
325+
if used_to_be_allowed.is_some() { " (E0119)" } else { "" }
325326
);
326327
let impl_span = tcx.sess.source_map().def_span(
327328
tcx.span_of_impl(impl_def_id).unwrap()
328329
);
329-
let mut err = if used_to_be_allowed {
330+
let mut err = if let Some(kind) = used_to_be_allowed {
331+
let lint = match kind {
332+
FutureCompatOverlapErrorKind::Issue43355 =>
333+
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
334+
FutureCompatOverlapErrorKind::Issue33140 =>
335+
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
336+
};
330337
tcx.struct_span_lint_node(
331-
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
338+
lint,
332339
tcx.hir().as_local_node_id(impl_def_id).unwrap(),
333340
impl_span,
334341
&msg)

‎src/librustc/traits/specialize/specialization_graph.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,22 @@ struct Children {
5858
blanket_impls: Vec<DefId>,
5959
}
6060

61+
#[derive(Copy, Clone, Debug)]
62+
pub enum FutureCompatOverlapErrorKind {
63+
Issue43355,
64+
Issue33140,
65+
}
66+
67+
#[derive(Debug)]
68+
pub struct FutureCompatOverlapError {
69+
pub error: OverlapError,
70+
pub kind: FutureCompatOverlapErrorKind
71+
}
72+
6173
/// The result of attempting to insert an impl into a group of children.
6274
enum Inserted {
6375
/// The impl was inserted as a new child in this group of children.
64-
BecameNewSibling(Option<OverlapError>),
76+
BecameNewSibling(Option<FutureCompatOverlapError>),
6577

6678
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
6779
ReplaceChildren(Vec<DefId>),
@@ -162,7 +174,19 @@ impl<'a, 'gcx, 'tcx> Children {
162174
impl_def_id,
163175
traits::IntercrateMode::Issue43355,
164176
|overlap| {
165-
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
177+
if let Some(overlap_kind) =
178+
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
179+
{
180+
match overlap_kind {
181+
ty::ImplOverlapKind::Permitted => {}
182+
ty::ImplOverlapKind::Issue33140 => {
183+
last_lint = Some(FutureCompatOverlapError {
184+
error: overlap_error(overlap),
185+
kind: FutureCompatOverlapErrorKind::Issue33140
186+
});
187+
}
188+
}
189+
166190
return Ok((false, false));
167191
}
168192

@@ -190,13 +214,23 @@ impl<'a, 'gcx, 'tcx> Children {
190214

191215
replace_children.push(possible_sibling);
192216
} else {
193-
if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
217+
if let None = tcx.impls_are_allowed_to_overlap(
218+
impl_def_id, possible_sibling)
219+
{
220+
// do future-compat checks for overlap. Have issue #33140
221+
// errors overwrite issue #43355 errors when both are present.
222+
194223
traits::overlapping_impls(
195224
tcx,
196225
possible_sibling,
197226
impl_def_id,
198227
traits::IntercrateMode::Fixed,
199-
|overlap| last_lint = Some(overlap_error(overlap)),
228+
|overlap| {
229+
last_lint = Some(FutureCompatOverlapError {
230+
error: overlap_error(overlap),
231+
kind: FutureCompatOverlapErrorKind::Issue43355
232+
});
233+
},
200234
|| (),
201235
);
202236
}
@@ -263,7 +297,7 @@ impl<'a, 'gcx, 'tcx> Graph {
263297
pub fn insert(&mut self,
264298
tcx: TyCtxt<'a, 'gcx, 'tcx>,
265299
impl_def_id: DefId)
266-
-> Result<Option<OverlapError>, OverlapError> {
300+
-> Result<Option<FutureCompatOverlapError>, OverlapError> {
267301
assert!(impl_def_id.is_local());
268302

269303
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();

‎src/librustc/ty/mod.rs

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,6 +2637,45 @@ impl<'gcx> ::std::ops::Deref for Attributes<'gcx> {
26372637
}
26382638
}
26392639

2640+
#[derive(Debug, PartialEq, Eq)]
2641+
pub enum ImplOverlapKind {
2642+
/// These impls are always allowed to overlap.
2643+
Permitted,
2644+
/// These impls are allowed to overlap, but that raises
2645+
/// an issue #33140 future-compatibility warning.
2646+
///
2647+
/// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
2648+
/// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
2649+
///
2650+
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
2651+
/// that difference, making what reduces to the following set of impls:
2652+
///
2653+
/// ```
2654+
/// trait Trait {}
2655+
/// impl Trait for dyn Send + Sync {}
2656+
/// impl Trait for dyn Sync + Send {}
2657+
/// ```
2658+
///
2659+
/// Obviously, once we made these types be identical, that code causes a coherence
2660+
/// error and a fairly big headache for us. However, luckily for us, the trait
2661+
/// `Trait` used in this case is basically a marker trait, and therefore having
2662+
/// overlapping impls for it is sound.
2663+
///
2664+
/// To handle this, we basically regard the trait as a marker trait, with an additional
2665+
/// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
2666+
/// it has the following restrictions:
2667+
///
2668+
/// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
2669+
/// positive impls.
2670+
/// 2. The trait-ref of both impls must be equal.
2671+
/// 3. The trait-ref of both impls must be a trait object type consisting only of
2672+
/// marker traits.
2673+
/// 4. Neither of the impls can have any where-clauses.
2674+
///
2675+
/// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
2676+
Issue33140
2677+
}
2678+
26402679
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
26412680
pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> {
26422681
self.typeck_tables_of(self.hir().body_owner_def_id(body))
@@ -2788,8 +2827,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
27882827

27892828
/// Returns `true` if the impls are the same polarity and the trait either
27902829
/// has no items or is annotated #[marker] and prevents item overrides.
2791-
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
2792-
if self.features().overlapping_marker_traits {
2830+
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId)
2831+
-> Option<ImplOverlapKind>
2832+
{
2833+
let is_legit = if self.features().overlapping_marker_traits {
27932834
let trait1_is_empty = self.impl_trait_ref(def_id1)
27942835
.map_or(false, |trait_ref| {
27952836
self.associated_item_def_ids(trait_ref.def_id).is_empty()
@@ -2811,6 +2852,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28112852
&& is_marker_impl(def_id2)
28122853
} else {
28132854
false
2855+
};
2856+
2857+
if is_legit {
2858+
debug!("impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted)",
2859+
def_id1, def_id2);
2860+
Some(ImplOverlapKind::Permitted)
2861+
} else {
2862+
if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
2863+
if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
2864+
if self_ty1 == self_ty2 {
2865+
debug!("impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
2866+
def_id1, def_id2);
2867+
return Some(ImplOverlapKind::Issue33140);
2868+
} else {
2869+
debug!("impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
2870+
def_id1, def_id2, self_ty1, self_ty2);
2871+
}
2872+
}
2873+
}
2874+
2875+
debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None",
2876+
def_id1, def_id2);
2877+
None
28142878
}
28152879
}
28162880

@@ -3203,6 +3267,59 @@ fn instance_def_size_estimate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
32033267
}
32043268
}
32053269

3270+
/// If `def_id` is an issue 33140 hack impl, return its self type. Otherwise
3271+
/// return None.
3272+
///
3273+
/// See ImplOverlapKind::Issue33140 for more details.
3274+
fn issue33140_self_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
3275+
def_id: DefId)
3276+
-> Option<Ty<'tcx>>
3277+
{
3278+
debug!("issue33140_self_ty({:?})", def_id);
3279+
3280+
let trait_ref = tcx.impl_trait_ref(def_id).unwrap_or_else(|| {
3281+
bug!("issue33140_self_ty called on inherent impl {:?}", def_id)
3282+
});
3283+
3284+
debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref);
3285+
3286+
let is_marker_like =
3287+
tcx.impl_polarity(def_id) == hir::ImplPolarity::Positive &&
3288+
tcx.associated_item_def_ids(trait_ref.def_id).is_empty();
3289+
3290+
// Check whether these impls would be ok for a marker trait.
3291+
if !is_marker_like {
3292+
debug!("issue33140_self_ty - not marker-like!");
3293+
return None;
3294+
}
3295+
3296+
// impl must be `impl Trait for dyn Marker1 + Marker2 + ...`
3297+
if trait_ref.substs.len() != 1 {
3298+
debug!("issue33140_self_ty - impl has substs!");
3299+
return None;
3300+
}
3301+
3302+
let predicates = tcx.predicates_of(def_id);
3303+
if predicates.parent.is_some() || !predicates.predicates.is_empty() {
3304+
debug!("issue33140_self_ty - impl has predicates {:?}!", predicates);
3305+
return None;
3306+
}
3307+
3308+
let self_ty = trait_ref.self_ty();
3309+
let self_ty_matches = match self_ty.sty {
3310+
ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(),
3311+
_ => false
3312+
};
3313+
3314+
if self_ty_matches {
3315+
debug!("issue33140_self_ty - MATCHES!");
3316+
Some(self_ty)
3317+
} else {
3318+
debug!("issue33140_self_ty - non-matching self type");
3319+
None
3320+
}
3321+
}
3322+
32063323
pub fn provide(providers: &mut ty::query::Providers<'_>) {
32073324
context::provide(providers);
32083325
erase_regions::provide(providers);
@@ -3221,6 +3338,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
32213338
crate_hash,
32223339
trait_impls_of: trait_def::trait_impls_of_provider,
32233340
instance_def_size_estimate,
3341+
issue33140_self_ty,
32243342
..*providers
32253343
};
32263344
}

‎src/librustc/ty/query/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ define_queries! { <'tcx>
202202

203203
[] fn impl_trait_ref: ImplTraitRef(DefId) -> Option<ty::TraitRef<'tcx>>,
204204
[] fn impl_polarity: ImplPolarity(DefId) -> hir::ImplPolarity,
205+
206+
[] fn issue33140_self_ty: Issue33140SelfTy(DefId) -> Option<ty::Ty<'tcx>>,
205207
},
206208

207209
TypeChecking {

‎src/librustc/ty/query/plumbing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
12751275
DepKind::AdtDefOfItem => { force!(adt_def, def_id!()); }
12761276
DepKind::ImplTraitRef => { force!(impl_trait_ref, def_id!()); }
12771277
DepKind::ImplPolarity => { force!(impl_polarity, def_id!()); }
1278+
DepKind::Issue33140SelfTy => { force!(issue33140_self_ty, def_id!()); }
12781279
DepKind::FnSignature => { force!(fn_sig, def_id!()); }
12791280
DepKind::CoerceUnsizedInfo => { force!(coerce_unsized_info, def_id!()); }
12801281
DepKind::ItemVariances => { force!(variances_of, def_id!()); }

‎src/test/run-pass/issues/issue-33140.rs

Lines changed: 0 additions & 47 deletions
This file was deleted.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#![feature(optin_builtin_traits)]
2+
#![allow(order_dependent_trait_objects)]
3+
4+
// Check that the issue #33140 hack does not allow unintended things.
5+
6+
// OK
7+
trait Trait0 {
8+
}
9+
10+
impl Trait0 for dyn Send {}
11+
impl Trait0 for dyn Send {}
12+
13+
// Problem 1: associated types
14+
trait Trait1 {
15+
fn my_fn(&self) {}
16+
}
17+
18+
impl Trait1 for dyn Send {}
19+
impl Trait1 for dyn Send {}
20+
//~^ ERROR E0119
21+
22+
// Problem 2: negative impl
23+
trait Trait2 {
24+
}
25+
26+
impl Trait2 for dyn Send {}
27+
impl !Trait2 for dyn Send {}
28+
//~^ ERROR E0119
29+
30+
31+
// Problem 3: type parameter
32+
trait Trait3<T: ?Sized> {
33+
}
34+
35+
impl Trait3<dyn Sync> for dyn Send {}
36+
impl Trait3<dyn Sync> for dyn Send {}
37+
//~^ ERROR E0119
38+
39+
// Problem 4a: not a trait object - generic
40+
trait Trait4a {
41+
}
42+
43+
impl<T: ?Sized> Trait4a for T {}
44+
impl Trait4a for dyn Send {}
45+
//~^ ERROR E0119
46+
47+
// Problem 4b: not a trait object - misc
48+
trait Trait4b {
49+
}
50+
51+
impl Trait4b for () {}
52+
impl Trait4b for () {}
53+
//~^ ERROR E0119
54+
55+
// Problem 4c: not a principal-less trait object
56+
trait Trait4c {
57+
}
58+
59+
impl Trait4c for dyn Trait1 + Send {}
60+
impl Trait4c for dyn Trait1 + Send {}
61+
//~^ ERROR E0119
62+
63+
// Problem 4d: lifetimes
64+
trait Trait4d {
65+
}
66+
67+
impl<'a> Trait4d for dyn Send + 'a {}
68+
impl<'a> Trait4d for dyn Send + 'a {}
69+
//~^ ERROR E0119
70+
71+
72+
// Problem 5: where-clauses
73+
trait Trait5 {
74+
}
75+
76+
impl Trait5 for dyn Send {}
77+
impl Trait5 for dyn Send where u32: Copy {}
78+
//~^ ERROR E0119
79+
80+
fn main() {}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`:
2+
--> $DIR/issue-33140-hack-boundaries.rs:19:1
3+
|
4+
LL | impl Trait1 for dyn Send {}
5+
| ------------------------ first implementation here
6+
LL | impl Trait1 for dyn Send {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
8+
9+
error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
10+
--> $DIR/issue-33140-hack-boundaries.rs:27:1
11+
|
12+
LL | impl Trait2 for dyn Send {}
13+
| ------------------------ first implementation here
14+
LL | impl !Trait2 for dyn Send {}
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
16+
17+
error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`:
18+
--> $DIR/issue-33140-hack-boundaries.rs:36:1
19+
|
20+
LL | impl Trait3<dyn Sync> for dyn Send {}
21+
| ---------------------------------- first implementation here
22+
LL | impl Trait3<dyn Sync> for dyn Send {}
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
24+
25+
error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`:
26+
--> $DIR/issue-33140-hack-boundaries.rs:44:1
27+
|
28+
LL | impl<T: ?Sized> Trait4a for T {}
29+
| ----------------------------- first implementation here
30+
LL | impl Trait4a for dyn Send {}
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
32+
33+
error[E0119]: conflicting implementations of trait `Trait4b` for type `()`:
34+
--> $DIR/issue-33140-hack-boundaries.rs:52:1
35+
|
36+
LL | impl Trait4b for () {}
37+
| ------------------- first implementation here
38+
LL | impl Trait4b for () {}
39+
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
40+
41+
error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`:
42+
--> $DIR/issue-33140-hack-boundaries.rs:60:1
43+
|
44+
LL | impl Trait4c for dyn Trait1 + Send {}
45+
| ---------------------------------- first implementation here
46+
LL | impl Trait4c for dyn Trait1 + Send {}
47+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`
48+
49+
error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`:
50+
--> $DIR/issue-33140-hack-boundaries.rs:68:1
51+
|
52+
LL | impl<'a> Trait4d for dyn Send + 'a {}
53+
| ---------------------------------- first implementation here
54+
LL | impl<'a> Trait4d for dyn Send + 'a {}
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`
56+
57+
error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`:
58+
--> $DIR/issue-33140-hack-boundaries.rs:77:1
59+
|
60+
LL | impl Trait5 for dyn Send {}
61+
| ------------------------ first implementation here
62+
LL | impl Trait5 for dyn Send where u32: Copy {}
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
64+
65+
error: aborting due to 8 previous errors
66+
67+
For more information about this error, try `rustc --explain E0119`.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// compile-pass
2+
3+
#![warn(order_dependent_trait_objects)]
4+
5+
// Check that traitobject 0.1.0 compiles
6+
7+
//! # traitobject
8+
//!
9+
//! Unsafe helpers for working with raw TraitObjects.
10+
11+
/// A trait implemented for all trait objects.
12+
///
13+
/// Implementations for all traits in std are provided.
14+
pub unsafe trait Trait {}
15+
16+
unsafe impl Trait for ::std::any::Any + Send { }
17+
unsafe impl Trait for ::std::any::Any + Sync { }
18+
unsafe impl Trait for ::std::any::Any + Send + Sync { }
19+
unsafe impl<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Send { }
20+
unsafe impl<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Sync { }
21+
unsafe impl<T: ?Sized> Trait for ::std::borrow::Borrow<T> + Send + Sync { }
22+
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Send { }
23+
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Sync { }
24+
unsafe impl<T: ?Sized> Trait for ::std::borrow::BorrowMut<T> + Send + Sync { }
25+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Send { }
26+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Sync { }
27+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsMut<T> + Send + Sync { }
28+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + Send { }
29+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + Sync { }
30+
unsafe impl<T: ?Sized> Trait for ::std::convert::AsRef<T> + Send + Sync { }
31+
unsafe impl Trait for ::std::error::Error + Send { }
32+
unsafe impl Trait for ::std::error::Error + Sync { }
33+
unsafe impl Trait for ::std::error::Error + Send + Sync { }
34+
unsafe impl Trait for ::std::fmt::Binary + Send { }
35+
unsafe impl Trait for ::std::fmt::Binary + Sync { }
36+
unsafe impl Trait for ::std::fmt::Binary + Send + Sync { }
37+
unsafe impl Trait for ::std::fmt::Debug + Send { }
38+
unsafe impl Trait for ::std::fmt::Debug + Sync { }
39+
unsafe impl Trait for ::std::fmt::Debug + Send + Sync { }
40+
unsafe impl Trait for ::std::fmt::Display + Send { }
41+
unsafe impl Trait for ::std::fmt::Display + Sync { }
42+
unsafe impl Trait for ::std::fmt::Display + Send + Sync { }
43+
unsafe impl Trait for ::std::fmt::LowerExp + Send { }
44+
unsafe impl Trait for ::std::fmt::LowerExp + Sync { }
45+
unsafe impl Trait for ::std::fmt::LowerExp + Send + Sync { }
46+
unsafe impl Trait for ::std::fmt::LowerHex + Send { }
47+
unsafe impl Trait for ::std::fmt::LowerHex + Sync { }
48+
unsafe impl Trait for ::std::fmt::LowerHex + Send + Sync { }
49+
unsafe impl Trait for ::std::fmt::Octal + Send { }
50+
unsafe impl Trait for ::std::fmt::Octal + Sync { }
51+
unsafe impl Trait for ::std::fmt::Octal + Send + Sync { }
52+
unsafe impl Trait for ::std::fmt::Pointer + Send { }
53+
unsafe impl Trait for ::std::fmt::Pointer + Sync { }
54+
unsafe impl Trait for ::std::fmt::Pointer + Send + Sync { }
55+
unsafe impl Trait for ::std::fmt::UpperExp + Send { }
56+
unsafe impl Trait for ::std::fmt::UpperExp + Sync { }
57+
unsafe impl Trait for ::std::fmt::UpperExp + Send + Sync { }
58+
unsafe impl Trait for ::std::fmt::UpperHex + Send { }
59+
unsafe impl Trait for ::std::fmt::UpperHex + Sync { }
60+
unsafe impl Trait for ::std::fmt::UpperHex + Send + Sync { }
61+
unsafe impl Trait for ::std::fmt::Write + Send { }
62+
unsafe impl Trait for ::std::fmt::Write + Sync { }
63+
unsafe impl Trait for ::std::fmt::Write + Send + Sync { }
64+
unsafe impl Trait for ::std::hash::Hasher + Send { }
65+
unsafe impl Trait for ::std::hash::Hasher + Sync { }
66+
unsafe impl Trait for ::std::hash::Hasher + Send + Sync { }
67+
unsafe impl Trait for ::std::io::BufRead + Send { }
68+
unsafe impl Trait for ::std::io::BufRead + Sync { }
69+
unsafe impl Trait for ::std::io::BufRead + Send + Sync { }
70+
unsafe impl Trait for ::std::io::Read + Send { }
71+
unsafe impl Trait for ::std::io::Read + Sync { }
72+
unsafe impl Trait for ::std::io::Read + Send + Sync { }
73+
unsafe impl Trait for ::std::io::Seek + Send { }
74+
unsafe impl Trait for ::std::io::Seek + Sync { }
75+
unsafe impl Trait for ::std::io::Seek + Send + Sync { }
76+
unsafe impl Trait for ::std::io::Write + Send { }
77+
unsafe impl Trait for ::std::io::Write + Sync { }
78+
unsafe impl Trait for ::std::io::Write + Send + Sync { }
79+
unsafe impl<T, I> Trait for ::std::iter::IntoIterator<IntoIter=I, Item=T> { }
80+
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + Send { }
81+
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + Sync { }
82+
unsafe impl<T> Trait for ::std::iter::Iterator<Item=T> + Send + Sync { }
83+
unsafe impl Trait for ::std::marker::Send + Send { }
84+
unsafe impl Trait for ::std::marker::Send + Sync { }
85+
unsafe impl Trait for ::std::marker::Send + Send + Sync { }
86+
unsafe impl Trait for ::std::marker::Sync + Send { }
87+
unsafe impl Trait for ::std::marker::Sync + Sync { }
88+
unsafe impl Trait for ::std::marker::Sync + Send + Sync { }
89+
unsafe impl Trait for ::std::ops::Drop + Send { }
90+
unsafe impl Trait for ::std::ops::Drop + Sync { }
91+
unsafe impl Trait for ::std::ops::Drop + Send + Sync { }
92+
unsafe impl Trait for ::std::string::ToString + Send { }
93+
unsafe impl Trait for ::std::string::ToString + Sync { }
94+
unsafe impl Trait for ::std::string::ToString + Send + Sync { }
95+
fn assert_trait<T: Trait + ?Sized>() {}
96+
97+
fn main() {
98+
assert_trait::<dyn Send>();
99+
assert_trait::<dyn Sync>();
100+
assert_trait::<dyn Send + Sync>();
101+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119)
2+
--> $DIR/issue-33140-traitobject-crate.rs:85:1
3+
|
4+
LL | unsafe impl Trait for ::std::marker::Send + Sync { }
5+
| ------------------------------------------------ first implementation here
6+
LL | unsafe impl Trait for ::std::marker::Send + Send + Sync { }
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)`
8+
|
9+
note: lint level defined here
10+
--> $DIR/issue-33140-traitobject-crate.rs:3:9
11+
|
12+
LL | #![warn(order_dependent_trait_objects)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
15+
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
16+
17+
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119)
18+
--> $DIR/issue-33140-traitobject-crate.rs:86:1
19+
|
20+
LL | unsafe impl Trait for ::std::marker::Send + Send + Sync { }
21+
| ------------------------------------------------------- first implementation here
22+
LL | unsafe impl Trait for ::std::marker::Sync + Send { }
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)`
24+
|
25+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
26+
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
27+
28+
warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119)
29+
--> $DIR/issue-33140-traitobject-crate.rs:88:1
30+
|
31+
LL | unsafe impl Trait for ::std::marker::Sync + Send { }
32+
| ------------------------------------------------ first implementation here
33+
LL | unsafe impl Trait for ::std::marker::Sync + Sync { }
34+
LL | unsafe impl Trait for ::std::marker::Sync + Send + Sync { }
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)`
36+
|
37+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
38+
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
39+

‎src/test/ui/issues/issue-33140.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#![deny(order_dependent_trait_objects)]
2-
31
trait Trait {
42
fn xyz() -> bool;
53
}
@@ -10,7 +8,6 @@ impl Trait for dyn Send + Sync {
108

119
impl Trait for dyn Sync + Send {
1210
//~^ ERROR conflicting implementations
13-
//~| hard error
1411
fn xyz() -> bool { true }
1512
}
1613

@@ -24,14 +21,12 @@ impl Trait2 for dyn Send + Sync {
2421

2522
impl Trait2 for dyn Sync + Send + Sync {
2623
//~^ ERROR conflicting implementations
27-
//~| hard error
2824
fn uvw() -> bool { true }
2925
}
3026

3127
struct Foo<T: ?Sized>(T);
3228
impl Foo<dyn Send + Sync> {
3329
fn abc() -> bool { //~ ERROR duplicate definitions with name `abc`
34-
//~| hard error
3530
false
3631
}
3732
}

‎src/test/ui/issues/issue-33140.stderr

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,25 @@
1-
error: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
2-
--> $DIR/issue-33140.rs:11:1
1+
error[E0119]: conflicting implementations of trait `Trait` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`:
2+
--> $DIR/issue-33140.rs:9:1
33
|
44
LL | impl Trait for dyn Send + Sync {
55
| ------------------------------ first implementation here
66
...
77
LL | impl Trait for dyn Sync + Send {
8-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
9-
|
10-
note: lint level defined here
11-
--> $DIR/issue-33140.rs:1:9
12-
|
13-
LL | #![deny(order_dependent_trait_objects)]
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
16-
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)`
179

18-
error: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119)
19-
--> $DIR/issue-33140.rs:25:1
10+
error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`:
11+
--> $DIR/issue-33140.rs:22:1
2012
|
2113
LL | impl Trait2 for dyn Send + Sync {
2214
| ------------------------------- first implementation here
2315
...
2416
LL | impl Trait2 for dyn Sync + Send + Sync {
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)`
26-
|
27-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
28-
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)`
2918

30-
error: duplicate definitions with name `abc` (E0592)
31-
--> $DIR/issue-33140.rs:33:5
19+
error[E0592]: duplicate definitions with name `abc`
20+
--> $DIR/issue-33140.rs:29:5
3221
|
3322
LL | / fn abc() -> bool { //~ ERROR duplicate definitions with name `abc`
34-
LL | | //~| hard error
3523
LL | | false
3624
LL | | }
3725
| |_____^ duplicate definitions for `abc`
@@ -40,9 +28,8 @@ LL | / fn abc() -> bool {
4028
LL | | true
4129
LL | | }
4230
| |_____- other definition for `abc`
43-
|
44-
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
45-
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
4631

4732
error: aborting due to 3 previous errors
4833

34+
Some errors occurred: E0119, E0592.
35+
For more information about an error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)
Please sign in to comment.