Skip to content

Commit abda584

Browse files
authored
Rollup merge of #104229 - compiler-errors:overlap-full-path, r=davidtwco
Don't print full paths in overlap errors We don't print the full path in other diagnostics -- I don't think it particularly helps with the error message. I also delayed the printing until actually needing to render the error message. r? diagnostics
2 parents a86bdb4 + f902b49 commit abda584

32 files changed

+157
-156
lines changed

compiler/rustc_errors/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,10 @@ impl HandlerInner {
12541254
}
12551255

12561256
if diagnostic.has_future_breakage() {
1257+
// Future breakages aren't emitted if they're Level::Allowed,
1258+
// but they still need to be constructed and stashed below,
1259+
// so they'll trigger the good-path bug check.
1260+
self.suppressed_expected_diag = true;
12571261
self.future_breakage_diagnostics.push(diagnostic.clone());
12581262
}
12591263

compiler/rustc_trait_selection/src/errors.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ pub struct NoValueInOnUnimplemented {
5858
pub span: Span,
5959
}
6060

61-
pub struct NegativePositiveConflict<'a> {
61+
pub struct NegativePositiveConflict<'tcx> {
6262
pub impl_span: Span,
63-
pub trait_desc: &'a str,
64-
pub self_desc: &'a Option<String>,
63+
pub trait_desc: ty::TraitRef<'tcx>,
64+
pub self_ty: Option<Ty<'tcx>>,
6565
pub negative_impl_span: Result<Span, Symbol>,
6666
pub positive_impl_span: Result<Span, Symbol>,
6767
}
@@ -73,10 +73,10 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> {
7373
handler: &Handler,
7474
) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> {
7575
let mut diag = handler.struct_err(fluent::trait_selection_negative_positive_conflict);
76-
diag.set_arg("trait_desc", self.trait_desc);
76+
diag.set_arg("trait_desc", self.trait_desc.print_only_trait_path().to_string());
7777
diag.set_arg(
7878
"self_desc",
79-
self.self_desc.clone().map_or_else(|| String::from("none"), |ty| ty),
79+
self.self_ty.map_or_else(|| "none".to_string(), |ty| ty.to_string()),
8080
);
8181
diag.set_span(self.impl_span);
8282
diag.code(rustc_errors::error_code!(E0751));

compiler/rustc_trait_selection/src/traits/coherence.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
6464
/// with a suitably-freshened `ImplHeader` with those types
6565
/// substituted. Otherwise, returns `None`.
6666
#[instrument(skip(tcx, skip_leak_check), level = "debug")]
67-
pub fn overlapping_impls(
68-
tcx: TyCtxt<'_>,
67+
pub fn overlapping_impls<'tcx>(
68+
tcx: TyCtxt<'tcx>,
6969
impl1_def_id: DefId,
7070
impl2_def_id: DefId,
7171
skip_leak_check: SkipLeakCheck,
7272
overlap_mode: OverlapMode,
73-
) -> Option<OverlapResult<'_>> {
73+
) -> Option<OverlapResult<'tcx>> {
7474
// Before doing expensive operations like entering an inference context, do
7575
// a quick check via fast_reject to tell if the impl headers could possibly
7676
// unify.

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

+40-35
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ use crate::traits::engine::TraitEngineExt as _;
1919
use crate::traits::select::IntercrateAmbiguityCause;
2020
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause};
2121
use rustc_data_structures::fx::FxIndexSet;
22-
use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee};
22+
use rustc_errors::{error_code, DelayDm, Diagnostic};
2323
use rustc_hir::def_id::{DefId, LocalDefId};
24-
use rustc_middle::ty::{self, ImplSubject, TyCtxt};
24+
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
2525
use rustc_middle::ty::{InternalSubsts, SubstsRef};
2626
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
2727
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
@@ -32,10 +32,10 @@ use super::SelectionContext;
3232

