1use std::fmt;
2
3use rustc_data_structures::intern::Interned;
4use rustc_errors::{Applicability, Diag, IntoDiagArg};
5use rustc_hir as hir;
6use rustc_hir::def::Namespace;
7use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
8use rustc_middle::bug;
9use rustc_middle::ty::error::ExpectedFound;
10use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
11use rustc_middle::ty::{self, GenericArgsRef, IsSuggestable, RePlaceholder, Region, TyCtxt};
12use tracing::{debug, instrument};
13
14use crate::diagnostics::{
15 ActualImplExpectedKind, ActualImplExpectedLifetimeKind, ActualImplExplNotes,
16 TraitPlaceholderMismatch, TyOrSig,
17};
18use crate::error_reporting::infer::nice_region_error::NiceRegionError;
19use crate::infer::{RegionResolutionError, SubregionOrigin, TypeTrace, ValuePairs};
20use crate::traits::{ObligationCause, ObligationCauseCode};
21
22#[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)]
23pub(crate) struct Highlighted<'tcx, T> {
24 pub tcx: TyCtxt<'tcx>,
25 pub highlight: RegionHighlightMode<'tcx>,
26 pub value: T,
27 pub ns: Namespace,
28}
29
30impl<'tcx, T> IntoDiagArg for Highlighted<'tcx, T>
31where
32 T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
33{
34 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
35 rustc_errors::DiagArgValue::Str(self.to_string().into())
36 }
37}
38
39impl<'tcx, T> Highlighted<'tcx, T> {
40 fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> {
41 Highlighted { tcx: self.tcx, highlight: self.highlight, value: f(self.value), ns: self.ns }
42 }
43}
44
45impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
46where
47 T: for<'a> Print<FmtPrinter<'a, 'tcx>>,
48{
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 let mut p = ty::print::FmtPrinter::new(self.tcx, self.ns);
51 p.region_highlight_mode = self.highlight;
52
53 self.value.print(&mut p)?;
54 f.write_str(&p.into_buffer())
55 }
56}
57
58impl<'tcx> NiceRegionError<'_, 'tcx> {
59 pub(super) fn try_report_placeholder_conflict(&self) -> Option<Diag<'tcx>> {
62 match &self.error {
63 Some(RegionResolutionError::SubSupConflict(
73 vid,
74 _,
75 SubregionOrigin::Subtype(TypeTrace { cause, values }),
76 sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
77 _,
78 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
79 _,
80 )) => self.try_report_trait_placeholder_mismatch(
81 Some(ty::Region::new_var(self.tcx(), *vid)),
82 cause,
83 Some(*sub_placeholder),
84 Some(*sup_placeholder),
85 values,
86 ),
87
88 Some(RegionResolutionError::SubSupConflict(
89 vid,
90 _,
91 SubregionOrigin::Subtype(TypeTrace { cause, values }),
92 sub_placeholder @ Region(Interned(RePlaceholder(_), _)),
93 _,
94 _,
95 _,
96 )) => self.try_report_trait_placeholder_mismatch(
97 Some(ty::Region::new_var(self.tcx(), *vid)),
98 cause,
99 Some(*sub_placeholder),
100 None,
101 values,
102 ),
103
104 Some(RegionResolutionError::SubSupConflict(
105 vid,
106 _,
107 SubregionOrigin::Subtype(TypeTrace { cause, values }),
108 _,
109 _,
110 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
111 _,
112 )) => self.try_report_trait_placeholder_mismatch(
113 Some(ty::Region::new_var(self.tcx(), *vid)),
114 cause,
115 None,
116 Some(*sup_placeholder),
117 values,
118 ),
119
120 Some(RegionResolutionError::SubSupConflict(
121 vid,
122 _,
123 _,
124 _,
125 SubregionOrigin::Subtype(TypeTrace { cause, values }),
126 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
127 _,
128 )) => self.try_report_trait_placeholder_mismatch(
129 Some(ty::Region::new_var(self.tcx(), *vid)),
130 cause,
131 None,
132 Some(*sup_placeholder),
133 values,
134 ),
135
136 Some(RegionResolutionError::UpperBoundUniverseConflict(
137 vid,
138 _,
139 _,
140 SubregionOrigin::Subtype(TypeTrace { cause, values }),
141 sup_placeholder @ Region(Interned(RePlaceholder(_), _)),
142 )) => self.try_report_trait_placeholder_mismatch(
143 Some(ty::Region::new_var(self.tcx(), *vid)),
144 cause,
145 None,
146 Some(*sup_placeholder),
147 values,
148 ),
149
150 Some(RegionResolutionError::ConcreteFailure(
151 SubregionOrigin::Subtype(TypeTrace { cause, values }),
152 sub_region @ Region(Interned(RePlaceholder(_), _)),
153 sup_region @ Region(Interned(RePlaceholder(_), _)),
154 )) => self.try_report_trait_placeholder_mismatch(
155 None,
156 cause,
157 Some(*sub_region),
158 Some(*sup_region),
159 values,
160 ),
161
162 Some(RegionResolutionError::ConcreteFailure(
163 SubregionOrigin::Subtype(TypeTrace { cause, values }),
164 sub_region @ Region(Interned(RePlaceholder(_), _)),
165 sup_region,
166 )) => self.try_report_trait_placeholder_mismatch(
167 (!sup_region.is_named(self.tcx())).then_some(*sup_region),
168 cause,
169 Some(*sub_region),
170 None,
171 values,
172 ),
173
174 Some(RegionResolutionError::ConcreteFailure(
175 SubregionOrigin::Subtype(TypeTrace { cause, values }),
176 sub_region,
177 sup_region @ Region(Interned(RePlaceholder(_), _)),
178 )) => self.try_report_trait_placeholder_mismatch(
179 (!sub_region.is_named(self.tcx())).then_some(*sub_region),
180 cause,
181 None,
182 Some(*sup_region),
183 values,
184 ),
185
186 _ => None,
187 }
188 }
189
190 fn try_report_trait_placeholder_mismatch(
191 &self,
192 vid: Option<Region<'tcx>>,
193 cause: &ObligationCause<'tcx>,
194 sub_placeholder: Option<Region<'tcx>>,
195 sup_placeholder: Option<Region<'tcx>>,
196 value_pairs: &ValuePairs<'tcx>,
197 ) -> Option<Diag<'tcx>> {
198 let (expected_args, found_args, trait_def_id) = match value_pairs {
199 ValuePairs::TraitRefs(ExpectedFound { expected, found })
200 if expected.def_id == found.def_id =>
201 {
202 (expected.args, found.args, expected.def_id)
206 }
207 _ => return None,
208 };
209
210 Some(self.report_trait_placeholder_mismatch(
211 vid,
212 cause,
213 sub_placeholder,
214 sup_placeholder,
215 trait_def_id,
216 expected_args,
217 found_args,
218 ))
219 }
220
221 #[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(230u32),
::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:313",
"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(313u32),
::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))
}));
}
}
if self.tcx().is_fn_trait(trait_def_id) {
let actual_self_ty =
self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(self.cx.tcx,
trait_def_id, actual_args).self_ty());
if let ty::Closure(closure_def_id, _) = *actual_self_ty.kind()
&& let Some(local_def_id) = closure_def_id.as_local() &&
let hir::Node::Expr(hir::Expr {
kind: hir::ExprKind::Closure(closure), .. }) =
self.tcx().hir_node_by_def_id(local_def_id) {
let body = self.tcx().hir_body(closure.body);
let expected_input_tys = expected_args.type_at(1);
if let ty::Tuple(input_tys) = *expected_input_tys.kind() {
let suggestions: Vec<_> =
body.params.iter().zip(input_tys.iter()).filter_map(|(param,
ty)|
{
if param.ty_span == param.pat.span &&
ty.is_suggestable(self.tcx(), false) {
Some((param.pat.span.shrink_to_hi(),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!(": {0}", ty))
})))
} else { None }
}).collect();
if !suggestions.is_empty() {
let msg =
if suggestions.len() == 1 {
"consider adding an explicit type annotation to the closure's argument"
} else {
"consider adding explicit type annotations to the closure's arguments"
};
err.multipart_suggestion(msg, suggestions,
Applicability::MaybeIncorrect);
}
}
}
}
err
}
}
}#[instrument(level = "debug", skip(self))]
231 fn report_trait_placeholder_mismatch(
232 &self,
233 vid: Option<Region<'tcx>>,
234 cause: &ObligationCause<'tcx>,
235 sub_placeholder: Option<Region<'tcx>>,
236 sup_placeholder: Option<Region<'tcx>>,
237 trait_def_id: DefId,
238 expected_args: GenericArgsRef<'tcx>,
239 actual_args: GenericArgsRef<'tcx>,
240 ) -> Diag<'tcx> {
241 let span = cause.span;
242
243 let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) =
244 if let ObligationCauseCode::WhereClause(def_id, span)
245 | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code()
246 && def_id != CRATE_DEF_ID.to_def_id()
247 {
248 (
249 true,
250 Some(span),
251 Some(self.tcx().def_span(def_id)),
252 None,
253 self.tcx().def_path_str(def_id),
254 )
255 } else {
256 (false, None, None, Some(span), String::new())
257 };
258
259 let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
260 self.cx.tcx,
261 trait_def_id,
262 expected_args,
263 ));
264 let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new_from_args(
265 self.cx.tcx,
266 trait_def_id,
267 actual_args,
268 ));
269
270 let mut counter = 0;
277 let mut has_sub = None;
278 let mut has_sup = None;
279
280 let mut actual_has_vid = None;
281 let mut expected_has_vid = None;
282
283 self.tcx().for_each_free_region(&expected_trait_ref, |r| {
284 if Some(r) == sub_placeholder && has_sub.is_none() {
285 has_sub = Some(counter);
286 counter += 1;
287 } else if Some(r) == sup_placeholder && has_sup.is_none() {
288 has_sup = Some(counter);
289 counter += 1;
290 }
291
292 if Some(r) == vid && expected_has_vid.is_none() {
293 expected_has_vid = Some(counter);
294 counter += 1;
295 }
296 });
297
298 self.tcx().for_each_free_region(&actual_trait_ref, |r| {
299 if Some(r) == vid && actual_has_vid.is_none() {
300 actual_has_vid = Some(counter);
301 counter += 1;
302 }
303 });
304
305 let actual_self_ty_has_vid =
306 self.tcx().any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid);
307
308 let expected_self_ty_has_vid =
309 self.tcx().any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid);
310
311 let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
312
313 debug!(
314 ?actual_has_vid,
315 ?expected_has_vid,
316 ?has_sub,
317 ?has_sup,
318 ?actual_self_ty_has_vid,
319 ?expected_self_ty_has_vid,
320 );
321
322 let actual_impl_expl_notes = self.explain_actual_impl_that_was_found(
323 sub_placeholder,
324 sup_placeholder,
325 has_sub,
326 has_sup,
327 expected_trait_ref,
328 actual_trait_ref,
329 vid,
330 expected_has_vid,
331 actual_has_vid,
332 any_self_ty_has_vid,
333 leading_ellipsis,
334 );
335
336 let mut err = self.tcx().dcx().create_err(TraitPlaceholderMismatch {
337 span,
338 satisfy_span,
339 where_span,
340 dup_span,
341 def_id,
342 trait_def_id: self.tcx().def_path_str(trait_def_id),
343 actual_impl_expl_notes,
344 });
345
346 let mut current_code = cause.code();
347 let mut coroutine_def_id = None;
348
349 loop {
350 match current_code {
351 ObligationCauseCode::MatchImpl(inner_cause, _) => {
352 current_code = inner_cause.code();
353 }
354 ObligationCauseCode::BuiltinDerived(derived) => {
355 let self_ty = derived.parent_trait_pred.skip_binder().self_ty();
356
357 if let ty::Coroutine(def_id, _) | ty::CoroutineWitness(def_id, _) =
358 self_ty.kind()
359 {
360 coroutine_def_id = Some(*def_id);
361 break;
362 }
363
364 current_code = &derived.parent_code;
365 }
366 _ => break,
367 }
368 }
369
370 if let Some(def_id) = coroutine_def_id {
371 if self.tcx().trait_is_auto(trait_def_id) {
372 let c_span = self.tcx().def_span(def_id);
373 let descr = self.tcx().def_descr(def_id);
374 let trait_name = self.tcx().def_path_str(trait_def_id);
375
376 err.span_label(
377 c_span,
378 format!("this {descr} captures a value whose type is not `{trait_name}`"),
379 );
380 }
381 }
382
383 if self.tcx().is_fn_trait(trait_def_id) {
388 let actual_self_ty = self.cx.resolve_vars_if_possible(
389 ty::TraitRef::new_from_args(self.cx.tcx, trait_def_id, actual_args).self_ty(),
390 );
391 if let ty::Closure(closure_def_id, _) = *actual_self_ty.kind()
392 && let Some(local_def_id) = closure_def_id.as_local()
393 && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(closure), .. }) =
394 self.tcx().hir_node_by_def_id(local_def_id)
395 {
396 let body = self.tcx().hir_body(closure.body);
397 let expected_input_tys = expected_args.type_at(1);
399 if let ty::Tuple(input_tys) = *expected_input_tys.kind() {
400 let suggestions: Vec<_> = body
401 .params
402 .iter()
403 .zip(input_tys.iter())
404 .filter_map(|(param, ty)| {
405 if param.ty_span == param.pat.span
407 && ty.is_suggestable(self.tcx(), false)
408 {
409 Some((param.pat.span.shrink_to_hi(), format!(": {ty}")))
410 } else {
411 None
412 }
413 })
414 .collect();
415 if !suggestions.is_empty() {
416 let msg = if suggestions.len() == 1 {
417 "consider adding an explicit type annotation to the closure's argument"
418 } else {
419 "consider adding explicit type annotations to the closure's arguments"
420 };
421 err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect);
422 }
423 }
424 }
425 }
426
427 err
428 }
429
430 fn explain_actual_impl_that_was_found(
436 &self,
437 sub_placeholder: Option<Region<'tcx>>,
438 sup_placeholder: Option<Region<'tcx>>,
439 has_sub: Option<usize>,
440 has_sup: Option<usize>,
441 expected_trait_ref: ty::TraitRef<'tcx>,
442 actual_trait_ref: ty::TraitRef<'tcx>,
443 vid: Option<Region<'tcx>>,
444 expected_has_vid: Option<usize>,
445 actual_has_vid: Option<usize>,
446 any_self_ty_has_vid: bool,
447 leading_ellipsis: bool,
448 ) -> Vec<ActualImplExplNotes<'tcx>> {
449 let highlight_trait_ref = |trait_ref| Highlighted {
465 tcx: self.tcx(),
466 highlight: RegionHighlightMode::default(),
467 value: trait_ref,
468 ns: Namespace::TypeNS,
469 };
470
471 let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
472
473 let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
474 expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
475 expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
476
477 let passive_voice = match (has_sub, has_sup) {
478 (Some(_), _) | (_, Some(_)) => any_self_ty_has_vid,
479 (None, None) => {
480 expected_trait_ref.highlight.maybe_highlighting_region(vid, expected_has_vid);
481 match expected_has_vid {
482 Some(_) => true,
483 None => any_self_ty_has_vid,
484 }
485 }
486 };
487
488 let (kind, ty_or_sig, trait_path) = if same_self_type {
489 let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
490 self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
491
492 if self_ty.value.is_closure() && self.tcx().is_fn_trait(expected_trait_ref.value.def_id)
493 {
494 let closure_sig = self_ty.map(|closure| {
495 if let ty::Closure(_, args) = closure.kind() {
496 self.tcx()
497 .signature_unclosure(args.as_closure().sig(), rustc_hir::Safety::Safe)
498 } else {
499 ::rustc_middle::util::bug::bug_fmt(format_args!("type is not longer closure"));bug!("type is not longer closure");
500 }
501 });
502 (
503 ActualImplExpectedKind::Signature,
504 TyOrSig::ClosureSig(closure_sig),
505 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
506 )
507 } else {
508 (
509 ActualImplExpectedKind::Other,
510 TyOrSig::Ty(self_ty),
511 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
512 )
513 }
514 } else if passive_voice {
515 (
516 ActualImplExpectedKind::Passive,
517 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
518 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
519 )
520 } else {
521 (
522 ActualImplExpectedKind::Other,
523 TyOrSig::Ty(expected_trait_ref.map(|tr| tr.self_ty())),
524 expected_trait_ref.map(|tr| tr.print_only_trait_path()),
525 )
526 };
527
528 let (lt_kind, lifetime_1, lifetime_2) = match (has_sub, has_sup) {
529 (Some(n1), Some(n2)) => {
530 (ActualImplExpectedLifetimeKind::Two, std::cmp::min(n1, n2), std::cmp::max(n1, n2))
531 }
532 (Some(n), _) | (_, Some(n)) => (ActualImplExpectedLifetimeKind::Any, n, 0),
533 (None, None) => {
534 if let Some(n) = expected_has_vid {
535 (ActualImplExpectedLifetimeKind::Some, n, 0)
536 } else {
537 (ActualImplExpectedLifetimeKind::Nothing, 0, 0)
538 }
539 }
540 };
541
542 let note_1 = ActualImplExplNotes::new_expected(
543 kind,
544 lt_kind,
545 leading_ellipsis,
546 ty_or_sig,
547 trait_path,
548 lifetime_1,
549 lifetime_2,
550 );
551
552 let mut actual_trait_ref = highlight_trait_ref(actual_trait_ref);
553 actual_trait_ref.highlight.maybe_highlighting_region(vid, actual_has_vid);
554
555 let passive_voice = match actual_has_vid {
556 Some(_) => any_self_ty_has_vid,
557 None => true,
558 };
559
560 let trait_path = actual_trait_ref.map(|tr| tr.print_only_trait_path());
561 let ty = actual_trait_ref.map(|tr| tr.self_ty()).to_string();
562 let has_lifetime = actual_has_vid.is_some();
563 let lifetime = actual_has_vid.unwrap_or_default();
564
565 let note_2 = if same_self_type {
566 ActualImplExplNotes::ButActuallyImplementsTrait { trait_path, has_lifetime, lifetime }
567 } else if passive_voice {
568 ActualImplExplNotes::ButActuallyImplementedForTy {
569 trait_path,
570 ty,
571 has_lifetime,
572 lifetime,
573 }
574 } else {
575 ActualImplExplNotes::ButActuallyTyImplements { trait_path, ty, has_lifetime, lifetime }
576 };
577
578 ::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]
579 }
580}