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::error_reporting::infer::nice_region_error::NiceRegionError;
14use crate::errors::{
15 ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
16 TraitPlaceholderMismatch, TyOrSig,
17};
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<'tcx, 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<'tcx, 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(box 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(box 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(box 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(box 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(box 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(box 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(box 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(box 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);
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,
})
}
}
}#[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 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
346 fn explain_actual_impl_that_was_found(
352 &self,
353 sub_placeholder: Option<Region<'tcx>>,
354 sup_placeholder: Option<Region<'tcx>>,
355 has_sub: Option<usize>,
356 has_sup: Option<usize>,
357 expected_trait_ref: ty::TraitRef<'tcx>,
358 actual_trait_ref: ty::TraitRef<'tcx>,
359 vid: Option<Region<'tcx>>,
360 expected_has_vid: Option<usize>,
361 actual_has_vid: Option<usize>,
362 any_self_ty_has_vid: bool,
363 leading_ellipsis: bool,
364 ) -> Vec<ActualImplExplNotes<'tcx>> {
365 let highlight_trait_ref = |trait_ref| Highlighted {
381 tcx: self.tcx(),
382 highlight: RegionHighlightMode::default(),
383 value: trait_ref,
384 ns: Namespace::TypeNS,
385 };
386
387 let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
388
389 let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
390 expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
391 expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
392
393 let passive_voice = match (has_sub, has_sup) {
394 (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
395 (None, None) => {
396 expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
397 match expected_has_vid {
398 Some(_) => true,
399 None => any_self_ty_has_vid,
400 }
401 }
402 };
403
404 let (kind, ty_or_sig, trait_path) = if same_self_type {
405 let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
406 self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
407
408 if self_ty.value.is_closure() && self.tcx().is_fn_trait(expected_trait_ref.value.def_id)
409 {
410 let closure_sig = self_ty.map(|closure| {
411 if let ty::Closure(_, args) = closure.kind() {
412 self.tcx()
413 .signature_unclosure(args.as_closure().sig(), rustc_hir::Safety::Safe)
414 } else {
415 ::rustc_middle::util::bug::bug_fmt(format_args!("type is not longer closure"));bug!("type is not longer closure");
416 }
417 });
418 (
419 ActualImplExpectedKind::Signature,
420 TyOrSig::ClosureSig(closure_sig),
421 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
422 )
423 } else {
424 (
425 ActualImplExpectedKind::Other,
426 TyOrSig::Ty(self_ty),
427 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
428 )
429 }
430 } else if passive_voice {
431 (
432 ActualImplExpectedKind::Passive,
433 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
434 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
435 )
436 } else {
437 (
438 ActualImplExpectedKind::Other,
439 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
440 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
441 )
442 };
443
444 let (lt_kind, lifetime_1, lifetime_2) = match (has_sub, has_sup) {
445 (Some(n1), Some(n2)) => {
446 (ActualImplExpectedLifetimeKind::Two, std::cmp::min(n1, n2), std::cmp::max(n1, n2))
447 }
448 (Some(n), _) | (_, Some(n)) => (ActualImplExpectedLifetimeKind::Any, n, 0),
449 (None, None) => {
450 if let Some(n) = expected_has_vid {
451 (ActualImplExpectedLifetimeKind::Some, n, 0)
452 } else {
453 (ActualImplExpectedLifetimeKind::Nothing, 0, 0)
454 }
455 }
456 };
457
458 let note_1 = ActualImplExplNotes::new_expected(
459 kind,
460 lt_kind,
461 leading_ellipsis,
462 ty_or_sig,
463 trait_path,
464 lifetime_1,
465 lifetime_2,
466 );
467
468 let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
469 actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
470
471 let passive_voice = match actual_has_vid {
472 Some(_) => any_self_ty_has_vid,
473 None => true,
474 };
475
476 let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path());
477 let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string();
478 let has_lifetime = actual_has_vid.is_some();
479 let lifetime = actual_has_vid.unwrap_or_default();
480
481 let note_2 = if same_self_type {
482 ActualImplExplNotes::ButActuallyImplementsTrait { trait_path, has_lifetime, lifetime }
483 } else if passive_voice {
484 ActualImplExplNotes::ButActuallyImplementedForTy {
485 trait_path,
486 ty,
487 has_lifetime,
488 lifetime,
489 }
490 } else {
491 ActualImplExplNotes::ButActuallyTyImplements { trait_path, ty, has_lifetime, lifetime }
492 };
493
494 ::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]
495 }
496}