Skip to content

Commit cdd93fd

Browse files
authored
Rollup merge of #81972 - matthewjasper:hrtb-error-cleanup, r=nikomatsakis
Placeholder lifetime error cleanup - Remove note of trait definition - Avoid repeating the same self type - Use original region names when possible - Use this error kind more often - Print closure signatures when they are suppose to implement `Fn*` traits Works towards #57374 r? ```@nikomatsakis```
2 parents f79be2c + f852160 commit cdd93fd

34 files changed

+283
-451
lines changed

Diff for: compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
4343
self.infcx.tcx
4444
}
4545

46-
pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'cx>> {
46+
pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx>> {
4747
// Due to the improved diagnostics returned by the MIR borrow checker, only a subset of
4848
// the nice region errors are required when running under the MIR borrow checker.
4949
self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict())

Diff for: compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::ty;
99
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
1010
/// When given a `ConcreteFailure` for a function with parameters containing a named region and
1111
/// an anonymous region, emit an descriptive diagnostic error.
12-
pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'a>> {
12+
pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
1313
let (span, sub, sup) = self.regions()?;
1414

1515
debug!(

Diff for: compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs

+126-106
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::fmt::{self, Write};
1616
impl NiceRegionError<'me, 'tcx> {
1717
/// When given a `ConcreteFailure` for a function with arguments containing a named region and
1818
/// an anonymous region, emit a descriptive diagnostic error.
19-
pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'me>> {
19+
pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
2020
match &self.error {
2121
///////////////////////////////////////////////////////////////////////////
2222
// NB. The ordering of cases in this match is very
@@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> {
3030
Some(RegionResolutionError::SubSupConflict(
3131
vid,
3232
_,
33-
SubregionOrigin::Subtype(box TypeTrace {
34-
cause,
35-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
36-
}),
33+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
3734
sub_placeholder @ ty::RePlaceholder(_),
3835
_,
3936
sup_placeholder @ ty::RePlaceholder(_),
40-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
37+
)) => self.try_report_trait_placeholder_mismatch(
4138
Some(self.tcx().mk_region(ty::ReVar(*vid))),
4239
cause,
4340
Some(sub_placeholder),
4441
Some(sup_placeholder),
45-
expected.def_id,
46-
expected.substs,
47-
found.substs,
48-
)),
42+
values,
43+
),
4944

5045
Some(RegionResolutionError::SubSupConflict(
5146
vid,
5247
_,
53-
SubregionOrigin::Subtype(box TypeTrace {
54-
cause,
55-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
56-
}),
48+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
5749
sub_placeholder @ ty::RePlaceholder(_),
5850
_,
5951
_,
60-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
52+
)) => self.try_report_trait_placeholder_mismatch(
6153
Some(self.tcx().mk_region(ty::ReVar(*vid))),
6254
cause,
6355
Some(sub_placeholder),
6456
None,
65-
expected.def_id,
66-
expected.substs,
67-
found.substs,
68-
)),
57+
values,
58+
),
6959

7060
Some(RegionResolutionError::SubSupConflict(
7161
vid,
7262
_,
73-
SubregionOrigin::Subtype(box TypeTrace {
74-
cause,
75-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
76-
}),
63+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
7764
_,
7865
_,
7966
sup_placeholder @ ty::RePlaceholder(_),
80-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
67+
)) => self.try_report_trait_placeholder_mismatch(
8168
Some(self.tcx().mk_region(ty::ReVar(*vid))),
8269
cause,
8370
None,
8471
Some(*sup_placeholder),
85-
expected.def_id,
86-
expected.substs,
87-
found.substs,
88-
)),
72+
values,
73+
),
8974

9075
Some(RegionResolutionError::SubSupConflict(
9176
vid,
9277
_,
9378
_,
9479
_,
95-
SubregionOrigin::Subtype(box TypeTrace {
96-
cause,
97-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
98-
}),
80+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
9981
sup_placeholder @ ty::RePlaceholder(_),
100-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
82+
)) => self.try_report_trait_placeholder_mismatch(
10183
Some(self.tcx().mk_region(ty::ReVar(*vid))),
10284
cause,
10385
None,
10486
Some(*sup_placeholder),
105-
expected.def_id,
106-
expected.substs,
107-
found.substs,
108-
)),
87+
values,
88+
),
10989

