1use std::borrow::Cow;
2use std::iter;
3use std::path::PathBuf;
4
5use rustc_errors::codes::*;
6use rustc_errors::{Diag, IntoDiagArg};
7use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
8use rustc_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::intravisit::{self, Visitor};
10use rustc_hir::{
11 self as hir, Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource, PatKind,
12};
13use rustc_middle::hir::nested_filter;
14use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, DerefAdjustKind};
15use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
16use rustc_middle::ty::{
17 self, GenericArg, GenericArgKind, GenericArgsRef, GenericParamDefKind, InferConst,
18 IsSuggestable, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
19 TypeVisitableExt, TypeckResults,
20};
21use rustc_next_trait_solver::solve::TyOrConstInferVar;
22use rustc_span::{BytePos, DUMMY_SP, Ident, Span, bug, sym};
23use tracing::{debug, instrument, warn};
24
25use super::nice_region_error::placeholder_error::Highlighted;
26use crate::diagnostics::{
27 AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, SourceKindSubdiag,
28 SpecifyGenericParamsSuggestion,
29};
30use crate::error_reporting::TypeErrCtxt;
31use crate::infer::InferCtxt;
32
33pub enum TypeAnnotationNeeded {
34 E0282,
38 E0283,
43 E0284,
48}
49
50impl From<TypeAnnotationNeeded> for ErrCode {
51 fn from(val: TypeAnnotationNeeded) -> Self {
52 match val {
53 TypeAnnotationNeeded::E0282 => E0282,
54 TypeAnnotationNeeded::E0283 => E0283,
55 TypeAnnotationNeeded::E0284 => E0284,
56 }
57 }
58}
59
60pub struct InferenceDiagnosticsData {
62 pub name: String,
63 pub span: Option<Span>,
64 pub kind: UnderspecifiedArgKind,
65 pub parent: Option<InferenceDiagnosticsParentData>,
66}
67
68pub struct InferenceDiagnosticsParentData {
70 prefix: &'static str,
71 name: String,
72}
73
74#[derive(#[automatically_derived]
impl ::core::clone::Clone for UnderspecifiedArgKind {
#[inline]
fn clone(&self) -> Self {
match self {
Self::Type { prefix: __self_0 } =>
UnderspecifiedArgKind::Type {
prefix: ::core::clone::Clone::clone(__self_0),
},
Self::Const { is_parameter: __self_0 } =>
UnderspecifiedArgKind::Const {
is_parameter: ::core::clone::Clone::clone(__self_0),
},
}
}
}Clone)]
75pub enum UnderspecifiedArgKind {
76 Type { prefix: Cow<'static, str> },
77 Const { is_parameter: bool },
78}
79
80impl InferenceDiagnosticsData {
81 fn can_add_more_info(&self) -> bool {
82 !(self.name == "_" && #[allow(non_exhaustive_omitted_patterns)] match self.kind {
UnderspecifiedArgKind::Type { .. } => true,
_ => false,
}matches!(self.kind, UnderspecifiedArgKind::Type { .. }))
83 }
84
85 fn where_x_is_kind<'tcx>(&self, infcx: &InferCtxt<'tcx>, in_type: Ty<'tcx>) -> &'static str {
86 if in_type.is_ty_or_numeric_infer() {
87 ""
88 } else if self.name == "_" {
89 let displayed_ty = infcx
90 .deeply_resolve_ignoring_regions(in_type)
91 .fold_with(&mut ClosureEraser { infcx, depth: 0 });
92 if displayed_ty.is_ty_or_numeric_infer() {
93 ""
94 } else {
95 match displayed_ty
96 .walk()
97 .filter_map(TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>)
98 .take(2)
99 .count()
100 {
101 0 => "",
102 1 => "underscore_single",
103 _ => "underscore_multiple",
104 }
105 }
106 } else {
107 "has_name"
108 }
109 }
110
111 fn make_bad_error(&self, span: Span) -> InferenceBadError<'_> {
115 let has_parent = self.parent.is_some();
116 let bad_kind = if self.can_add_more_info() { "more_info" } else { "other" };
117 let (parent_prefix, parent_name) = self
118 .parent
119 .as_ref()
120 .map(|parent| (parent.prefix, parent.name.clone()))
121 .unwrap_or_default();
122 InferenceBadError {
123 span,
124 bad_kind,
125 prefix_kind: self.kind.clone(),
126 prefix: self.kind.try_get_prefix().unwrap_or_default(),
127 name: self.name.clone(),
128 has_parent,
129 parent_prefix,
130 parent_name,
131 }
132 }
133}
134
135impl InferenceDiagnosticsParentData {
136 fn for_parent_def_id(
137 tcx: TyCtxt<'_>,
138 parent_def_id: DefId,
139 ) -> Option<InferenceDiagnosticsParentData> {
140 let parent_name =
141 tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string();
142
143 Some(InferenceDiagnosticsParentData {
144 prefix: tcx.def_descr(parent_def_id),
145 name: parent_name,
146 })
147 }
148
149 fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<InferenceDiagnosticsParentData> {
150 Self::for_parent_def_id(tcx, tcx.parent(def_id))
151 }
152}
153
154impl IntoDiagArg for UnderspecifiedArgKind {
155 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
156 let kind = match self {
157 Self::Type { .. } => "type",
158 Self::Const { is_parameter: true } => "const_with_param",
159 Self::Const { is_parameter: false } => "const",
160 };
161 rustc_errors::DiagArgValue::Str(kind.into())
162 }
163}
164
165impl UnderspecifiedArgKind {
166 fn try_get_prefix(&self) -> Option<&str> {
167 match self {
168 Self::Type { prefix } => Some(prefix.as_ref()),
169 Self::Const { .. } => None,
170 }
171 }
172}
173
174struct ClosureEraser<'a, 'tcx> {
175 infcx: &'a InferCtxt<'tcx>,
176 depth: usize,
177}
178
179impl<'a, 'tcx> ClosureEraser<'a, 'tcx> {
180 fn new_infer(&mut self) -> Ty<'tcx> {
181 self.infcx.next_ty_var(DUMMY_SP)
182 }
183}
184
185impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
186 fn cx(&self) -> TyCtxt<'tcx> {
187 self.infcx.tcx
188 }
189
190 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
191 self.depth += 1;
192 let ty = match ty.kind() {
193 ty::Closure(_, args) => {
194 let closure_sig = args.as_closure().sig();
197 Ty::new_fn_ptr(
198 self.cx(),
199 self.cx().signature_unclosure(closure_sig, hir::Safety::Safe),
200 )
201 }
202 ty::Adt(_, args) if !args.iter().any(|a| a.has_infer()) => {
203 self.new_infer()
208 }
209 ty::Adt(def, args) => {
210 let generics = self.cx().generics_of(def.did());
211 let generics: Vec<bool> = generics
212 .own_params
213 .iter()
214 .map(|param| param.default_value(self.cx()).is_some())
215 .collect();
216 let ty = Ty::new_adt(
217 self.cx(),
218 *def,
219 self.cx().mk_args_from_iter(generics.into_iter().zip(args.iter()).map(
220 |(has_default, arg)| {
221 if arg.has_infer() {
222 arg.fold_with(self)
228 } else if has_default {
229 arg
236 } else if let GenericArgKind::Type(_) = arg.kind() {
237 self.new_infer().into()
239 } else {
240 arg.fold_with(self)
241 }
242 },
243 )),
244 );
245 ty
246 }
247 _ if ty.has_infer() => {
248 ty.super_fold_with(self)
252 }
253 _ if self.depth == 1 => ty.super_fold_with(self),
256 _ => self.new_infer(),
259 };
260 self.depth -= 1;
261 ty
262 }
263
264 fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
265 c
267 }
268}
269
270fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
271 let mut p = FmtPrinter::new(infcx.tcx, ns);
272 let ty_getter = move |ty_vid| {
273 if infcx.try_resolve_ty_var(ty_vid).is_ok() {
274 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:274",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::WARN,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(274u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::WARN <=
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("resolved ty var in error message")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};warn!("resolved ty var in error message");
275 }
276
277 let var_origin = infcx.type_var_origin(ty_vid);
278 if let Some(def_id) = var_origin.param_def_id
279 && infcx.tcx.def_kind(def_id) == DefKind::TyParam
282 && let name = infcx.tcx.item_name(def_id)
283 && !var_origin.span.from_expansion()
284 {
285 let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
286 let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();
287 let generic_param_def = generics.param_at(idx as usize, infcx.tcx);
288 if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind {
289 None
290 } else {
291 Some(name)
292 }
293 } else {
294 None
295 }
296 };
297 p.ty_infer_name_resolver = Some(Box::new(ty_getter));
298 let const_getter =
299 move |ct_vid| Some(infcx.tcx.item_name(infcx.const_var_origin(ct_vid)?.param_def_id?));
300 p.const_infer_name_resolver = Some(Box::new(const_getter));
301 p
302}
303
304fn ty_to_string<'tcx>(
305 infcx: &InferCtxt<'tcx>,
306 ty: Ty<'tcx>,
307 called_method_def_id: Option<DefId>,
308) -> String {
309 let mut p = fmt_printer(infcx, Namespace::TypeNS);
310 let ty = infcx.deeply_resolve_ignoring_regions(ty);
311 let ty = ty.fold_with(&mut ClosureEraser { infcx, depth: 0 });
314
315 match (ty.kind(), called_method_def_id) {
316 (ty::FnDef(..), _) => {
319 ty.fn_sig(infcx.tcx).print(&mut p).unwrap();
320 p.into_buffer()
321 }
322 (_, Some(def_id))
323 if ty.is_ty_or_numeric_infer()
324 && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
325 {
326 "Vec<_>".to_string()
327 }
328 _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
329 _ => {
330 ty.print(&mut p).unwrap();
331 p.into_buffer()
332 }
333 }
334}
335
336fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
340 let ty::Closure(_, args) = ty.kind() else {
341 ::rustc_span::macros::bug_impl(None,
format_args!("cannot convert non-closure to fn str in `closure_as_fn_str`"),
Location::caller())bug!("cannot convert non-closure to fn str in `closure_as_fn_str`")
342 };
343 let fn_sig = args.as_closure().sig();
344 let args = fn_sig
345 .inputs()
346 .skip_binder()
347 .iter()
348 .next()
349 .map(|args| {
350 args.tuple_fields()
351 .iter()
352 .map(|arg| ty_to_string(infcx, arg, None))
353 .collect::<Vec<_>>()
354 .join(", ")
355 })
356 .unwrap_or_default();
357 let ret = if fn_sig.output().skip_binder().is_unit() {
358 String::new()
359 } else {
360 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" -> {0}",
ty_to_string(infcx, fn_sig.output().skip_binder(), None)))
})format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None))
361 };
362 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("fn({0}){1}", args, ret))
})format!("fn({args}){ret}")
363}
364
365impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
366 pub fn extract_inference_diagnostics_data(
369 &self,
370 term: Term<'tcx>,
371 highlight: ty::print::RegionHighlightMode<'tcx>,
372 ) -> InferenceDiagnosticsData {
373 let tcx = self.tcx;
374 match term.kind() {
375 TermKind::Ty(ty) => {
376 if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
377 let var_origin = self.infcx.type_var_origin(ty_vid);
378 if let Some(def_id) = var_origin.param_def_id
379 && self.tcx.def_kind(def_id) == DefKind::TyParam
382 && !var_origin.span.from_expansion()
383 {
384 return InferenceDiagnosticsData {
385 name: self.tcx.item_name(def_id).to_string(),
386 span: Some(var_origin.span),
387 kind: UnderspecifiedArgKind::Type { prefix: "type parameter".into() },
388 parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
389 };
390 }
391 }
392
393 InferenceDiagnosticsData {
394 name: Highlighted { highlight, ns: Namespace::TypeNS, tcx, value: ty }
395 .to_string(),
396 span: None,
397 kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) },
398 parent: None,
399 }
400 }
401 TermKind::Const(ct) => {
402 if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
403 let origin = self.const_var_origin(vid).expect("expected unresolved const var");
404 if let Some(def_id) = origin.param_def_id {
405 return InferenceDiagnosticsData {
406 name: self.tcx.item_name(def_id).to_string(),
407 span: Some(origin.span),
408 kind: UnderspecifiedArgKind::Const { is_parameter: true },
409 parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
410 };
411 }
412
413 if true {
if !!origin.span.is_dummy() {
::core::panicking::panic("assertion failed: !origin.span.is_dummy()")
};
};debug_assert!(!origin.span.is_dummy());
414 InferenceDiagnosticsData {
415 name: Highlighted { highlight, ns: Namespace::ValueNS, tcx, value: ct }
416 .to_string(),
417 span: Some(origin.span),
418 kind: UnderspecifiedArgKind::Const { is_parameter: false },
419 parent: None,
420 }
421 } else {
422 InferenceDiagnosticsData {
429 name: Highlighted { highlight, ns: Namespace::ValueNS, tcx, value: ct }
430 .to_string(),
431 span: None,
432 kind: UnderspecifiedArgKind::Const { is_parameter: false },
433 parent: None,
434 }
435 }
436 }
437 }
438 }
439
440 fn bad_inference_failure_err(
443 &self,
444 span: Span,
445 arg_data: InferenceDiagnosticsData,
446 error_code: TypeAnnotationNeeded,
447 ) -> Diag<'a> {
448 let source_kind = "other";
449 let source_name = "";
450 let failure_span = None;
451 let subdiagnostic = None;
452 let bad_label = Some(arg_data.make_bad_error(span));
453 match error_code {
454 TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
455 span,
456 source_kind,
457 source_name,
458 failure_span,
459 subdiagnostic,
460 bad_label,
461 }),
462 TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
463 span,
464 source_kind,
465 source_name,
466 failure_span,
467 subdiagnostic,
468 bad_label,
469 }),
470 TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
471 span,
472 source_kind,
473 source_name,
474 failure_span,
475 subdiagnostic,
476 bad_label,
477 }),
478 }
479 }
480
481 {}
#[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("emit_inference_failure_err",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(481u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("body_def_id")
}> =
::tracing::__macro_support::FieldName::new("body_def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("failure_span")
}> =
::tracing::__macro_support::FieldName::new("failure_span");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("term")
}> =
::tracing::__macro_support::FieldName::new("term");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("should_label_span")
}> =
::tracing::__macro_support::FieldName::new("should_label_span");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&body_def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&failure_span)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&term)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&should_label_span
as &dyn ::tracing::field::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<'a> = loop {};
return __tracing_attr_fake_return;
}
{
self.emit_inference_failure_err_with_type_hint(body_def_id,
failure_span, term, error_code, should_label_span, None)
}
}
}#[instrument(level = "debug", skip(self, error_code))]
482 pub fn emit_inference_failure_err(
483 &self,
484 body_def_id: LocalDefId,
485 failure_span: Span,
486 term: Term<'tcx>,
487 error_code: TypeAnnotationNeeded,
488 should_label_span: bool,
489 ) -> Diag<'a> {
490 self.emit_inference_failure_err_with_type_hint(
491 body_def_id,
492 failure_span,
493 term,
494 error_code,
495 should_label_span,
496 None,
497 )
498 }
499
500 pub fn emit_inference_failure_err_with_type_hint(
501 &self,
502 body_def_id: LocalDefId,
503 failure_span: Span,
504 term: Term<'tcx>,
505 error_code: TypeAnnotationNeeded,
506 should_label_span: bool,
507 ty: Option<Ty<'tcx>>,
508 ) -> Diag<'a> {
509 let term = self.deeply_resolve_ignoring_regions(term);
510 let arg_data = self
511 .extract_inference_diagnostics_data(term, ty::print::RegionHighlightMode::default());
512
513 let Some(typeck_results) = &self.typeck_results else {
514 return self.bad_inference_failure_err(failure_span, arg_data, error_code);
518 };
519
520 let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty);
521 let mut body_from_expansion = false;
522 if let Some(body) =
523 self.tcx.hir_maybe_body_owned_by(self.tcx.typeck_root_def_id_local(body_def_id))
524 {
525 let expr = body.value;
526 local_visitor.visit_expr(expr);
527 body_from_expansion = body.value.span.from_expansion();
528 }
529
530 let Some(InferSource { span, kind }) = local_visitor.infer_source else {
531 let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id)
532 && let parent = self.tcx.local_parent(body_def_id)
533 && self.tcx.is_automatically_derived(parent.to_def_id())
534 && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent)
535 && let hir::ItemKind::Impl(imp) = item.kind
536 && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind
537 && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res
538 && let Some(def_id) = def_id.as_local()
539 && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(def_id)
540 {
541 item.kind.recovered()
546 } else {
547 false
548 };
549 let mut err = self.bad_inference_failure_err(failure_span, arg_data, error_code);
550 if silence {
551 err.downgrade_to_delayed_bug();
552 }
553 return err;
554 };
555
556 let (source_kind, name, long_ty_path) = kind.ty_localized_msg(self);
557 let failure_span = if should_label_span && !failure_span.overlaps(span) {
558 Some(failure_span)
559 } else {
560 None
561 };
562
563 let subdiagnostic = kind.suggestion(
564 self.tcx,
565 self.infcx,
566 body_def_id,
567 term,
568 &arg_data,
569 typeck_results,
570 body_from_expansion,
571 span,
572 );
573 let delay_as_bug = match kind {
574 InferSourceKind::ClosureArg { kind, .. } if let PatKind::Err(_) = kind => {
575 true
577 }
578 InferSourceKind::GenericArg { hir_id, argument_index, .. }
579 if let hir::Node::PathSegment(segment) = self.tcx.hir_node(hir_id)
580 && let Some(args) = segment.args
581 && let Some(hir::GenericArg::Type(ty)) = args.args.get(argument_index)
582 && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
583 && let Res::Err = path.res =>
584 {
585 true
587 }
588 _ => false,
589 };
590
591 let mut err = match error_code {
592 TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
593 span,
594 source_kind,
595 source_name: &name,
596 failure_span,
597 subdiagnostic,
598 bad_label: None,
599 }),
600 TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
601 span,
602 source_kind,
603 source_name: &name,
604 failure_span,
605 subdiagnostic,
606 bad_label: None,
607 }),
608 TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
609 span,
610 source_kind,
611 source_name: &name,
612 failure_span,
613 subdiagnostic,
614 bad_label: None,
615 }),
616 };
617 *err.long_ty_path() = long_ty_path;
618 if delay_as_bug {
619 err.downgrade_to_delayed_bug();
621 }
622 err
623 }
624}
625
626#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InferSource<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "InferSource",
"span", &self.span, "kind", &&self.kind)
}
}Debug)]
627struct InferSource<'tcx> {
628 span: Span,
629 kind: InferSourceKind<'tcx>,
630}
631
632#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InferSourceKind<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::LetBinding {
insert_span: __self_0,
pattern_name: __self_1,
ty: __self_2,
def_id: __self_3 } =>
::core::fmt::Formatter::debug_struct_field4_finish(f,
"LetBinding", "insert_span", __self_0, "pattern_name",
__self_1, "ty", __self_2, "def_id", &__self_3),
Self::ClosureArg {
insert_span: __self_0, ty: __self_1, kind: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClosureArg", "insert_span", __self_0, "ty", __self_1,
"kind", &__self_2),
Self::GenericArg {
insert_span: __self_0,
argument_index: __self_1,
generics_def_id: __self_2,
def_id: __self_3,
generic_args: __self_4,
have_turbofish: __self_5,
hir_id: __self_6 } => {
let names: &'static _ =
&["insert_span", "argument_index", "generics_def_id",
"def_id", "generic_args", "have_turbofish", "hir_id"];
let values: &[&dyn ::core::fmt::Debug] =
&[__self_0, __self_1, __self_2, __self_3, __self_4,
__self_5, &__self_6];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"GenericArg", names, values)
}
Self::FullyQualifiedMethodCall {
receiver: __self_0,
successor: __self_1,
args: __self_2,
def_id: __self_3 } =>
::core::fmt::Formatter::debug_struct_field4_finish(f,
"FullyQualifiedMethodCall", "receiver", __self_0,
"successor", __self_1, "args", __self_2, "def_id",
&__self_3),
Self::ClosureReturn {
ty: __self_0, data: __self_1, should_wrap_expr: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"ClosureReturn", "ty", __self_0, "data", __self_1,
"should_wrap_expr", &__self_2),
}
}
}Debug)]
633enum InferSourceKind<'tcx> {
634 LetBinding {
635 insert_span: Span,
636 pattern_name: Option<Ident>,
637 ty: Ty<'tcx>,
638 def_id: Option<DefId>,
639 },
640 ClosureArg {
641 insert_span: Span,
642 ty: Ty<'tcx>,
643 kind: PatKind<'tcx>,
644 },
645 GenericArg {
646 insert_span: Span,
647 argument_index: usize,
648 generics_def_id: DefId,
649 def_id: DefId,
650 generic_args: &'tcx [GenericArg<'tcx>],
651 have_turbofish: bool,
652 hir_id: HirId,
653 },
654 FullyQualifiedMethodCall {
655 receiver: &'tcx Expr<'tcx>,
656 successor: (&'static str, BytePos),
659 args: GenericArgsRef<'tcx>,
660 def_id: DefId,
661 },
662 ClosureReturn {
663 ty: Ty<'tcx>,
664 data: &'tcx FnRetTy<'tcx>,
665 should_wrap_expr: Option<Span>,
666 },
667}
668
669impl<'tcx> InferSource<'tcx> {
670 fn from_expansion(&self) -> bool {
671 let source_from_expansion = match self.kind {
672 InferSourceKind::LetBinding { insert_span, .. }
673 | InferSourceKind::ClosureArg { insert_span, .. }
674 | InferSourceKind::GenericArg { insert_span, .. } => insert_span.from_expansion(),
675 InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => {
676 receiver.span.from_expansion()
677 }
678 InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
679 data.span().from_expansion() || should_wrap_expr.is_some_and(Span::from_expansion)
680 }
681 };
682 source_from_expansion || self.span.from_expansion()
683 }
684}
685
686impl<'tcx> InferSourceKind<'tcx> {
687 fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
688 let mut long_ty_path = None;
689 match *self {
690 InferSourceKind::LetBinding { ty, .. }
691 | InferSourceKind::ClosureArg { ty, .. }
692 | InferSourceKind::ClosureReturn { ty, .. } => {
693 if ty.is_closure() {
694 ("closure", closure_as_fn_str(infcx, ty), long_ty_path)
695 } else if ty.is_ty_or_numeric_infer()
696 || ty.is_primitive()
697 || #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Adt(_, args) if args.terms().next().is_none() => true,
_ => false,
}matches!(
698 ty.kind(),
699 ty::Adt(_, args)
700 if args.terms().next().is_none()
701 )
702 {
703 ("other", String::new(), long_ty_path)
707 } else {
708 ("normal", infcx.tcx.short_string(ty, &mut long_ty_path), long_ty_path)
709 }
710 }
711 InferSourceKind::GenericArg { .. }
713 | InferSourceKind::FullyQualifiedMethodCall { .. } => {
714 ("other", String::new(), long_ty_path)
715 }
716 }
717 }
718
719 fn suggestion<'local>(
720 &self,
721 tcx: TyCtxt<'tcx>,
722 infcx: &InferCtxt<'tcx>,
723 body_def_id: LocalDefId,
724 term: Term<'tcx>,
725 arg_data: &'local InferenceDiagnosticsData,
726 typeck_results: &TypeckResults<'tcx>,
727 body_from_expansion: bool,
728 span: Span,
729 ) -> Option<SourceKindSubdiag<'local>>
730 where
731 'tcx: 'local,
732 {
733 let subdiag = match *self {
734 InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => {
735 SourceKindSubdiag::LetLike {
736 span: insert_span,
737 name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
738 x_kind: arg_data.where_x_is_kind(infcx, ty),
739 prefix_kind: arg_data.kind.clone(),
740 prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
741 arg_name: &arg_data.name,
742 kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
743 type_name: ty_to_string(infcx, ty, def_id),
744 }
745 }
746 InferSourceKind::ClosureArg { insert_span, ty, .. } => SourceKindSubdiag::LetLike {
747 span: insert_span,
748 name: String::new(),
749 x_kind: arg_data.where_x_is_kind(infcx, ty),
750 prefix_kind: arg_data.kind.clone(),
751 prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
752 arg_name: &arg_data.name,
753 kind: "closure",
754 type_name: ty_to_string(infcx, ty, None),
755 },
756 InferSourceKind::GenericArg {
757 insert_span,
758 argument_index,
759 generics_def_id,
760 def_id: _,
761 generic_args,
762 have_turbofish,
763 hir_id,
764 } => {
765 let generics = tcx.generics_of(generics_def_id);
766 let is_type = term.as_type().is_some();
767
768 let (parent_exists, parent_prefix, parent_name) =
769 InferenceDiagnosticsParentData::for_parent_def_id(tcx, generics_def_id)
770 .map_or((false, String::new(), String::new()), |parent| {
771 (true, parent.prefix.to_string(), parent.name)
772 });
773
774 let param = &generics.own_params[argument_index];
775 let param_name = param.name.to_string();
776
777 let mut used_fallback = false;
778 let args = if tcx.get_diagnostic_item(sym::iterator_collect_fn)
779 == Some(generics_def_id)
780 {
781 if let hir::Node::Expr(expr) = tcx.parent_hir_node(hir_id)
782 && let hir::ExprKind::Call(expr, _args) = expr.kind
783 && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
784 && let Res::Def(DefKind::AssocFn, def_id) = path.res
785 && let Some(try_trait) = tcx.lang_items().try_trait()
786 && try_trait == tcx.parent(def_id)
787 && let DefKind::Fn | DefKind::AssocFn =
788 tcx.def_kind(body_def_id.to_def_id())
789 && let ret = tcx
790 .fn_sig(body_def_id.to_def_id())
791 .instantiate_identity()
792 .skip_binder()
793 .output()
794 && let ty::Adt(adt, _args) = ret.kind()
795 && let Some(sym::Option | sym::Result) = tcx.get_diagnostic_name(adt.did())
796 {
797 if let Some(sym::Option) = tcx.get_diagnostic_name(adt.did()) {
798 "Option<_>".to_string()
799 } else {
800 "Result<_, _>".to_string()
801 }
802 } else {
803 "Vec<_>".to_string()
804 }
805 } else {
806 let mut p = fmt_printer(infcx, Namespace::TypeNS);
807 p.comma_sep(generic_args.iter().copied().map(|arg| {
808 if arg.is_suggestable(tcx, true) {
809 used_fallback = true;
810 return arg;
811 }
812 match arg.kind() {
813 GenericArgKind::Lifetime(_) => ::rustc_span::macros::bug_impl(None, format_args!("unexpected lifetime"),
Location::caller())bug!("unexpected lifetime"),
814 GenericArgKind::Type(_) => infcx.next_ty_var(DUMMY_SP).into(),
815 GenericArgKind::Const(_) => infcx.next_const_var(DUMMY_SP).into(),
816 }
817 }))
818 .unwrap();
819 p.into_buffer()
820 };
821
822 let suggestion = if have_turbofish || body_from_expansion {
823 None
824 } else if generic_args.len() == 1 && used_fallback {
825 match param.kind {
826 GenericParamDefKind::Type { .. } => {
827 Some(SpecifyGenericParamsSuggestion::GenericTypeSuggestion {
828 span: insert_span,
829 param: param_name.clone(),
830 })
831 }
832 GenericParamDefKind::Const { .. } => {
833 Some(SpecifyGenericParamsSuggestion::ConstGenericSuggestion {
834 span: insert_span,
835 param: param_name.clone(),
836 })
837 }
838 GenericParamDefKind::Lifetime => {
839 ::rustc_span::macros::bug_impl(None, format_args!("unexpected lifetime"),
Location::caller())bug!("unexpected lifetime")
840 }
841 }
842 } else {
843 Some(SpecifyGenericParamsSuggestion::GenericSuggestion {
844 span: insert_span,
845 arg_count: generic_args.len(),
846 args,
847 })
848 };
849
850 SourceKindSubdiag::Generic {
851 span,
852 is_type,
853 param_name,
854 parent_exists,
855 parent_prefix,
856 parent_name,
857 suggestion,
858 }
859 }
860 InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
861 let placeholder = Some(infcx.next_ty_var(DUMMY_SP));
862 let args = args.make_suggestable(tcx, true, placeholder)?;
863
864 let mut p = fmt_printer(infcx, Namespace::ValueNS);
865 p.print_def_path(def_id, args).unwrap();
866 let def_path = p.into_buffer();
867
868 let adjustment = match typeck_results.expr_adjustments(receiver) {
872 [
873 Adjustment { kind: Adjust::Deref(DerefAdjustKind::Builtin), target: _ },
874 ..,
875 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), target: _ },
876 ] => "",
877 [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mut_)), target: _ }] => {
878 hir::Mutability::from(*mut_).ref_prefix_str()
879 }
880 _ => "",
881 };
882
883 SourceKindSubdiag::new_fully_qualified(
884 receiver.span,
885 def_path,
886 adjustment,
887 successor,
888 )
889 }
890 InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
891 let placeholder = Some(infcx.next_ty_var(DUMMY_SP));
892
893 let ty = ty.make_suggestable(tcx, true, placeholder)?;
894 let ty_info = ty_to_string(infcx, ty, None);
895 SourceKindSubdiag::new_closure_return(ty_info, data, should_wrap_expr)
896 }
897 };
898
899 Some(subdiag)
900 }
901}
902
903#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InsertableGenericArgs<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["insert_span", "args", "generics_def_id", "def_id",
"have_turbofish", "hir_id"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.insert_span, &self.args, &self.generics_def_id,
&self.def_id, &self.have_turbofish, &&self.hir_id];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"InsertableGenericArgs", names, values)
}
}Debug)]
904struct InsertableGenericArgs<'tcx> {
905 insert_span: Span,
906 args: GenericArgsRef<'tcx>,
907 generics_def_id: DefId,
908 def_id: DefId,
909 have_turbofish: bool,
910 hir_id: HirId,
911}
912
913struct FindInferSourceVisitor<'a, 'tcx> {
921 tecx: &'a TypeErrCtxt<'a, 'tcx>,
922 typeck_results: &'a TypeckResults<'tcx>,
923
924 target: Term<'tcx>,
925 ty: Option<Ty<'tcx>>,
926
927 attempt: usize,
928 infer_source_cost: usize,
929 infer_source: Option<InferSource<'tcx>>,
930}
931
932impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
933 fn new(
934 tecx: &'a TypeErrCtxt<'a, 'tcx>,
935 typeck_results: &'a TypeckResults<'tcx>,
936 target: Term<'tcx>,
937 ty: Option<Ty<'tcx>>,
938 ) -> Self {
939 FindInferSourceVisitor {
940 tecx,
941 typeck_results,
942
943 target,
944 ty,
945
946 attempt: 0,
947 infer_source_cost: usize::MAX,
948 infer_source: None,
949 }
950 }
951
952 fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
957 #[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for CostCtxt<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for CostCtxt<'tcx> {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for CostCtxt<'tcx> { }Copy)]
958 struct CostCtxt<'tcx> {
959 tcx: TyCtxt<'tcx>,
960 }
961 impl<'tcx> CostCtxt<'tcx> {
962 fn arg_cost(self, arg: GenericArg<'tcx>) -> usize {
963 match arg.kind() {
964 GenericArgKind::Lifetime(_) => 0, GenericArgKind::Type(ty) => self.ty_cost(ty),
966 GenericArgKind::Const(_) => 3, }
968 }
969 fn ty_cost(self, ty: Ty<'tcx>) -> usize {
970 match *ty.kind() {
971 ty::Closure(..) => 1000,
972 ty::FnDef(..) => 150,
973 ty::FnPtr(..) => 30,
974 ty::Adt(def, args) => {
975 5 + self
976 .tcx
977 .generics_of(def.did())
978 .own_args_no_defaults(self.tcx, args)
979 .iter()
980 .map(|&arg| self.arg_cost(arg))
981 .sum::<usize>()
982 }
983 ty::Tuple(args) => 5 + args.iter().map(|arg| self.ty_cost(arg)).sum::<usize>(),
984 ty::Ref(_, ty, _) => 2 + self.ty_cost(ty),
985 ty::Infer(..) => 0,
986 _ => 1,
987 }
988 }
989 }
990
991 let tcx = self.tecx.tcx;
993 let ctx = CostCtxt { tcx };
994 match source.kind {
995 InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
996 InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
997 InferSourceKind::GenericArg { def_id, generic_args, .. } => {
998 let variant_cost = match tcx.def_kind(def_id) {
999 DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15,
1001 _ => 10,
1002 };
1003 variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>()
1004 }
1005 InferSourceKind::FullyQualifiedMethodCall { args, .. } => {
1006 20 + args.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>()
1007 }
1008 InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
1009 30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
1010 }
1011 }
1012 }
1013
1014 {}
#[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("update_infer_source",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1016u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("new_source")
}> =
::tracing::__macro_support::FieldName::new("new_source");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&new_source)
as &dyn ::tracing::field::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: () = loop {};
return __tracing_attr_fake_return;
}
{
if new_source.from_expansion() { return; }
let cost = self.source_cost(&new_source) + self.attempt;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1023",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1023u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("cost")
}> =
::tracing::__macro_support::FieldName::new("cost");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cost)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
self.attempt += 1;
if let Some(InferSource {
kind: InferSourceKind::GenericArg { def_id: did, .. }, .. })
= self.infer_source &&
let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..
} = new_source.kind && ty.is_ty_or_numeric_infer() {
*def_id = Some(did);
}
if cost < self.infer_source_cost {
self.infer_source_cost = cost;
self.infer_source = Some(new_source);
}
}
}
}#[instrument(level = "debug", skip(self))]
1017 fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
1018 if new_source.from_expansion() {
1019 return;
1020 }
1021
1022 let cost = self.source_cost(&new_source) + self.attempt;
1023 debug!(?cost);
1024 self.attempt += 1;
1025 if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, .. }, .. }) =
1026 self.infer_source
1027 && let InferSourceKind::LetBinding { ref ty, ref mut def_id, .. } = new_source.kind
1028 && ty.is_ty_or_numeric_infer()
1029 {
1030 *def_id = Some(did);
1033 }
1034
1035 if cost < self.infer_source_cost {
1036 self.infer_source_cost = cost;
1037 self.infer_source = Some(new_source);
1038 }
1039 }
1040
1041 fn node_args_opt(&self, hir_id: HirId) -> Option<GenericArgsRef<'tcx>> {
1042 let args = self.typeck_results.node_args_opt(hir_id);
1043 self.tecx.deeply_resolve_ignoring_regions(args)
1044 }
1045
1046 fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
1047 let ty = self.typeck_results.node_type_opt(hir_id);
1048 self.tecx.deeply_resolve_ignoring_regions(ty)
1049 }
1050
1051 fn generic_arg_is_target(&self, arg: GenericArg<'tcx>) -> bool {
1054 if arg == self.target.into() {
1055 return true;
1056 }
1057
1058 match (arg.kind(), self.target.kind()) {
1059 (GenericArgKind::Type(inner_ty), TermKind::Ty(target_ty)) => {
1060 use ty::{Infer, TyVar};
1061 match (inner_ty.kind(), target_ty.kind()) {
1062 (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
1063 self.tecx.sub_unification_table_root_var(a_vid)
1064 == self.tecx.sub_unification_table_root_var(b_vid)
1065 }
1066 _ => false,
1067 }
1068 }
1069 (GenericArgKind::Const(inner_ct), TermKind::Const(target_ct)) => {
1070 match (inner_ct.kind(), target_ct.kind()) {
1071 (
1072 ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
1073 ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
1074 ) => self.tecx.root_const_var(a_vid) == self.tecx.root_const_var(b_vid),
1075 _ => false,
1076 }
1077 }
1078 _ => false,
1079 }
1080 }
1081
1082 fn generic_arg_contains_target(&self, arg: GenericArg<'tcx>) -> bool {
1085 let mut walker = arg.walk();
1086 while let Some(inner) = walker.next() {
1087 if self.generic_arg_is_target(inner) {
1088 return true;
1089 }
1090 match inner.kind() {
1091 GenericArgKind::Lifetime(_) => {}
1092 GenericArgKind::Type(ty) => {
1093 if #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }) |
ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) =>
true,
_ => false,
}matches!(
1094 ty.kind(),
1095 ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })
1096 | ty::Closure(..)
1097 | ty::CoroutineClosure(..)
1098 | ty::Coroutine(..)
1099 ) {
1100 walker.skip_current_subtree();
1111 }
1112 }
1113 GenericArgKind::Const(ct) => {
1114 if #[allow(non_exhaustive_omitted_patterns)] match ct.kind() {
ty::ConstKind::Alias(..) => true,
_ => false,
}matches!(ct.kind(), ty::ConstKind::Alias(..)) {
1115 walker.skip_current_subtree();
1118 }
1119 }
1120 }
1121 }
1122 false
1123 }
1124
1125 fn expr_inferred_arg_iter(
1126 &self,
1127 expr: &'tcx hir::Expr<'tcx>,
1128 ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
1129 let tcx = self.tecx.tcx;
1130 match expr.kind {
1131 hir::ExprKind::Path(ref path) => {
1132 if let Some(args) = self.node_args_opt(expr.hir_id) {
1133 return self.path_inferred_arg_iter(expr.hir_id, args, path);
1134 }
1135 }
1136 hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _)
1147 if #[allow(non_exhaustive_omitted_patterns)] match path.res {
Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _) => true,
_ => false,
}matches!(path.res, Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) => {
1154 if let Some(ty) = self.opt_node_type(expr.hir_id)
1155 && let ty::Adt(_, args) = ty.kind()
1156 {
1157 return Box::new(self.resolved_path_inferred_arg_iter(path, args));
1158 }
1159 }
1160 hir::ExprKind::MethodCall(segment, ..) => {
1161 if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
1162 let generics = tcx.generics_of(def_id);
1163 let insertable = try {
1164 if generics.has_impl_trait() {
1165 None?
1166 }
1167 let args = self.node_args_opt(expr.hir_id)?;
1168 let span = tcx.hir_span(segment.hir_id);
1169 let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1170 let have_turbofish = segment.args.is_some_and(|args| {
1171 args.args.iter().any(|arg| arg.is_ty_or_const())
1172 });
1173 InsertableGenericArgs {
1174 insert_span,
1175 args,
1176 generics_def_id: def_id,
1177 def_id,
1178 have_turbofish,
1179 hir_id: expr.hir_id,
1180 }
1181 };
1182 return Box::new(insertable.into_iter());
1183 }
1184 }
1185 _ => {}
1186 }
1187
1188 Box::new(iter::empty())
1189 }
1190
1191 fn resolved_path_inferred_arg_iter(
1192 &self,
1193 path: &'tcx hir::Path<'tcx>,
1194 args: GenericArgsRef<'tcx>,
1195 ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'tcx {
1196 let tcx = self.tecx.tcx;
1197 let have_turbofish = path.segments.iter().any(|segment| {
1198 segment.args.is_some_and(|args| args.args.iter().any(|arg| arg.is_ty_or_const()))
1199 });
1200 let last_segment_using_path_data = try {
1206 let generics_def_id = tcx.res_generics_def_id(path.res)?;
1207 let generics = tcx.generics_of(generics_def_id);
1208 if generics.has_impl_trait() {
1209 do yeet ();
1210 }
1211 let insert_span =
1212 path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
1213 InsertableGenericArgs {
1214 insert_span,
1215 args,
1216 generics_def_id,
1217 def_id: path.res.def_id(),
1218 have_turbofish,
1219 hir_id: path.segments.last().unwrap().hir_id,
1220 }
1221 };
1222
1223 path.segments
1224 .iter()
1225 .filter_map(move |segment| {
1226 let res = segment.res;
1227 let generics_def_id = tcx.res_generics_def_id(res)?;
1228 let generics = tcx.generics_of(generics_def_id);
1229 if generics.has_impl_trait() {
1230 return None;
1231 }
1232 let span = tcx.hir_span(segment.hir_id);
1233 let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1234 Some(InsertableGenericArgs {
1235 insert_span,
1236 args,
1237 generics_def_id,
1238 def_id: res.def_id(),
1239 have_turbofish,
1240 hir_id: segment.hir_id,
1241 })
1242 })
1243 .chain(last_segment_using_path_data)
1244 }
1245
1246 fn path_inferred_arg_iter(
1247 &self,
1248 hir_id: HirId,
1249 args: GenericArgsRef<'tcx>,
1250 qpath: &'tcx hir::QPath<'tcx>,
1251 ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
1252 let tcx = self.tecx.tcx;
1253 match qpath {
1254 hir::QPath::Resolved(_self_ty, path) => {
1255 Box::new(self.resolved_path_inferred_arg_iter(path, args))
1256 }
1257 hir::QPath::TypeRelative(ty, segment) => {
1258 let Some(def_id) = self.typeck_results.type_dependent_def_id(hir_id) else {
1259 return Box::new(iter::empty());
1260 };
1261
1262 let generics = tcx.generics_of(def_id);
1263 let segment = if !segment.infer_args || generics.has_impl_trait() {
1264 None
1265 } else {
1266 let span = tcx.hir_span(segment.hir_id);
1267 let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1268 Some(InsertableGenericArgs {
1269 insert_span,
1270 args,
1271 generics_def_id: def_id,
1272 def_id,
1273 have_turbofish: false,
1274 hir_id: segment.hir_id,
1275 })
1276 };
1277
1278 let parent_def_id = generics.parent.unwrap();
1279 if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) {
1280 let parent_ty =
1281 tcx.type_of(parent_def_id).instantiate(tcx, args).skip_norm_wip();
1282 match (parent_ty.kind(), &ty.kind) {
1283 (
1284 ty::Adt(def, args),
1285 hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
1286 ) => {
1287 if tcx.res_generics_def_id(path.res) != Some(def.did()) {
1288 match path.res {
1289 Res::Def(DefKind::TyAlias, _) => {
1290 }
1297 Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {}
1300 _ => {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1300",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::WARN,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1300u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::WARN <=
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("unexpected path: def={0:?} args={1:?} path={2:?}",
def, args, path) as &dyn ::tracing::field::Value))])
});
} else { ; }
}warn!(
1301 "unexpected path: def={:?} args={:?} path={:?}",
1302 def, args, path,
1303 ),
1304 }
1305 } else {
1306 return Box::new(
1307 self.resolved_path_inferred_arg_iter(path, args).chain(segment),
1308 );
1309 }
1310 }
1311 _ => (),
1312 }
1313 }
1314
1315 Box::new(segment.into_iter())
1316 }
1317 }
1318 }
1319}
1320
1321impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
1322 type NestedFilter = nested_filter::OnlyBodies;
1323
1324 fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
1325 self.tecx.tcx
1326 }
1327
1328 fn visit_local(&mut self, local: &'tcx LetStmt<'tcx>) {
1329 intravisit::walk_local(self, local);
1330
1331 if let Some(mut ty) = self.opt_node_type(local.hir_id) {
1332 if self.generic_arg_contains_target(ty.into()) {
1333 fn get_did(
1334 typeck_results: &TypeckResults<'_>,
1335 expr: &hir::Expr<'_>,
1336 ) -> Option<DefId> {
1337 match expr.kind {
1338 hir::ExprKind::Match(expr, _, hir::MatchSource::TryDesugar(_))
1339 if let hir::ExprKind::Call(_, [expr]) = expr.kind =>
1340 {
1341 get_did(typeck_results, expr)
1342 }
1343 hir::ExprKind::Call(base, _args)
1344 if let hir::ExprKind::Path(path) = base.kind
1345 && let hir::QPath::Resolved(_, path) = path
1346 && let Res::Def(_, did) = path.res =>
1347 {
1348 Some(did)
1349 }
1350 hir::ExprKind::MethodCall(..)
1351 if let Some(did) =
1352 typeck_results.type_dependent_def_id(expr.hir_id) =>
1353 {
1354 Some(did)
1355 }
1356 _ => None,
1357 }
1358 }
1359 if let Some(t) = self.ty
1360 && ty.has_infer()
1361 {
1362 ty = t;
1363 }
1364 if let LocalSource::Normal = local.source
1365 && local.ty.is_none()
1366 {
1367 self.update_infer_source(InferSource {
1368 span: local.pat.span,
1369 kind: InferSourceKind::LetBinding {
1370 insert_span: local.pat.span.shrink_to_hi(),
1371 pattern_name: local.pat.simple_ident(),
1372 ty,
1373 def_id: local.init.and_then(|expr| get_did(self.typeck_results, expr)),
1374 },
1375 });
1376 }
1377 }
1378 }
1379 }
1380
1381 fn visit_body(&mut self, body: &Body<'tcx>) {
1384 for param in body.params {
1385 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1385",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1385u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("param: span {0:?}, ty_span {1:?}, pat.span {2:?}",
param.span, param.ty_span, param.pat.span) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
1386 "param: span {:?}, ty_span {:?}, pat.span {:?}",
1387 param.span, param.ty_span, param.pat.span
1388 );
1389 if param.ty_span != param.pat.span {
1390 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1390",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1390u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&["message"],
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("skipping param: has explicit type")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("skipping param: has explicit type");
1391 continue;
1392 }
1393
1394 let Some(param_ty) = self.opt_node_type(param.hir_id) else { continue };
1395
1396 if self.generic_arg_contains_target(param_ty.into()) {
1397 self.update_infer_source(InferSource {
1398 span: param.pat.span,
1399 kind: InferSourceKind::ClosureArg {
1400 insert_span: param.pat.span.shrink_to_hi(),
1401 ty: param_ty,
1402 kind: param.pat.kind,
1403 },
1404 })
1405 }
1406 }
1407 intravisit::walk_body(self, body);
1408 }
1409
1410 {}
#[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("visit_expr",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1410u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr")
}> =
::tracing::__macro_support::FieldName::new("expr");
NAME.as_str()
}], ::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};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
as &dyn ::tracing::field::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: () = loop {};
return __tracing_attr_fake_return;
}
{
let tcx = self.tecx.tcx;
match expr.kind {
ExprKind::Call(func, args) => {
for arg in args { self.visit_expr(arg); }
self.visit_expr(func);
}
_ => intravisit::walk_expr(self, expr),
}
for args in self.expr_inferred_arg_iter(expr) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1426",
"rustc_trait_selection::error_reporting::infer::need_type_info",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
::tracing_core::__macro_support::Option::Some(1426u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("args")
}> =
::tracing::__macro_support::FieldName::new("args");
NAME.as_str()
}], ::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&args)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let InsertableGenericArgs {
insert_span,
args,
generics_def_id,
def_id,
have_turbofish,
hir_id } = args;
let generics = tcx.generics_of(generics_def_id);
if let Some(argument_index) =
generics.own_args(args).iter().position(|&arg|
self.generic_arg_contains_target(arg)) {
let args = self.tecx.deeply_resolve_ignoring_regions(args);
let generic_args =
&generics.own_args_no_defaults(tcx,
args)[generics.own_counts().lifetimes..];
let span =
match expr.kind {
ExprKind::MethodCall(segment, ..) if
have_turbofish && let Some(hir_args) = segment.args &&
let Some(idx) =
argument_index.checked_sub(generics.own_counts().lifetimes)
&&
let Some(arg) =
hir_args.args.get(hir_args.num_lifetime_args() + idx) => {
arg.span()
}
ExprKind::MethodCall(segment, ..) => segment.ident.span,
_ => expr.span,
};
let mut argument_index = argument_index;
if generics.has_own_self() { argument_index += 1; }
self.update_infer_source(InferSource {
span,
kind: InferSourceKind::GenericArg {
insert_span,
argument_index,
generics_def_id,
def_id,
generic_args,
have_turbofish,
hir_id,
},
});
}
}
if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
if let (&ExprKind::Closure(&Closure {
fn_decl, body, fn_decl_span, .. }), ty::Closure(_, args)) =
(&expr.kind, node_ty.kind()) {
let output = args.as_closure().sig().output().skip_binder();
if self.generic_arg_contains_target(output.into()) {
let body = self.tecx.tcx.hir_body(body);
let should_wrap_expr =
if #[allow(non_exhaustive_omitted_patterns)] match body.value.kind
{
ExprKind::Block(..) => true,
_ => false,
} {
None
} else { Some(body.value.span.shrink_to_hi()) };
self.update_infer_source(InferSource {
span: fn_decl_span,
kind: InferSourceKind::ClosureReturn {
ty: output,
data: &fn_decl.output,
should_wrap_expr,
},
})
}
}
}
let has_impl_trait =
|def_id|
{
iter::successors(Some(tcx.generics_of(def_id)),
|generics|
{
generics.parent.map(|def_id| tcx.generics_of(def_id))
}).any(|generics| generics.has_impl_trait())
};
if let ExprKind::MethodCall(path, receiver, method_args, span) =
expr.kind &&
let Some(args) = self.node_args_opt(expr.hir_id) &&
args.iter().any(|arg| self.generic_arg_contains_target(arg))
&&
let Some(def_id) =
self.typeck_results.type_dependent_def_id(expr.hir_id) &&
self.tecx.tcx.trait_of_assoc(def_id).is_some() &&
!has_impl_trait(def_id) &&
tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
{
let successor =
method_args.get(0).map_or_else(|| (")", span.hi()),
|arg| (", ", arg.span.lo()));
let args = self.tecx.deeply_resolve_ignoring_regions(args);
self.update_infer_source(InferSource {
span: path.ident.span,
kind: InferSourceKind::FullyQualifiedMethodCall {
receiver,
successor,
args,
def_id,
},
})
}
}
}
}#[instrument(level = "debug", skip(self))]
1411 fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
1412 let tcx = self.tecx.tcx;
1413 match expr.kind {
1414 ExprKind::Call(func, args) => {
1417 for arg in args {
1418 self.visit_expr(arg);
1419 }
1420 self.visit_expr(func);
1421 }
1422 _ => intravisit::walk_expr(self, expr),
1423 }
1424
1425 for args in self.expr_inferred_arg_iter(expr) {
1426 debug!(?args);
1427 let InsertableGenericArgs {
1428 insert_span,
1429 args,
1430 generics_def_id,
1431 def_id,
1432 have_turbofish,
1433 hir_id,
1434 } = args;
1435 let generics = tcx.generics_of(generics_def_id);
1436 if let Some(argument_index) = generics
1437 .own_args(args)
1438 .iter()
1439 .position(|&arg| self.generic_arg_contains_target(arg))
1440 {
1441 let args = self.tecx.deeply_resolve_ignoring_regions(args);
1442 let generic_args =
1443 &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..];
1444 let span = match expr.kind {
1445 ExprKind::MethodCall(segment, ..)
1446 if have_turbofish
1447 && let Some(hir_args) = segment.args
1448 && let Some(idx) =
1449 argument_index.checked_sub(generics.own_counts().lifetimes)
1450 && let Some(arg) =
1451 hir_args.args.get(hir_args.num_lifetime_args() + idx) =>
1452 {
1453 arg.span()
1454 }
1455 ExprKind::MethodCall(segment, ..) => segment.ident.span,
1456 _ => expr.span,
1457 };
1458 let mut argument_index = argument_index;
1459 if generics.has_own_self() {
1460 argument_index += 1;
1461 }
1462
1463 self.update_infer_source(InferSource {
1464 span,
1465 kind: InferSourceKind::GenericArg {
1466 insert_span,
1467 argument_index,
1468 generics_def_id,
1469 def_id,
1470 generic_args,
1471 have_turbofish,
1472 hir_id,
1473 },
1474 });
1475 }
1476 }
1477
1478 if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
1479 if let (
1480 &ExprKind::Closure(&Closure { fn_decl, body, fn_decl_span, .. }),
1481 ty::Closure(_, args),
1482 ) = (&expr.kind, node_ty.kind())
1483 {
1484 let output = args.as_closure().sig().output().skip_binder();
1485 if self.generic_arg_contains_target(output.into()) {
1486 let body = self.tecx.tcx.hir_body(body);
1487 let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) {
1488 None
1489 } else {
1490 Some(body.value.span.shrink_to_hi())
1491 };
1492 self.update_infer_source(InferSource {
1493 span: fn_decl_span,
1494 kind: InferSourceKind::ClosureReturn {
1495 ty: output,
1496 data: &fn_decl.output,
1497 should_wrap_expr,
1498 },
1499 })
1500 }
1501 }
1502 }
1503
1504 let has_impl_trait = |def_id| {
1505 iter::successors(Some(tcx.generics_of(def_id)), |generics| {
1506 generics.parent.map(|def_id| tcx.generics_of(def_id))
1507 })
1508 .any(|generics| generics.has_impl_trait())
1509 };
1510 if let ExprKind::MethodCall(path, receiver, method_args, span) = expr.kind
1511 && let Some(args) = self.node_args_opt(expr.hir_id)
1512 && args.iter().any(|arg| self.generic_arg_contains_target(arg))
1513 && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
1514 && self.tecx.tcx.trait_of_assoc(def_id).is_some()
1515 && !has_impl_trait(def_id)
1516 && tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
1519 {
1520 let successor =
1521 method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
1522 let args = self.tecx.deeply_resolve_ignoring_regions(args);
1523 self.update_infer_source(InferSource {
1524 span: path.ident.span,
1525 kind: InferSourceKind::FullyQualifiedMethodCall {
1526 receiver,
1527 successor,
1528 args,
1529 def_id,
1530 },
1531 })
1532 }
1533 }
1534}