1use std::fmt;
2
3use rustc_data_structures::intern::Interned;
4use rustc_errors::{Diag, IntoDiagArg};
5use rustc_hir::def::Namespace;
6use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
7use rustc_middle::bug;
8use rustc_middle::ty::error::ExpectedFound;
9use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
10use rustc_middle::ty::{self, GenericArgsRef, RePlaceholder, Region, TyCtxt};
11use tracing::{debug, instrument};
12
13use crate::diagnostics::{
14 ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
15 TraitPlaceholderMismatch, TyOrSig,
16};
17use crate::error_reporting::infer::nice_region_error::NiceRegionError;
18use crate::infer::{RegionResolutionError, SubregionOrigin, TypeTrace, ValuePairs};
19use crate::traits::{ObligationCause, ObligationCauseCode};
20
21#[derive(#[automatically_derived]
impl<'tcx, T: ::core::marker::Copy> ::core::marker::Copy for
Highlighted<'tcx, T> {
}Copy, #[automatically_derived]
impl<'tcx, T: ::core::clone::Clone> ::core::clone::Clone for
Highlighted<'tcx, T> {
#[inline]
fn clone(&self) -> Highlighted<'tcx, T> {
Highlighted {
tcx: ::core::clone::Clone::clone(&self.tcx),
highlight: ::core::clone::Clone::clone(&self.highlight),
value: ::core::clone::Clone::clone(&self.value),
ns: ::core::clone::Clone::clone(&self.ns),
}
}
}Clone)]
22pub(crate) struct Highlighted<'tcx, T> {
23 pub tcx: TyCtxt<'tcx>,
24 pub highlight: RegionHighlightMode<'tcx>,
25 pub value: T,
26 pub ns: Namespace,
27}
28
29impl<'tcx, T> IntoDiagArg for Highlighted<'tcx, T>
30where
31 T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
32{
33 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
34 rustc_errors::DiagArgValue::Str(self.to_string().into())
35 }
36}
37
38impl<'tcx, T> Highlighted<'tcx, T> {
39 fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> {
40 Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value), ns: self.ns }
41 }
42}
43
44impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
45where
46 T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
47{
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 let mut p = ty::print::FmtPrinter::new(self.tcx, self.ns);
50 p.region_highlight_mode = self.highlight;
51
52 self.value.print(&mut p)?;
53 f.write_str(&p.into_buffer())
54 }
55}
56
57impl<'tcx> NiceRegionError<'_, 'tcx> {
58 pub(super) fn try_report_placeholder_conflict(&self) -> Option<Diag<'tcx>> {
61 match &self.error {
62 Some(RegionResolutionError::SubSupConflict(
72 vid,
73 _,
74 SubregionOrigin::Subtype(TypeTrace { cause, values }),
75 sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
76 _,
77 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
78 _,
79 )) => self.try_report_trait_placeholder_mismatch(
80 Some(ty::Region::new_var(self.tcx(), *vid)),
81 cause,
82 Some(*sub_placeholder),
83 Some(*sup_placeholder),
84 values,
85 ),
86
87 Some(RegionResolutionError::SubSupConflict(
88 vid,
89 _,
90 SubregionOrigin::Subtype(TypeTrace { cause, values }),
91 sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
92 _,
93 _,
94 _,
95 )) => self.try_report_trait_placeholder_mismatch(
96 Some(ty::Region::new_var(self.tcx(), *vid)),
97 cause,
98 Some(*sub_placeholder),
99 None,
100 values,
101 ),
102
103 Some(RegionResolutionError::SubSupConflict(
104 vid,
105 _,
106 SubregionOrigin::Subtype(TypeTrace { cause, values }),
107 _,
108 _,
109 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
110 _,
111 )) => self.try_report_trait_placeholder_mismatch(
112 Some(ty::Region::new_var(self.tcx(), *vid)),
113 cause,
114 None,
115 Some(*sup_placeholder),
116 values,
117 ),
118
119 Some(RegionResolutionError::SubSupConflict(
120 vid,
121 _,
122 _,
123 _,
124 SubregionOrigin::Subtype(TypeTrace { cause, values }),
125 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
126 _,
127 )) => self.try_report_trait_placeholder_mismatch(
128 Some(ty::Region::new_var(self.tcx(), *vid)),
129 cause,
130 None,
131 Some(*sup_placeholder),
132 values,
133 ),
134
135 Some(RegionResolutionError::UpperBoundUniverseConflict(
136 vid,
137 _,
138 _,
139 SubregionOrigin::Subtype(TypeTrace { cause, values }),
140 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
141 )) => self.try_report_trait_placeholder_mismatch(
142 Some(ty::Region::new_var(self.tcx(), *vid)),
143 cause,
144 None,
145 Some(*sup_placeholder),
146 values,
147 ),
148
149 Some(RegionResolutionError::ConcreteFailure(
150 SubregionOrigin::Subtype(TypeTrace { cause, values }),
151 sub_region @ Region(Interned(RePlaceholder(_), _)),
152 sup_region @ Region(Interned(RePlaceholder(_), _)),
153 )) => self.try_report_trait_placeholder_mismatch(
154 None,
155 cause,
156 Some(*sub_region),
157 Some(*sup_region),
158 values,
159 ),
160
161 Some(RegionResolutionError::ConcreteFailure(
162 SubregionOrigin::Subtype(TypeTrace { cause, values }),
163 sub_region @ Region(Interned(RePlaceholder(_), _)),
164 sup_region,
165 )) => self.try_report_trait_placeholder_mismatch(
166 (!sup_region.is_named(self.tcx())).then_some(*sup_region),
167 cause,
168 Some(*sub_region),
169 None,
170 values,
171 ),
172
173 Some(RegionResolutionError::ConcreteFailure(
174 SubregionOrigin::Subtype(TypeTrace { cause, values }),
175 sub_region,
176 sup_region @ Region(Interned(RePlaceholder(_), _)),
177 )) => self.try_report_trait_placeholder_mismatch(
178 (!sub_region.is_named(self.tcx())).then_some(*sub_region),
179 cause,
180 None,
181 Some(*sup_region),
182 values,
183 ),
184
185 _ => None,
186 }
187 }
188
189 fn try_report_trait_placeholder_mismatch(
190 &self,
191 vid: Option<Region<'tcx>>,
192 cause: &ObligationCause<'tcx>,
193 sub_placeholder: Option<Region<'tcx>>,
194 sup_placeholder: Option<Region<'tcx>>,
195 value_pairs: &ValuePairs<'tcx>,
196 ) -> Option<Diag<'tcx>> {
197 let (expected_args, found_args, trait_def_id) = match value_pairs {
198 ValuePairs::TraitRefs(ExpectedFound { expected, found })
199 if expected.def_id == found.def_id =>
200 {
201 (expected.args, found.args, expected.def_id)
205 }
206 _ => return None,
207 };
208
209 Some(self.report_trait_placeholder_mismatch(
210 vid,
211 cause,
212 sub_placeholder,
213 sup_placeholder,
214 trait_def_id,
215 expected_args,
216 found_args,
217 ))
218 }
219
220 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("report_trait_placeholder_mismatch",
"rustc_trait_selection::error_reporting::infer::nice_region_error::placeholder_error",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs"),
::tracing_core::__macro_support::Option::Some(229u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::placeholder_error"),
::tracing_core::field::FieldSet::new(&["vid", "cause",
"sub_placeholder", "sup_placeholder", "trait_def_id",
"expected_args", "actual_args"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&vid)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cause)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sub_placeholder)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sup_placeholder)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expected_args)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&actual_args)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Diag<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let span = cause.span;
let (leading_ellipsis, satisfy_span, where_span, dup_span,
def_id) =
if let ObligationCauseCode::WhereClause(def_id, span) |
ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) =
*cause.code() && def_id != CRATE_DEF_ID.to_def_id() {
(true, Some(span), Some(self.tcx().def_span(def_id)), None,
self.tcx().def_path_str(def_id))
} else { (false, None, None, Some(span), String::new()) };
let expected_trait_ref =
self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(self.cx.tcx,
trait_def_id, expected_args));
let actual_trait_ref =
self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(self.cx.tcx,
trait_def_id, actual_args));
let mut counter = 0;
let mut has_sub = None;
let mut has_sup = None;
let mut actual_has_vid = None;
let mut expected_has_vid = None;
self.tcx().for_each_free_region(&expected_trait_ref,
|r|
{
if Some(r) == sub_placeholder && has_sub.is_none() {
has_sub = Some(counter);
counter += 1;
} else if Some(r) == sup_placeholder && has_sup.is_none() {
has_sup = Some(counter);
counter += 1;
}
if Some(r) == vid && expected_has_vid.is_none() {
expected_has_vid = Some(counter);
counter += 1;
}
});
self.tcx().for_each_free_region(&actual_trait_ref,
|r|
{
if Some(r) == vid && actual_has_vid.is_none() {
actual_has_vid = Some(counter);
counter += 1;
}
});
let actual_self_ty_has_vid =
self.tcx().any_free_region_meets(&actual_trait_ref.self_ty(),
|r| Some(r) == vid);
let expected_self_ty_has_vid =
self.tcx().any_free_region_meets(&expected_trait_ref.self_ty(),
|r| Some(r) == vid);
let any_self_ty_has_vid =
actual_self_ty_has_vid || expected_self_ty_has_vid;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs:312",
"rustc_trait_selection::error_reporting::infer::nice_region_error::placeholder_error",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/placeholder_error.rs"),
::tracing_core::__macro_support::Option::Some(312u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::nice_region_error::placeholder_error"),
::tracing_core::field::FieldSet::new(&["actual_has_vid",
"expected_has_vid", "has_sub", "has_sup",
"actual_self_ty_has_vid", "expected_self_ty_has_vid"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&actual_has_vid)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&expected_has_vid)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&has_sub) as
&dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&has_sup) as
&dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&actual_self_ty_has_vid)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&expected_self_ty_has_vid)
as &dyn Value))])
});
} else { ; }
};
let actual_impl_expl_notes =
self.explain_actual_impl_that_was_found(sub_placeholder,
sup_placeholder, has_sub, has_sup, expected_trait_ref,
actual_trait_ref, vid, expected_has_vid, actual_has_vid,
any_self_ty_has_vid, leading_ellipsis);
let mut err =
self.tcx().dcx().create_err(TraitPlaceholderMismatch {
span,
satisfy_span,
where_span,
dup_span,
def_id,
trait_def_id: self.tcx().def_path_str(trait_def_id),
actual_impl_expl_notes,
});
let mut current_code = cause.code();
let mut coroutine_def_id = None;
loop {
match current_code {
ObligationCauseCode::MatchImpl(inner_cause, _) => {
current_code = inner_cause.code();
}
ObligationCauseCode::BuiltinDerived(derived) => {
let self_ty =
derived.parent_trait_pred.skip_binder().self_ty();
if let ty::Coroutine(def_id, _) |
ty::CoroutineWitness(def_id, _) = self_ty.kind() {
coroutine_def_id = Some(*def_id);
break;
}
current_code = &derived.parent_code;
}
_ => break,
}
}
if let Some(def_id) = coroutine_def_id {
if self.tcx().trait_is_auto(trait_def_id) {
let c_span = self.tcx().def_span(def_id);
let descr = self.tcx().def_descr(def_id);
let trait_name = self.tcx().def_path_str(trait_def_id);
err.span_label(c_span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("this {0} captures a value whose type is not `{1}`",
descr, trait_name))
}));
}
}
err
}
}
}#[instrument(level = "debug", skip(self))]
230 fn report_trait_placeholder_mismatch(
231 &self,
232 vid: Option<Region<'tcx>>,
233 cause: &ObligationCause<'tcx>,
234 sub_placeholder: Option<Region<'tcx>>,
235 sup_placeholder: Option<Region<'tcx>>,
236 trait_def_id: DefId,
237 expected_args: GenericArgsRef<'tcx>,
238 actual_args: GenericArgsRef<'tcx>,
239 ) -> Diag<'tcx> {
240 let span = cause.span;
241
242 let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) =
243 if let ObligationCauseCode::WhereClause(def_id, span)
244 | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code()
245 && def_id != CRATE_DEF_ID.to_def_id()
246 {
247 (
248 true,
249 Some(span),
250 Some(self.tcx().def_span(def_id)),
251 None,
252 self.tcx().def_path_str(def_id),
253 )
254 } else {
255 (false, None, None, Some(span), String::new())
256 };
257
258 let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
259 self.cx.tcx,
260 trait_def_id,
261 expected_args,
262 ));
263 let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
264 self.cx.tcx,
265 trait_def_id,
266 actual_args,
267 ));
268
269 let mut counter = 0;
276 let mut has_sub = None;
277 let mut has_sup = None;
278
279 let mut actual_has_vid = None;
280 let mut expected_has_vid = None;
281
282 self.tcx().for_each_free_region(&expected_trait_ref, |r| {
283 if Some(r) == sub_placeholder && has_sub.is_none() {
284 has_sub = Some(counter);
285 counter += 1;
286 } else if Some(r) == sup_placeholder && has_sup.is_none() {
287 has_sup = Some(counter);
288 counter += 1;
289 }
290
291 if Some(r) == vid && expected_has_vid.is_none() {
292 expected_has_vid = Some(counter);
293 counter += 1;
294 }
295 });
296
297 self.tcx().for_each_free_region(&actual_trait_ref, |r| {
298 if Some(r) == vid && actual_has_vid.is_none() {
299 actual_has_vid = Some(counter);
300 counter += 1;
301 }
302 });
303
304 let actual_self_ty_has_vid =
305 self.tcx().any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid);
306
307 let expected_self_ty_has_vid =
308 self.tcx().any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid);
309
310 let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
311
312 debug!(
313 ?actual_has_vid,
314 ?expected_has_vid,
315 ?has_sub,
316 ?has_sup,
317 ?actual_self_ty_has_vid,
318 ?expected_self_ty_has_vid,
319 );
320
321 let actual_impl_expl_notes = self.explain_actual_impl_that_was_found(
322 sub_placeholder,
323 sup_placeholder,
324 has_sub,
325 has_sup,
326 expected_trait_ref,
327 actual_trait_ref,
328 vid,
329 expected_has_vid,
330 actual_has_vid,
331 any_self_ty_has_vid,
332 leading_ellipsis,
333 );
334
335 let mut err = self.tcx().dcx().create_err(TraitPlaceholderMismatch {
336 span,
337 satisfy_span,
338 where_span,
339 dup_span,
340 def_id,
341 trait_def_id: self.tcx().def_path_str(trait_def_id),
342 actual_impl_expl_notes,
343 });
344
345 let mut current_code = cause.code();
346 let mut coroutine_def_id = None;
347
348 loop {
349 match current_code {
350 ObligationCauseCode::MatchImpl(inner_cause, _) => {
351 current_code = inner_cause.code();
352 }
353 ObligationCauseCode::BuiltinDerived(derived) => {
354 let self_ty = derived.parent_trait_pred.skip_binder().self_ty();
355
356 if let ty::Coroutine(def_id, _) | ty::CoroutineWitness(def_id, _) =
357 self_ty.kind()
358 {
359 coroutine_def_id = Some(*def_id);
360 break;
361 }
362
363 current_code = &derived.parent_code;
364 }
365 _ => break,
366 }
367 }
368
369 if let Some(def_id) = coroutine_def_id {
370 if self.tcx().trait_is_auto(trait_def_id) {
371 let c_span = self.tcx().def_span(def_id);
372 let descr = self.tcx().def_descr(def_id);
373 let trait_name = self.tcx().def_path_str(trait_def_id);
374
375 err.span_label(
376 c_span,
377 format!("this {descr} captures a value whose type is not `{trait_name}`"),
378 );
379 }
380 }
381
382 err
383 }
384
385 fn explain_actual_impl_that_was_found(
391 &self,
392 sub_placeholder: Option<Region<'tcx>>,
393 sup_placeholder: Option<Region<'tcx>>,
394 has_sub: Option<usize>,
395 has_sup: Option<usize>,
396 expected_trait_ref: ty::TraitRef<'tcx>,
397 actual_trait_ref: ty::TraitRef<'tcx>,
398 vid: Option<Region<'tcx>>,
399 expected_has_vid: Option<usize>,
400 actual_has_vid: Option<usize>,
401 any_self_ty_has_vid: bool,
402 leading_ellipsis: bool,
403 ) -> Vec<ActualImplExplNotes<'tcx>> {
404 let highlight_trait_ref = |trait_ref| Highlighted {
420 tcx: self.tcx(),
421 highlight: RegionHighlightMode::default(),
422 value: trait_ref,
423 ns: Namespace::TypeNS,
424 };
425
426 let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
427
428 let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
429 expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
430 expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
431
432 let passive_voice = match (has_sub, has_sup) {
433 (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
434 (None, None) => {
435 expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
436 match expected_has_vid {
437 Some(_) => true,
438 None => any_self_ty_has_vid,
439 }
440 }
441 };
442
443 let (kind, ty_or_sig, trait_path) = if same_self_type {
444 let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
445 self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
446
447 if self_ty.value.is_closure() && self.tcx().is_fn_trait(expected_trait_ref.value.def_id)
448 {
449 let closure_sig = self_ty.map(|closure| {
450 if let ty::Closure(_, args) = closure.kind() {
451 self.tcx()
452 .signature_unclosure(args.as_closure().sig(), rustc_hir::Safety::Safe)
453 } else {
454 ::rustc_middle::util::bug::bug_fmt(format_args!("type is not longer closure"));bug!("type is not longer closure");
455 }
456 });
457 (
458 ActualImplExpectedKind::Signature,
459 TyOrSig::ClosureSig(closure_sig),
460 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
461 )
462 } else {
463 (
464 ActualImplExpectedKind::Other,
465 TyOrSig::Ty(self_ty),
466 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
467 )
468 }
469 } else if passive_voice {
470 (
471 ActualImplExpectedKind::Passive,
472 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
473 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
474 )
475 } else {
476 (
477 ActualImplExpectedKind::Other,
478 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
479 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
480 )
481 };
482
483 let (lt_kind, lifetime_1, lifetime_2) = match (has_sub, has_sup) {
484 (Some(n1), Some(n2)) => {
485 (ActualImplExpectedLifetimeKind::Two, std::cmp::min(n1, n2), std::cmp::max(n1, n2))
486 }
487 (Some(n), _) | (_, Some(n)) => (ActualImplExpectedLifetimeKind::Any, n, 0),
488 (None, None) => {
489 if let Some(n) = expected_has_vid {
490 (ActualImplExpectedLifetimeKind::Some, n, 0)
491 } else {
492 (ActualImplExpectedLifetimeKind::Nothing, 0, 0)
493 }
494 }
495 };
496
497 let note_1 = ActualImplExplNotes::new_expected(
498 kind,
499 lt_kind,
500 leading_ellipsis,
501 ty_or_sig,
502 trait_path,
503 lifetime_1,
504 lifetime_2,
505 );
506
507 let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
508 actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
509
510 let passive_voice = match actual_has_vid {
511 Some(_) => any_self_ty_has_vid,
512 None => true,
513 };
514
515 let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path());
516 let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string();
517 let has_lifetime = actual_has_vid.is_some();
518 let lifetime = actual_has_vid.unwrap_or_default();
519
520 let note_2 = if same_self_type {
521 ActualImplExplNotes::ButActuallyImplementsTrait { trait_path, has_lifetime, lifetime }
522 } else if passive_voice {
523 ActualImplExplNotes::ButActuallyImplementedForTy {
524 trait_path,
525 ty,
526 has_lifetime,
527 lifetime,
528 }
529 } else {
530 ActualImplExplNotes::ButActuallyTyImplements { trait_path, ty, has_lifetime, lifetime }
531 };
532
533 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[note_1, note_2]))vec![note_1, note_2]
534 }
535}