11090
Some(RegionResolutionError::UpperBoundUniverseConflict(
11191
vid,
11292
_,
11393
_,
114-
SubregionOrigin::Subtype(box TypeTrace {
115-
cause,
116-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
117-
}),
94+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
11895
sup_placeholder @ ty::RePlaceholder(_),
119-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
96+
)) => self.try_report_trait_placeholder_mismatch(
12097
Some(self.tcx().mk_region(ty::ReVar(*vid))),
12198
cause,
12299
None,
123100
Some(*sup_placeholder),
124-
expected.def_id,
125-
expected.substs,
126-
found.substs,
127-
)),
101+
values,
102+
),
128103

129104
Some(RegionResolutionError::ConcreteFailure(
130-
SubregionOrigin::Subtype(box TypeTrace {
131-
cause,
132-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
133-
}),
105+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
134106
sub_region @ ty::RePlaceholder(_),
135107
sup_region @ ty::RePlaceholder(_),
136-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
108+
)) => self.try_report_trait_placeholder_mismatch(
137109
None,
138110
cause,
139111
Some(*sub_region),
140112
Some(*sup_region),
141-
expected.def_id,
142-
expected.substs,
143-
found.substs,
144-
)),
113+
values,
114+
),
145115

146116
Some(RegionResolutionError::ConcreteFailure(
147-
SubregionOrigin::Subtype(box TypeTrace {
148-
cause,
149-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
150-
}),
117+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
151118
sub_region @ ty::RePlaceholder(_),
152119
sup_region,
153-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
154-
Some(sup_region),
120+
)) => self.try_report_trait_placeholder_mismatch(
121+
(!sup_region.has_name()).then_some(sup_region),
155122
cause,
156-
Some(*sub_region),
123+
Some(sub_region),
157124
None,
158-
expected.def_id,
159-
expected.substs,
160-
found.substs,
161-
)),
125+
values,
126+
),
162127

163128
Some(RegionResolutionError::ConcreteFailure(
164-
SubregionOrigin::Subtype(box TypeTrace {
165-
cause,
166-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
167-
}),
129+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
168130
sub_region,
169131
sup_region @ ty::RePlaceholder(_),
170-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
171-
Some(sub_region),
132+
)) => self.try_report_trait_placeholder_mismatch(
133+
(!sub_region.has_name()).then_some(sub_region),
172134
cause,
173135
None,
174-
Some(*sup_region),
175-
expected.def_id,
176-
expected.substs,
177-
found.substs,
178-
)),
136+
Some(sup_region),
137+
values,
138+
),
179139

180140
_ => None,
181141
}
182142
}
183143

144+
fn try_report_trait_placeholder_mismatch(
145+
&self,
146+
vid: Option<ty::Region<'tcx>>,
147+
cause: &ObligationCause<'tcx>,
148+
sub_placeholder: Option<ty::Region<'tcx>>,
149+
sup_placeholder: Option<ty::Region<'tcx>>,
150+
value_pairs: &ValuePairs<'tcx>,
151+
) -> Option<DiagnosticBuilder<'tcx>> {
152+
let (expected_substs, found_substs, trait_def_id) = match value_pairs {
153+
ValuePairs::TraitRefs(ExpectedFound { expected, found })
154+
if expected.def_id == found.def_id =>
155+
{
156+
(expected.substs, found.substs, expected.def_id)
157+
}
158+
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
159+
if expected.def_id() == found.def_id() =>
160+
{
161+
// It's possible that the placeholders come from a binder
162+
// outside of this value pair. Use `no_bound_vars` as a
163+
// simple heuristic for that.
164+
(expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id())
165+
}
166+
_ => return None,
167+
};
168+
169+
Some(self.report_trait_placeholder_mismatch(
170+
vid,
171+
cause,
172+
sub_placeholder,
173+
sup_placeholder,
174+
trait_def_id,
175+
expected_substs,
176+
found_substs,
177+
))
178+
}
179+
184180
// error[E0308]: implementation of `Foo` does not apply to enough lifetimes
185181
// --> /home/nmatsakis/tmp/foo.rs:12:5
186182
// |
@@ -190,7 +186,8 @@ impl NiceRegionError<'me, 'tcx> {
190186
// = note: Due to a where-clause on the function `all`,
191187
// = note: `T` must implement `...` for any two lifetimes `'1` and `'2`.
192188
// = note: However, the type `T` only implements `...` for some specific lifetime `'2`.
193-
fn try_report_placeholders_trait(
189+
#[instrument(level = "debug", skip(self))]
190+
fn report_trait_placeholder_mismatch(
194191
&self,
195192
vid: Option<ty::Region<'tcx>>,
196193
cause: &ObligationCause<'tcx>,
@@ -199,28 +196,13 @@ impl NiceRegionError<'me, 'tcx> {
199196
trait_def_id: DefId,
200197
expected_substs: SubstsRef<'tcx>,
201198
actual_substs: SubstsRef<'tcx>,
202-
) -> DiagnosticBuilder<'me> {
203-
debug!(
204-
"try_report_placeholders_trait(\
205-
vid={:?}, \
206-
sub_placeholder={:?}, \
207-
sup_placeholder={:?}, \
208-
trait_def_id={:?}, \
209-
expected_substs={:?}, \
210-
actual_substs={:?})",
211-
vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
212-
);
213-
199+
) -> DiagnosticBuilder<'tcx> {
214200
let span = cause.span(self.tcx());
215201
let msg = format!(
216202
"implementation of `{}` is not general enough",
217203
self.tcx().def_path_str(trait_def_id),
218204
);
219205
let mut err = self.tcx().sess.struct_span_err(span, &msg);
220-
err.span_label(
221-
self.tcx().def_span(trait_def_id),
222-
format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)),
223-
);
224206

