Turn order dependent trait objects future incompat warning into a hard error

This commit is contained in:
Oli Scherer 2025-02-13 09:53:08 +00:00
parent eeb9035117
commit 8f6b184946
13 changed files with 38 additions and 330 deletions

View file

@ -1920,9 +1920,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
let mut impl_candidate = None;
for c in impls {
if let Some(prev) = impl_candidate.replace(c) {
if self.prefer_lhs_over_victim(has_non_region_infer, c, prev) {
if self.prefer_lhs_over_victim(has_non_region_infer, c, prev.0) {
// Ok, prefer `c` over the previous entry
} else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c) {
} else if self.prefer_lhs_over_victim(has_non_region_infer, prev, c.0) {
// Ok, keep `prev` instead of the new entry
impl_candidate = Some(prev);
} else {
@ -1981,7 +1981,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
&self,
has_non_region_infer: bool,
(lhs, lhs_evaluation): (DefId, EvaluationResult),
(victim, victim_evaluation): (DefId, EvaluationResult),
victim: DefId,
) -> bool {
let tcx = self.tcx();
// See if we can toss out `victim` based on specialization.
@ -1997,14 +1997,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
match tcx.impls_are_allowed_to_overlap(lhs, victim) {
// For #33140 the impl headers must be exactly equal, the trait must not have
// any associated items and there are no where-clauses.
//
// We can just arbitrarily drop one of the impls.
Some(ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects) => {
assert_eq!(lhs_evaluation, victim_evaluation);
true
}
// For candidates which already reference errors it doesn't really
// matter what we do 🤷
Some(ty::ImplOverlapKind::Permitted { marker: false }) => {

View file

@ -20,7 +20,7 @@ use rustc_middle::bug;
use rustc_middle::query::LocalCrate;
use rustc_middle::ty::print::PrintTraitRefExt as _;
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt, TypingMode};
use rustc_session::lint::builtin::{COHERENCE_LEAK_CHECK, ORDER_DEPENDENT_TRAIT_OBJECTS};
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, sym};
use rustc_type_ir::solve::NoSolution;
use specialization_graph::GraphExt;
@ -557,13 +557,9 @@ fn report_conflicting_impls<'tcx>(
let msg = || {
format!(
"conflicting implementations of trait `{}`{}{}",
"conflicting implementations of trait `{}`{}",
overlap.trait_ref.print_trait_sugared(),
overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
match used_to_be_allowed {
Some(FutureCompatOverlapErrorKind::OrderDepTraitObjects) => ": (E0119)",
_ => "",
}
)
};
@ -588,7 +584,6 @@ fn report_conflicting_impls<'tcx>(
}
Some(kind) => {
let lint = match kind {
FutureCompatOverlapErrorKind::OrderDepTraitObjects => ORDER_DEPENDENT_TRAIT_OBJECTS,
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
};
tcx.node_span_lint(lint, tcx.local_def_id_to_hir_id(impl_def_id), impl_span, |err| {

View file

@ -12,7 +12,6 @@ use crate::traits;
#[derive(Copy, Clone, Debug)]
pub enum FutureCompatOverlapErrorKind {
OrderDepTraitObjects,
LeakCheck,
}
@ -151,12 +150,6 @@ impl<'tcx> Children {
{
match overlap_kind {
ty::ImplOverlapKind::Permitted { marker: _ } => {}
ty::ImplOverlapKind::FutureCompatOrderDepTraitObjects => {
*last_lint_mut = Some(FutureCompatOverlapError {
error: create_overlap_error(overlap),
kind: FutureCompatOverlapErrorKind::OrderDepTraitObjects,
});
}
}
return Ok((false, false));