Skip to content

Commit 96ae278

Browse files
committed
make incoherent_auto_trait_objects a hard error
1 parent 8a497b7 commit 96ae278

File tree

14 files changed

+73
-318
lines changed

14 files changed

+73
-318
lines changed

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,41 +1426,6 @@ declare_lint! {
14261426
};
14271427
}
14281428

1429-
declare_lint! {
1430-
/// The `order_dependent_trait_objects` lint detects a trait coherency
1431-
/// violation that would allow creating two trait impls for the same
1432-
/// dynamic trait object involving marker traits.
1433-
///
1434-
/// ### Example
1435-
///
1436-
/// ```rust,compile_fail
1437-
/// pub trait Trait {}
1438-
///
1439-
/// impl Trait for dyn Send + Sync { }
1440-
/// impl Trait for dyn Sync + Send { }
1441-
/// ```
1442-
///
1443-
/// {{produces}}
1444-
///
1445-
/// ### Explanation
1446-
///
1447-
/// A previous bug caused the compiler to interpret traits with different
1448-
/// orders (such as `Send + Sync` and `Sync + Send`) as distinct types
1449-
/// when they were intended to be treated the same. This allowed code to
1450-
/// define separate trait implementations when there should be a coherence
1451-
/// error. This is a [future-incompatible] lint to transition this to a
1452-
/// hard error in the future. See [issue #56484] for more details.
1453-
///
1454-
/// [issue #56484]: https://github.com/rust-lang/rust/issues/56484
1455-
/// [future-incompatible]: ../index.md#future-incompatible-lints
1456-
pub ORDER_DEPENDENT_TRAIT_OBJECTS,
1457-
Deny,
1458-
"trait-object types were treated as different depending on marker-trait order",
1459-
@future_incompatible = FutureIncompatibleInfo {
1460-
reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>",
1461-
};
1462-
}
1463-
14641429
declare_lint! {
14651430
/// The `coherence_leak_check` lint detects conflicting implementations of
14661431
/// a trait that are only distinguished by the old leak-check code.
@@ -3302,7 +3267,6 @@ declare_lint_pass! {
33023267
PATTERNS_IN_FNS_WITHOUT_BODY,
33033268
MISSING_FRAGMENT_SPECIFIER,
33043269
LATE_BOUND_LIFETIME_ARGUMENTS,
3305-
ORDER_DEPENDENT_TRAIT_OBJECTS,
33063270
COHERENCE_LEAK_CHECK,
33073271
DEPRECATED,
33083272
UNUSED_UNSAFE,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,6 @@ rustc_queries! {
722722
separate_provide_extern
723723
}
724724

725-
query issue33140_self_ty(key: DefId) -> Option<ty::Ty<'tcx>> {
726-
desc { |tcx| "computing Self type wrt issue #33140 `{}`", tcx.def_path_str(key) }
727-
}
728-
729725
/// Maps a `DefId` of a type to a list of its inherent impls.
730726
/// Contains implementations of methods that are inherent to a type.
731727
/// Methods in these implementations don't need to be exported.

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,45 +2109,9 @@ impl<'tcx> FieldDef {
21092109

21102110
pub type Attributes<'tcx> = impl Iterator<Item = &'tcx ast::Attribute>;
21112111
#[derive(Debug, PartialEq, Eq)]
2112-
pub enum ImplOverlapKind {
2113-
/// These impls are always allowed to overlap.
2114-
Permitted {
2115-
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
2116-
marker: bool,
2117-
},
2118-
/// These impls are allowed to overlap, but that raises
2119-
/// an issue #33140 future-compatibility warning.
2120-
///
2121-
/// Some background: in Rust 1.0, the trait-object types `Send + Sync` (today's
2122-
/// `dyn Send + Sync`) and `Sync + Send` (now `dyn Sync + Send`) were different.
2123-
///
2124-
/// The widely-used version 0.1.0 of the crate `traitobject` had accidentally relied
2125-
/// that difference, making what reduces to the following set of impls:
2126-
///
2127-
/// ```compile_fail,(E0119)
2128-
/// trait Trait {}
2129-
/// impl Trait for dyn Send + Sync {}
2130-
/// impl Trait for dyn Sync + Send {}
2131-
/// ```
2132-
///
2133-
/// Obviously, once we made these types be identical, that code causes a coherence
2134-
/// error and a fairly big headache for us. However, luckily for us, the trait
2135-
/// `Trait` used in this case is basically a marker trait, and therefore having
2136-
/// overlapping impls for it is sound.
2137-
///
2138-
/// To handle this, we basically regard the trait as a marker trait, with an additional
2139-
/// future-compatibility warning. To avoid accidentally "stabilizing" this feature,
2140-
/// it has the following restrictions:
2141-
///
2142-
/// 1. The trait must indeed be a marker-like trait (i.e., no items), and must be
2143-
/// positive impls.
2144-
/// 2. The trait-ref of both impls must be equal.
2145-
/// 3. The trait-ref of both impls must be a trait object type consisting only of
2146-
/// marker traits.
2147-
/// 4. Neither of the impls can have any where-clauses.
2148-
///
2149-
/// Once `traitobject` 0.1.0 is no longer an active concern, this hack can be removed.
2150-
Issue33140,
2112+
pub struct PermittedImplOverlap {
2113+
/// Whether or not the impl is permitted due to the trait being a `#[marker]` trait
2114+
pub marker: bool,
21512115
}
21522116

21532117
impl<'tcx> TyCtxt<'tcx> {
@@ -2229,13 +2193,13 @@ impl<'tcx> TyCtxt<'tcx> {
22292193
self,
22302194
def_id1: DefId,
22312195
def_id2: DefId,
2232-
) -> Option<ImplOverlapKind> {
2196+
) -> Option<PermittedImplOverlap> {
22332197
// If either trait impl references an error, they're allowed to overlap,
22342198
// as one of them essentially doesn't exist.
22352199
if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error())
22362200
|| self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error())
22372201
{
2238-
return Some(ImplOverlapKind::Permitted { marker: false });
2202+
return Some(PermittedImplOverlap { marker: false });
22392203
}
22402204

22412205
match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) {
@@ -2245,7 +2209,7 @@ impl<'tcx> TyCtxt<'tcx> {
22452209
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)",
22462210
def_id1, def_id2
22472211
);
2248-
return Some(ImplOverlapKind::Permitted { marker: false });
2212+
return Some(PermittedImplOverlap { marker: false });
22492213
}
22502214
(ImplPolarity::Positive, ImplPolarity::Negative)
22512215
| (ImplPolarity::Negative, ImplPolarity::Positive) => {
@@ -2273,25 +2237,8 @@ impl<'tcx> TyCtxt<'tcx> {
22732237
"impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)",
22742238
def_id1, def_id2
22752239
);
2276-
Some(ImplOverlapKind::Permitted { marker: true })
2240+
Some(PermittedImplOverlap { marker: true })
22772241
} else {
2278-
if let Some(self_ty1) = self.issue33140_self_ty(def_id1) {
2279-
if let Some(self_ty2) = self.issue33140_self_ty(def_id2) {
2280-
if self_ty1 == self_ty2 {
2281-
debug!(
2282-
"impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK",
2283-
def_id1, def_id2
2284-
);
2285-
return Some(ImplOverlapKind::Issue33140);
2286-
} else {
2287-
debug!(
2288-
"impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}",
2289-
def_id1, def_id2, self_ty1, self_ty2
2290-
);
2291-
}
2292-
}
2293-
}
2294-
22952242
debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2);
22962243
None
22972244
}

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ pub use self::project::{normalize, normalize_projection_type, normalize_to};
6363
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
6464
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
6565
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
66-
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
6766
pub use self::specialize::{specialization_graph, translate_substs, OverlapError};
6867
pub use self::structural_match::{
6968
search_for_adt_const_param_violation, search_for_structural_match_violation,

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1752,7 +1752,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17521752

17531753
if other.evaluation.must_apply_considering_regions() {
17541754
match tcx.impls_are_allowed_to_overlap(other_def, victim_def) {
1755-
Some(ty::ImplOverlapKind::Permitted { marker: true }) => {
1755+
Some(ty::PermittedImplOverlap { marker: true }) => {
17561756
// Subtle: If the predicate we are evaluating has inference
17571757
// variables, do *not* allow discarding candidates due to
17581758
// marker trait impls.

compiler/rustc_trait_selection/src/traits/specialize/mod.rs

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@ use specialization_graph::GraphExt;
1515
use crate::errors::NegativePositiveConflict;
1616
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
1717
use crate::traits::select::IntercrateAmbiguityCause;
18-
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
18+
use crate::traits::{self, coherence, ObligationCause};
1919
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
2020
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
2121
use rustc_hir::def_id::{DefId, LocalDefId};
2222
use rustc_middle::ty::{self, ImplSubject, TyCtxt};
2323
use rustc_middle::ty::{InternalSubsts, SubstsRef};
2424
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
25-
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
2625
use rustc_span::{Span, DUMMY_SP};
2726

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

268267
if let Some(overlap) = overlap {
@@ -286,7 +285,7 @@ fn report_overlap_conflict(
286285
tcx: TyCtxt<'_>,
287286
overlap: OverlapError,
288287
impl_def_id: LocalDefId,
289-
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
288+
used_to_be_allowed: bool,
290289
sg: &mut specialization_graph::Graph,
291290
) {
292291
let impl_polarity = tcx.impl_polarity(impl_def_id.to_def_id());
@@ -342,7 +341,7 @@ fn report_conflicting_impls(
342341
tcx: TyCtxt<'_>,
343342
overlap: OverlapError,
344343
impl_def_id: LocalDefId,
345-
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
344+
used_to_be_allowed: bool,
346345
sg: &mut specialization_graph::Graph,
347346
) {
348347
let impl_span = tcx.def_span(impl_def_id);
@@ -353,21 +352,16 @@ fn report_conflicting_impls(
353352
fn decorate<G: EmissionGuarantee>(
354353
tcx: TyCtxt<'_>,
355354
overlap: OverlapError,
356-
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
357355
impl_span: Span,
358356
err: LintDiagnosticBuilder<'_, G>,
359357
) -> G {
360358
let msg = format!(
361-
"conflicting implementations of trait `{}`{}{}",
359+
"conflicting implementations of trait `{}`{}",
362360
overlap.trait_desc,
363361
overlap
364362
.self_desc
365363
.clone()
366364
.map_or_else(String::new, |ty| { format!(" for type `{}`", ty) }),
367-
match used_to_be_allowed {
368-
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
369-
_ => "",
370-
}
371365
);
372366
let mut err = err.build(&msg);
373367
match tcx.span_of_impl(overlap.with_impl) {
@@ -401,39 +395,25 @@ fn report_conflicting_impls(
401395
err.emit()
402396
}
403397

404-
match used_to_be_allowed {
405-
None => {
406-
let reported = if overlap.with_impl.is_local()
407-
|| tcx.orphan_check_impl(impl_def_id).is_ok()
408-
{
409-
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
410-
Some(decorate(
411-
tcx,
412-
overlap,
413-
used_to_be_allowed,
414-
impl_span,
415-
LintDiagnosticBuilder::new(err),
416-
))
417-
} else {
418-
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
419-
};
420-
sg.has_errored = reported;
421-
}
422-
Some(kind) => {
423-
let lint = match kind {
424-
FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS,
425-
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
426-
};
427-
tcx.struct_span_lint_hir(
428-
lint,
429-
tcx.hir().local_def_id_to_hir_id(impl_def_id),
430-
impl_span,
431-
|ldb| {
432-
decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb);
433-
},
434-
);
435-
}
436-
};
398+
if used_to_be_allowed {
399+
tcx.struct_span_lint_hir(
400+
COHERENCE_LEAK_CHECK,
401+
tcx.hir().local_def_id_to_hir_id(impl_def_id),
402+
impl_span,
403+
|ldb| {
404+
decorate(tcx, overlap, impl_span, ldb);
405+
},
406+
);
407+
} else {
408+
let reported = if overlap.with_impl.is_local() || tcx.orphan_check_impl(impl_def_id).is_ok()
409+
{
410+
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
411+
Some(decorate(tcx, overlap, impl_span, LintDiagnosticBuilder::new(err)))
412+
} else {
413+
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
414+
};
415+
sg.has_errored = reported;
416+
}
437417
}
438418

439419
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a

compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,10 @@ use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
88

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

11-
#[derive(Copy, Clone, Debug)]
12-
pub enum FutureCompatOverlapErrorKind {
13-
Issue33140,
14-
LeakCheck,
15-
}
16-
1711
#[derive(Debug)]
1812
pub struct FutureCompatOverlapError {
1913
pub error: OverlapError,
20-
pub kind: FutureCompatOverlapErrorKind,
14+
pub used_to_be_allowed: bool,
2115
}
2216

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

154145
Ok((false, false))
155146
}
@@ -167,13 +158,7 @@ impl ChildrenExt<'_> for Children {
167158
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
168159
{
169160
match overlap_kind {
170-
ty::ImplOverlapKind::Permitted { marker: _ } => {}
171-
ty::ImplOverlapKind::Issue33140 => {
172-
*last_lint_mut = Some(FutureCompatOverlapError {
173-
error: create_overlap_error(overlap),
174-
kind: FutureCompatOverlapErrorKind::Issue33140,
175-
});
176-
}
161+
ty::PermittedImplOverlap { marker: _ } => {}
177162
}
178163

179164
return Ok((false, false));

0 commit comments

Comments
 (0)