225207
let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code {
226208
err.span_label(span, "doesn't satisfy where-clause");
@@ -285,17 +267,13 @@ impl NiceRegionError<'me, 'tcx> {
285267

286268
let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
287269

288-
debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid);
289-
debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid);
290-
debug!("try_report_placeholders_trait: has_sub={:?}", has_sub);
291-
debug!("try_report_placeholders_trait: has_sup={:?}", has_sup);
292270
debug!(
293-
"try_report_placeholders_trait: actual_self_ty_has_vid={:?}",
294-
actual_self_ty_has_vid
295-
);
296-
debug!(
297-
"try_report_placeholders_trait: expected_self_ty_has_vid={:?}",
298-
expected_self_ty_has_vid
271+
?actual_has_vid,
272+
?expected_has_vid,
273+
?has_sub,
274+
?has_sup,
275+
?actual_self_ty_has_vid,
276+
?expected_self_ty_has_vid,
299277
);
300278

301279
self.explain_actual_impl_that_was_found(
@@ -388,6 +366,8 @@ impl NiceRegionError<'me, 'tcx> {
388366
value: trait_ref,
389367
};
390368

369+
let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
370+
391371
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
392372
expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
393373
expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
@@ -403,7 +383,42 @@ impl NiceRegionError<'me, 'tcx> {
403383
}
404384
};
405385

406-
let mut note = if passive_voice {
386+
let mut note = if same_self_type {
387+
let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
388+
self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
389+
390+
if self_ty.value.is_closure()
391+
&& self
392+
.tcx()
393+
.fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id)
394+
.is_some()
395+
{
396+
let closure_sig = self_ty.map(|closure| {
397+
if let ty::Closure(_, substs) = closure.kind() {
398+
self.tcx().signature_unclosure(
399+
substs.as_closure().sig(),
400+
rustc_hir::Unsafety::Normal,
401+
)
402+
} else {
403+
bug!("type is not longer closure");
404+
}
405+
});
406+
407+
format!(
408+
"{}closure with signature `{}` must implement `{}`",
409+
if leading_ellipsis { "..." } else { "" },
410+
closure_sig,
411+
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
412+
)
413+
} else {
414+
format!(
415+
"{}`{}` must implement `{}`",
416+
if leading_ellipsis { "..." } else { "" },
417+
self_ty,
418+
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
419+
)
420+
}
421+
} else if passive_voice {
407422
format!(
408423
"{}`{}` would have to be implemented for the type `{}`",
409424
if leading_ellipsis { "..." } else { "" },
@@ -449,7 +464,12 @@ impl NiceRegionError<'me, 'tcx> {
449464
None => true,
450465
};
451466

452-
let mut note = if passive_voice {
467+
let mut note = if same_self_type {
468+
format!(
469+
"...but it actually implements `{}`",
470+
actual_trait_ref.map(|tr| tr.print_only_trait_path()),
471+
)
472+
} else if passive_voice {
453473
format!(
454474
"...but `{}` is actually implemented for the type `{}`",
455475
actual_trait_ref.map(|tr| tr.print_only_trait_path()),

0 commit comments

Comments
 (0)