3333
/// Information pertinent to an overlapping impl error.
3434
#[derive(Debug)]
35-
pub struct OverlapError {
35+
pub struct OverlapError<'tcx> {
3636
pub with_impl: DefId,
37-
pub trait_desc: String,
38-
pub self_desc: Option<String>,
37+
pub trait_ref: ty::TraitRef<'tcx>,
38+
pub self_ty: Option<Ty<'tcx>>,
3939
pub intercrate_ambiguity_causes: FxIndexSet<IntercrateAmbiguityCause>,
4040
pub involves_placeholder: bool,
4141
}
@@ -275,9 +275,9 @@ pub(super) fn specialization_graph_provider(
275275
// it negatively impacts perf.
276276
#[cold]
277277
#[inline(never)]
278-
fn report_overlap_conflict(
279-
tcx: TyCtxt<'_>,
280-
overlap: OverlapError,
278+
fn report_overlap_conflict<'tcx>(
279+
tcx: TyCtxt<'tcx>,
280+
overlap: OverlapError<'tcx>,
281281
impl_def_id: LocalDefId,
282282
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
283283
sg: &mut specialization_graph::Graph,
@@ -313,27 +313,27 @@ fn report_overlap_conflict(
313313
}
314314
}
315315

316-
fn report_negative_positive_conflict(
317-
tcx: TyCtxt<'_>,
318-
overlap: &OverlapError,
316+
fn report_negative_positive_conflict<'tcx>(
317+
tcx: TyCtxt<'tcx>,
318+
overlap: &OverlapError<'tcx>,
319319
local_impl_def_id: LocalDefId,
320320
negative_impl_def_id: DefId,
321321
positive_impl_def_id: DefId,
322322
sg: &mut specialization_graph::Graph,
323323
) {
324324
let mut err = tcx.sess.create_err(NegativePositiveConflict {
325325
impl_span: tcx.def_span(local_impl_def_id),
326-
trait_desc: &overlap.trait_desc,
327-
self_desc: &overlap.self_desc,
326+
trait_desc: overlap.trait_ref,
327+
self_ty: overlap.self_ty,
328328
negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
329329
positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
330330
});
331331
sg.has_errored = Some(err.emit());
332332
}
333333

334-
fn report_conflicting_impls(
335-
tcx: TyCtxt<'_>,
336-
overlap: OverlapError,
334+
fn report_conflicting_impls<'tcx>(
335+
tcx: TyCtxt<'tcx>,
336+
overlap: OverlapError<'tcx>,
337337
impl_def_id: LocalDefId,
338338
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
339339
sg: &mut specialization_graph::Graph,
@@ -343,12 +343,12 @@ fn report_conflicting_impls(
343343
// Work to be done after we've built the DiagnosticBuilder. We have to define it
344344
// now because the struct_lint methods don't return back the DiagnosticBuilder
345345
// that's passed in.
346-
fn decorate<'a, 'b, G: EmissionGuarantee>(
347-
tcx: TyCtxt<'_>,
348-
overlap: OverlapError,
346+
fn decorate<'tcx>(
347+
tcx: TyCtxt<'tcx>,
348+
overlap: &OverlapError<'tcx>,
349349
impl_span: Span,
350-
err: &'b mut DiagnosticBuilder<'a, G>,
351-
) -> &'b mut DiagnosticBuilder<'a, G> {
350+
err: &mut Diagnostic,
351+
) {
352352
match tcx.span_of_impl(overlap.with_impl) {
353353
Ok(span) => {
354354
err.span_label(span, "first implementation here");
@@ -357,7 +357,7 @@ fn report_conflicting_impls(
357357
impl_span,
358358
format!(
359359
"conflicting implementation{}",
360-
overlap.self_desc.map_or_else(String::new, |ty| format!(" for `{}`", ty))
360+
overlap.self_ty.map_or_else(String::new, |ty| format!(" for `{}`", ty))
361361
),
362362
);
363363
}
@@ -379,26 +379,28 @@ fn report_conflicting_impls(
379379
if overlap.involves_placeholder {
380380
coherence::add_placeholder_note(err);
381381
}
382-
err
383382
}
384383

385-
let msg = format!(
386-
"conflicting implementations of trait `{}`{}{}",
387-
overlap.trait_desc,
388-
overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")),
389-
match used_to_be_allowed {
390-
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
391-
_ => "",
392-
}
393-
);
384+
let msg = DelayDm(|| {
385+
format!(
386+
"conflicting implementations of trait `{}`{}{}",
387+
overlap.trait_ref.print_only_trait_path(),
388+
overlap.self_ty.map_or_else(String::new, |ty| format!(" for type `{ty}`")),
389+
match used_to_be_allowed {
390+
Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)",
391+
_ => "",
392+
}
393+
)
394+
});
394395

395396
match used_to_be_allowed {
396397
None => {
397398
let reported = if overlap.with_impl.is_local()
398399
|| tcx.orphan_check_impl(impl_def_id).is_ok()
399400
{
400-
let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",);
401-
decorate(tcx, overlap, impl_span, &mut err);
401+
let mut err = tcx.sess.struct_span_err(impl_span, msg);
402+
err.code(error_code!(E0119));
403+
decorate(tcx, &overlap, impl_span, &mut err);
402404
Some(err.emit())
403405
} else {
404406
Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"))
@@ -415,7 +417,10 @@ fn report_conflicting_impls(
415417
tcx.hir().local_def_id_to_hir_id(impl_def_id),
416418
impl_span,
417419
msg,
418-
|err| decorate(tcx, overlap, impl_span, err),
420+
|err| {
421+
decorate(tcx, &overlap, impl_span, err);
422+
err
423+
},
419424
);
420425
}
421426
};

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

+30-38
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use super::OverlapError;
33
use crate::traits;
44
use rustc_hir::def_id::DefId;
55
use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
6-
use rustc_middle::ty::print::with_no_trimmed_paths;
76
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
87

98
pub use rustc_middle::traits::specialization_graph::*;
@@ -15,15 +14,15 @@ pub enum FutureCompatOverlapErrorKind {
1514
}
1615

1716
#[derive(Debug)]
18-
pub struct FutureCompatOverlapError {
19-
pub error: OverlapError,
17+
pub struct FutureCompatOverlapError<'tcx> {
18+
pub error: OverlapError<'tcx>,
2019
pub kind: FutureCompatOverlapErrorKind,
2120
}
2221

2322
/// The result of attempting to insert an impl into a group of children.
24-
enum Inserted {
23+
enum Inserted<'tcx> {
2524
/// The impl was inserted as a new child in this group of children.
26-
BecameNewSibling(Option<FutureCompatOverlapError>),
25+
BecameNewSibling(Option<FutureCompatOverlapError<'tcx>>),
2726

2827
/// The impl should replace existing impls [X1, ..], because the impl specializes X1, X2, etc.
2928
ReplaceChildren(Vec<DefId>),
@@ -42,12 +41,12 @@ trait ChildrenExt<'tcx> {
4241
impl_def_id: DefId,
4342
simplified_self: Option<SimplifiedType>,
4443
overlap_mode: OverlapMode,
45-
) -> Result<Inserted, OverlapError>;
44+
) -> Result<Inserted<'tcx>, OverlapError<'tcx>>;
4645
}
4746

48-
impl ChildrenExt<'_> for Children {
47+
impl<'tcx> ChildrenExt<'tcx> for Children {
4948
/// Insert an impl into this set of children without comparing to any existing impls.
50-
fn insert_blindly(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
49+
fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
5150
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
5251
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
5352
{
@@ -62,7 +61,7 @@ impl ChildrenExt<'_> for Children {
6261
/// Removes an impl from this set of children. Used when replacing
6362
/// an impl with a parent. The impl must be present in the list of
6463
/// children already.
65-
fn remove_existing(&mut self, tcx: TyCtxt<'_>, impl_def_id: DefId) {
64+
fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
6665
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
6766
let vec: &mut Vec<DefId>;
6867
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsInfer)
@@ -82,11 +81,11 @@ impl ChildrenExt<'_> for Children {
8281
/// specialization relationships.
8382
fn insert(
8483
&mut self,
85-
tcx: TyCtxt<'_>,
84+
tcx: TyCtxt<'tcx>,
8685
impl_def_id: DefId,
8786
simplified_self: Option<SimplifiedType>,
8887
overlap_mode: OverlapMode,
89-
) -> Result<Inserted, OverlapError> {
88+
) -> Result<Inserted<'tcx>, OverlapError<'tcx>> {
9089
let mut last_lint = None;
9190
let mut replace_children = Vec::new();
9291

@@ -103,30 +102,23 @@ impl ChildrenExt<'_> for Children {
103102
impl_def_id, simplified_self, possible_sibling,
104103
);
105104

106-
let create_overlap_error = |overlap: traits::coherence::OverlapResult<'_>| {
105+
let create_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>| {
107106
let trait_ref = overlap.impl_header.trait_ref.unwrap();
108107
let self_ty = trait_ref.self_ty();
109108

110-
// FIXME: should postpone string formatting until we decide to actually emit.
111-
with_no_trimmed_paths!({
112-
OverlapError {
113-
with_impl: possible_sibling,
114-
trait_desc: trait_ref.print_only_trait_path().to_string(),
115-
// Only report the `Self` type if it has at least
116-
// some outer concrete shell; otherwise, it's
117-
// not adding much information.
118-
self_desc: if self_ty.has_concrete_skeleton() {
119-
Some(self_ty.to_string())
120-
} else {
121-
None
122-
},
123-
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
124-
involves_placeholder: overlap.involves_placeholder,
125-
}
126-
})
109+
OverlapError {
110+
with_impl: possible_sibling,
111+
trait_ref,
112+
// Only report the `Self` type if it has at least
113+
// some outer concrete shell; otherwise, it's
114+
// not adding much information.
115+
self_ty: if self_ty.has_concrete_skeleton() { Some(self_ty) } else { None },
116+
intercrate_ambiguity_causes: overlap.intercrate_ambiguity_causes,
117+
involves_placeholder: overlap.involves_placeholder,
118+
}
127119
};
128120

129-
let report_overlap_error = |overlap: traits::coherence::OverlapResult<'_>,
121+
let report_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>,
130122
last_lint: &mut _| {
131123
// Found overlap, but no specialization; error out or report future-compat warning.
132124

@@ -255,31 +247,31 @@ where
255247
}
256248
}
257249

258-
pub trait GraphExt {
250+
pub trait GraphExt<'tcx> {
259251
/// Insert a local impl into the specialization graph. If an existing impl
260252
/// conflicts with it (has overlap, but neither specializes the other),
261253
/// information about the area of overlap is returned in the `Err`.
262254
fn insert(
263255
&mut self,
264-
tcx: TyCtxt<'_>,
256+
tcx: TyCtxt<'tcx>,
265257
impl_def_id: DefId,
266258
overlap_mode: OverlapMode,
267-
) -> Result<Option<FutureCompatOverlapError>, OverlapError>;
259+
) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>>;
268260

269261
/// Insert cached metadata mapping from a child impl back to its parent.
270-
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId);
262+
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId);
271263
}
272264

273-
impl GraphExt for Graph {
265+
impl<'tcx> GraphExt<'tcx> for Graph {
274266
/// Insert a local impl into the specialization graph. If an existing impl
275267
/// conflicts with it (has overlap, but neither specializes the other),
276268
/// information about the area of overlap is returned in the `Err`.
277269
fn insert(
278270
&mut self,
279-
tcx: TyCtxt<'_>,
271+
tcx: TyCtxt<'tcx>,
280272
impl_def_id: DefId,
281273
overlap_mode: OverlapMode,
282-
) -> Result<Option<FutureCompatOverlapError>, OverlapError> {
274+
) -> Result<Option<FutureCompatOverlapError<'tcx>>, OverlapError<'tcx>> {
283275
assert!(impl_def_id.is_local());
284276

285277
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
@@ -376,7 +368,7 @@ impl GraphExt for Graph {
376368
}
377369

378370
/// Insert cached metadata mapping from a child impl back to its parent.
379-
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'_>, parent: DefId, child: DefId) {
371+
fn record_impl_from_cstore(&mut self, tcx: TyCtxt<'tcx>, parent: DefId, child: DefId) {
380372
if self.parent.insert(child, parent).is_some() {
381373
bug!(
382374
"When recording an impl from the crate store, information about its parent \

src/test/ui/coherence/coherence-blanket-conflicts-with-specific-cross-crate.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0119]: conflicting implementations of trait `go_trait::GoMut` for type `MyThingy`
1+
error[E0119]: conflicting implementations of trait `GoMut` for type `MyThingy`
22
--> $DIR/coherence-blanket-conflicts-with-specific-cross-crate.rs:15:1
33
|
44
LL | impl GoMut for MyThingy {

src/test/ui/coherence/coherence-conflicting-negative-trait-impl.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
1+
error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`:
22
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
33
|
44
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
@@ -7,7 +7,7 @@ LL |
77
LL | impl<T: MyTrait> !Send for TestType<T> {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
99

10-
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`
10+
error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
1111
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
1212
|
1313
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}

src/test/ui/coherence/coherence-impls-copy.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | impl Copy for i32 {}
99
|
1010
= note: define and implement a trait or new type instead
1111

12-
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
12+
error[E0119]: conflicting implementations of trait `Copy` for type `&NotSync`
1313
--> $DIR/coherence-impls-copy.rs:28:1
1414
|
1515
LL | impl Copy for &'static NotSync {}

0 commit comments

Comments
 (0)