diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
commit | d1b2d29528b7794b41e66fc2136e395a02f8529b (patch) | |
tree | a4a17504b260206dec3cf55b2dca82929a348ac2 /compiler/rustc_infer/src/infer/error_reporting | |
parent | Releasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip |
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer/src/infer/error_reporting')
10 files changed, 399 insertions, 327 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b826ced04..ac5468f3d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -238,7 +238,7 @@ fn msg_span_from_named_region<'tcx>( let text = if name == kw::UnderscoreLifetime { "the anonymous lifetime as defined here".to_string() } else { - format!("the lifetime `{}` as defined here", name) + format!("the lifetime `{name}` as defined here") }; (text, Some(span)) } @@ -250,7 +250,7 @@ fn msg_span_from_named_region<'tcx>( }) ), _ => ( - format!("the lifetime `{}` as defined here", region), + format!("the lifetime `{region}` as defined here"), Some(tcx.def_span(scope)), ), } @@ -264,11 +264,11 @@ fn msg_span_from_named_region<'tcx>( ty::RePlaceholder(ty::PlaceholderRegion { bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. }, .. - }) => (format!("the anonymous lifetime defined here"), Some(span)), + }) => ("the anonymous lifetime defined here".to_owned(), Some(span)), ty::RePlaceholder(ty::PlaceholderRegion { bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. }, .. - }) => (format!("an anonymous lifetime"), None), + }) => ("an anonymous lifetime".to_owned(), None), _ => bug!("{:?}", region), } } @@ -280,7 +280,7 @@ fn emit_msg_span( span: Option<Span>, suffix: &str, ) { - let message = format!("{}{}{}", prefix, description, suffix); + let message = format!("{prefix}{description}{suffix}"); if let Some(span) = span { err.span_note(span, message); @@ -296,7 +296,7 @@ fn label_msg_span( span: Option<Span>, suffix: &str, ) { - let message = format!("{}{}{}", prefix, description, suffix); + let message = format!("{prefix}{description}{suffix}"); if let Some(span) = span { err.span_label(span, message); @@ -315,7 +315,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let mut err = tcx.sess.create_err(errors::OpaqueCapturesLifetime { span, - opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.substs), + opaque_ty: Ty::new_opaque(tcx, opaque_ty_key.def_id.to_def_id(), opaque_ty_key.args), opaque_ty_span: tcx.def_span(opaque_ty_key.def_id), }); @@ -333,7 +333,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( explain_free_region( tcx, &mut err, - &format!("hidden type `{}` captures ", hidden_ty), + &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", ); @@ -345,12 +345,21 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( fn_returns, hidden_region.to_string(), None, - format!("captures `{}`", hidden_region), + format!("captures `{hidden_region}`"), None, Some(reg_info.def_id), ) } } + ty::RePlaceholder(_) => { + explain_free_region( + tcx, + &mut err, + &format!("hidden type `{}` captures ", hidden_ty), + hidden_region, + "", + ); + } ty::ReError(_) => { err.delay_as_bug(); } @@ -373,7 +382,7 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( note_and_explain_region( tcx, &mut err, - &format!("hidden type `{}` captures ", hidden_ty), + &format!("hidden type `{hidden_ty}` captures "), hidden_region, "", None, @@ -386,16 +395,16 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( impl<'tcx> InferCtxt<'tcx> { pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> { - let (def_id, substs) = match *ty.kind() { - ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + let (def_id, args) = match *ty.kind() { + ty::Alias(_, ty::AliasTy { def_id, args, .. }) if matches!(self.tcx.def_kind(def_id), DefKind::OpaqueTy) => { - (def_id, substs) + (def_id, args) } - ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + ty::Alias(_, ty::AliasTy { def_id, args, .. }) if self.tcx.is_impl_trait_in_trait(def_id) => { - (def_id, substs) + (def_id, args) } _ => return None, }; @@ -403,7 +412,7 @@ impl<'tcx> InferCtxt<'tcx> { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( + self.tcx.explicit_item_bounds(def_id).iter_instantiated_copied(self.tcx, args).find_map( |(predicate, _)| { predicate .kind() @@ -573,7 +582,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { use hir::def_id::CrateNum; use rustc_hir::definitions::DisambiguatedDefPathData; use ty::print::Printer; - use ty::subst::GenericArg; + use ty::GenericArg; struct AbsolutePathPrinter<'tcx> { tcx: TyCtxt<'tcx>, @@ -711,12 +720,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { // don't show type `_` if span.desugaring_kind() == Some(DesugaringKind::ForLoop) - && let ty::Adt(def, substs) = ty.kind() + && let ty::Adt(def, args) = ty.kind() && Some(def.did()) == self.tcx.get_diagnostic_item(sym::Option) { - err.span_label(span, format!("this is an iterator with items of type `{}`", substs.type_at(0))); + err.span_label(span, format!("this is an iterator with items of type `{}`", args.type_at(0))); } else { - err.span_label(span, format!("this expression has type `{}`", ty)); + err.span_label(span, format!("this expression has type `{ty}`")); } } if let Some(ty::error::ExpectedFound { found, .. }) = exp_found @@ -726,7 +735,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.span_suggestion( span, "consider dereferencing the boxed value", - format!("*{}", snippet), + format!("*{snippet}"), Applicability::MachineApplicable, ); } @@ -734,6 +743,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => { err.span_label(span, "expected due to this"); } + ObligationCauseCode::BlockTailExpression( + _, + hir::MatchSource::TryDesugar(scrut_hir_id), + ) => { + if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { + let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); + let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { + let arg_expr = args.first().expect("try desugaring call w/out arg"); + self.typeck_results.as_ref().and_then(|typeck_results| { + typeck_results.expr_ty_opt(arg_expr) + }) + } else { + bug!("try desugaring w/out call expr as scrutinee"); + }; + + match scrut_ty { + Some(ty) if expected == ty => { + let source_map = self.tcx.sess.source_map(); + err.span_suggestion( + source_map.end_point(cause.span()), + "try removing this `?`", + "", + Applicability::MachineApplicable, + ); + } + _ => {} + } + } + }, ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { arm_block_id, arm_span, @@ -743,12 +781,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { prior_arm_ty, source, ref prior_arms, - scrut_hir_id, opt_suggest_box_span, scrut_span, .. }) => match source { - hir::MatchSource::TryDesugar => { + hir::MatchSource::TryDesugar(scrut_hir_id) => { if let Some(ty::error::ExpectedFound { expected, .. }) = exp_found { let scrut_expr = self.tcx.hir().expect_expr(scrut_hir_id); let scrut_ty = if let hir::ExprKind::Call(_, args) = &scrut_expr.kind { @@ -764,7 +801,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Some(ty) if expected == ty => { let source_map = self.tcx.sess.source_map(); err.span_suggestion( - source_map.end_point(cause.span), + source_map.end_point(cause.span()), "try removing this `?`", "", Applicability::MachineApplicable, @@ -785,13 +822,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if prior_arms.len() <= 4 { for sp in prior_arms { any_multiline_arm |= source_map.is_multiline(*sp); - err.span_label(*sp, format!("this is found to be of type `{}`", t)); + err.span_label(*sp, format!("this is found to be of type `{t}`")); } } else if let Some(sp) = prior_arms.last() { any_multiline_arm |= source_map.is_multiline(*sp); err.span_label( *sp, - format!("this and all prior arms are found to be of type `{}`", t), + format!("this and all prior arms are found to be of type `{t}`"), ); } let outer = if any_multiline_arm || !source_map.is_multiline(cause.span) { @@ -908,7 +945,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { value: &mut DiagnosticStyledString, other_value: &mut DiagnosticStyledString, name: String, - sub: ty::subst::SubstsRef<'tcx>, + sub: ty::GenericArgsRef<'tcx>, pos: usize, other_ty: Ty<'tcx>, ) { @@ -986,9 +1023,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { other_path: String, other_ty: Ty<'tcx>, ) -> Option<()> { - // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods, + // FIXME/HACK: Go back to `GenericArgsRef` to use its inherent methods, // ideally that shouldn't be necessary. - let sub = self.tcx.mk_substs(sub); + let sub = self.tcx.mk_args(sub); for (i, ta) in sub.types().enumerate() { if ta == other_ty { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty); @@ -1180,9 +1217,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let did1 = def1.did(); let did2 = def2.did(); let sub_no_defaults_1 = - self.tcx.generics_of(did1).own_substs_no_defaults(self.tcx, sub1); + self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1); let sub_no_defaults_2 = - self.tcx.generics_of(did2).own_substs_no_defaults(self.tcx, sub2); + self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2); let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new()); let path1 = self.tcx.def_path_str(did1); let path2 = self.tcx.def_path_str(did2); @@ -1403,11 +1440,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } // When encountering tuples of the same size, highlight only the differing types - (&ty::Tuple(substs1), &ty::Tuple(substs2)) if substs1.len() == substs2.len() => { + (&ty::Tuple(args1), &ty::Tuple(args2)) if args1.len() == args2.len() => { let mut values = (DiagnosticStyledString::normal("("), DiagnosticStyledString::normal("(")); - let len = substs1.len(); - for (i, (left, right)) in substs1.iter().zip(substs2).enumerate() { + let len = args1.len(); + for (i, (left, right)) in args1.iter().zip(args2).enumerate() { let (x1, x2) = self.cmp(left, right); (values.0).0.extend(x1.0); (values.1).0.extend(x2.0); @@ -1423,35 +1460,34 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { values } - (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { - let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); - let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); + (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => { + let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1); + let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2); let mut values = self.cmp_fn_sig(&sig1, &sig2); - let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did1, substs1)); - let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_substs(*did2, substs2)); + let path1 = format!(" {{{}}}", self.tcx.def_path_str_with_args(*did1, args1)); + let path2 = format!(" {{{}}}", self.tcx.def_path_str_with_args(*did2, args2)); let same_path = path1 == path2; values.0.push(path1, !same_path); values.1.push(path2, !same_path); values } - (ty::FnDef(did1, substs1), ty::FnPtr(sig2)) => { - let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1); + (ty::FnDef(did1, args1), ty::FnPtr(sig2)) => { + let sig1 = self.tcx.fn_sig(*did1).instantiate(self.tcx, args1); let mut values = self.cmp_fn_sig(&sig1, sig2); values.0.push_highlighted(format!( " {{{}}}", - self.tcx.def_path_str_with_substs(*did1, substs1) + self.tcx.def_path_str_with_args(*did1, args1) )); values } - (ty::FnPtr(sig1), ty::FnDef(did2, substs2)) => { - let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2); + (ty::FnPtr(sig1), ty::FnDef(did2, args2)) => { + let sig2 = self.tcx.fn_sig(*did2).instantiate(self.tcx, args2); let mut values = self.cmp_fn_sig(sig1, &sig2); - values.1.push_normal(format!( - " {{{}}}", - self.tcx.def_path_str_with_substs(*did2, substs2) - )); + values + .1 + .push_normal(format!(" {{{}}}", self.tcx.def_path_str_with_args(*did2, args2))); values } @@ -1636,6 +1672,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id))) } ValuePairs::Regions(_) => (false, Mismatch::Fixed("lifetime")), + ValuePairs::ExistentialTraitRef(_) => { + (false, Mismatch::Fixed("existential trait ref")) + } + ValuePairs::ExistentialProjection(_) => { + (false, Mismatch::Fixed("existential projection")) + } }; let Some(vals) = self.values_str(values) else { // Derived error. Cancel the emitter. @@ -1662,7 +1704,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .. })) = values { - Cow::from(format!("expected this to be `{}`", expected)) + Cow::from(format!("expected this to be `{expected}`")) } else { terr.to_string(self.tcx) }; @@ -1913,7 +1955,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { true }; - if should_suggest_fixes { + // FIXME(#73154): For now, we do leak check when coercing function + // pointers in typeck, instead of only during borrowck. This can lead + // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful. + if should_suggest_fixes + && !matches!(terr, TypeError::RegionsInsufficientlyPolymorphic(..)) + { self.suggest_tuple_pattern(cause, &exp_found, diag); self.suggest_accessing_field_where_appropriate(cause, &exp_found, diag); self.suggest_await_on_expect_found(cause, span, &exp_found, diag); @@ -1959,7 +2006,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { trace: &TypeTrace<'tcx>, terr: TypeError<'tcx>, ) -> Vec<TypeErrorAdditionalDiags> { - use crate::traits::ObligationCauseCode::MatchExpressionArm; + use crate::traits::ObligationCauseCode::{BlockTailExpression, MatchExpressionArm}; let mut suggestions = Vec::new(); let span = trace.cause.span(); let values = self.resolve_vars_if_possible(trace.values); @@ -1977,11 +2024,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // specify a byte literal (ty::Uint(ty::UintTy::U8), ty::Char) => { if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) - && let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\'')) - && !code.starts_with("\\u") // forbid all Unicode escapes - && code.chars().next().is_some_and(|c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII + && let Some(code) = + code.strip_prefix('\'').and_then(|s| s.strip_suffix('\'')) + // forbid all Unicode escapes + && !code.starts_with("\\u") + // forbids literal Unicode characters beyond ASCII + && code.chars().next().is_some_and(|c| c.is_ascii()) { - suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { span, code: escape_literal(code) }) + suggestions.push(TypeErrorAdditionalDiags::MeantByteLiteral { + span, + code: escape_literal(code), + }) } } // If a character was expected and the found expression is a string literal @@ -1992,7 +2045,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"')) && code.chars().count() == 1 { - suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral { span, code: escape_literal(code) }) + suggestions.push(TypeErrorAdditionalDiags::MeantCharLiteral { + span, + code: escape_literal(code), + }) } } // If a string was expected and the found expression is a character literal, @@ -2002,7 +2058,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\'')) { - suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral { span, code: escape_literal(code) }) + suggestions.push(TypeErrorAdditionalDiags::MeantStrLiteral { + span, + code: escape_literal(code), + }) } } } @@ -2011,17 +2070,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (ty::Bool, ty::Tuple(list)) => if list.len() == 0 { suggestions.extend(self.suggest_let_for_letchains(&trace.cause, span)); } - (ty::Array(_, _), ty::Array(_, _)) => suggestions.extend(self.suggest_specify_actual_length(terr, trace, span)), + (ty::Array(_, _), ty::Array(_, _)) => { + suggestions.extend(self.suggest_specify_actual_length(terr, trace, span)) + } _ => {} } } let code = trace.cause.code(); - if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code - && let hir::MatchSource::TryDesugar = source - && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values) - { - suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { found: found_ty.content(), expected: expected_ty.content() }); - } + if let &(MatchExpressionArm(box MatchExpressionArmCause { source, .. }) + | BlockTailExpression(.., source) + ) = code + && let hir::MatchSource::TryDesugar(_) = source + && let Some((expected_ty, found_ty, _, _)) = self.values_str(trace.values) + { + suggestions.push(TypeErrorAdditionalDiags::TryCannotConvert { + found: found_ty.content(), + expected: expected_ty.content(), + }); + } suggestions } @@ -2069,7 +2135,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { visitor.visit_body(body); visitor.result.map(|r| &r.peel_refs().kind) } - Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _), .. })) => { + Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(ty, _, _), .. })) => { Some(&ty.peel_refs().kind) } _ => None, @@ -2109,14 +2175,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { found: Ty<'tcx>, expected_fields: &List<Ty<'tcx>>, ) -> Option<TypeErrorAdditionalDiags> { - let [expected_tup_elem] = expected_fields[..] else { return None}; + let [expected_tup_elem] = expected_fields[..] else { return None }; if !self.same_type_modulo_infer(expected_tup_elem, found) { return None; } - let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) - else { return None }; + let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) else { return None }; let sugg = if code.starts_with('(') && code.ends_with(')') { let before_close = span.hi() - BytePos::from_u32(1); @@ -2141,6 +2206,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Regions(exp_found) => self.expected_found_str(exp_found), infer::Terms(exp_found) => self.expected_found_str_term(exp_found), infer::Aliases(exp_found) => self.expected_found_str(exp_found), + infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found), + infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found), infer::TraitRefs(exp_found) => { let pretty_exp_found = ty::error::ExpectedFound { expected: exp_found.expected.print_only_trait_path(), @@ -2356,7 +2423,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Ok(snip) = self.tcx.sess.source_map().span_to_next_source(p.span) && snip.starts_with(' ') { - format!("{new_lt}") + new_lt.to_string() } else { format!("{new_lt} ") } @@ -2370,13 +2437,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let labeled_user_string = match bound_kind { - GenericKind::Param(ref p) => format!("the parameter type `{}`", p), + GenericKind::Param(ref p) => format!("the parameter type `{p}`"), GenericKind::Alias(ref p) => match p.kind(self.tcx) { ty::AliasKind::Projection | ty::AliasKind::Inherent => { - format!("the associated type `{}`", p) + format!("the associated type `{p}`") } - ty::AliasKind::Weak => format!("the type alias `{}`", p), - ty::AliasKind::Opaque => format!("the opaque type `{}`", p), + ty::AliasKind::Weak => format!("the type alias `{p}`"), + ty::AliasKind::Opaque => format!("the opaque type `{p}`"), }, }; @@ -2390,7 +2457,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, impl_item_def_id, trait_item_def_id, - &format!("`{}: {}`", bound_kind, sub), + &format!("`{bound_kind}: {sub}`"), ); } @@ -2404,7 +2471,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let msg = "consider adding an explicit lifetime bound"; if let Some((sp, has_lifetimes)) = type_param_span { let suggestion = - if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) }; + if has_lifetimes { format!(" + {sub}") } else { format!(": {sub}") }; let mut suggestions = vec![(sp, suggestion)]; for add_lt_sugg in add_lt_suggs.into_iter().flatten() { suggestions.push(add_lt_sugg); @@ -2415,7 +2482,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Applicability::MaybeIncorrect, // Issue #41966 ); } else { - let consider = format!("{} `{}: {}`...", msg, bound_kind, sub); + let consider = format!("{msg} `{bound_kind}: {sub}`..."); err.help(consider); } } @@ -2424,13 +2491,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { |err: &mut Diagnostic, type_param_span: Option<(Span, bool)>| { let msg = "consider introducing an explicit lifetime bound"; if let Some((sp, has_lifetimes)) = type_param_span { - let suggestion = if has_lifetimes { - format!(" + {}", new_lt) - } else { - format!(": {}", new_lt) - }; + let suggestion = + if has_lifetimes { format!(" + {new_lt}") } else { format!(": {new_lt}") }; let mut sugg = - vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))]; + vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {new_lt}"))]; for lt in add_lt_suggs.clone().into_iter().flatten() { sugg.push(lt); sugg.rotate_right(1); @@ -2510,7 +2574,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { "{} may not live long enough", labeled_user_string ); - let pred = format!("{}: {}", bound_kind, sub); + let pred = format!("{bound_kind}: {sub}"); let suggestion = format!("{} {}", generics.add_where_or_trailing_comma(), pred,); err.span_suggestion( generics.tail_span_for_predicate_suggestion(), @@ -2566,21 +2630,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { note_and_explain_region( self.tcx, &mut err, - &format!("{} must be valid for ", labeled_user_string), + &format!("{labeled_user_string} must be valid for "), sub, "...", None, ); if let Some(infer::RelateParamBound(_, t, _)) = origin { - let return_impl_trait = - self.tcx.return_type_impl_trait(generic_param_scope).is_some(); let t = self.resolve_vars_if_possible(t); match t.kind() { // We've got: // fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ // suggest: // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - ty::Closure(..) | ty::Alias(ty::Opaque, ..) if return_impl_trait => { + ty::Closure(..) | ty::Alias(ty::Opaque, ..) => { new_binding_suggestion(&mut err, type_param_span); } _ => { @@ -2816,10 +2878,10 @@ impl<'tcx> InferCtxt<'tcx> { br_string(br), self.tcx.associated_item(def_id).name ), - infer::EarlyBoundRegion(_, name) => format!(" for lifetime parameter `{}`", name), + infer::EarlyBoundRegion(_, name) => format!(" for lifetime parameter `{name}`"), infer::UpvarRegion(ref upvar_id, _) => { let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id); - format!(" for capture of `{}` by closure", var_name) + format!(" for capture of `{var_name}` by closure") } infer::Nll(..) => bug!("NLL variable found in lexical phase"), }; @@ -2895,8 +2957,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { CompareImplItemObligation { kind: ty::AssocKind::Const, .. } => { ObligationCauseFailureCode::ConstCompat { span, subdiags } } + BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => { + ObligationCauseFailureCode::TryCompat { span, subdiags } + } MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source { - hir::MatchSource::TryDesugar => { + hir::MatchSource::TryDesugar(_) => { ObligationCauseFailureCode::TryCompat { span, subdiags } } _ => ObligationCauseFailureCode::MatchCompat { span, subdiags }, diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index bb75ecc6a..f2a3c47bd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -18,7 +18,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::{self, InferConst}; -use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef}; +use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span}; @@ -162,10 +162,18 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let mut infcx_inner = infcx.inner.borrow_mut(); let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind - && !var_origin.span.from_expansion() + if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind + && name != kw::SelfUpper && !var_origin.span.from_expansion() { - Some(name) + let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id)); + let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap(); + let generic_param_def = generics.param_at(idx as usize, infcx.tcx); + if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind + { + None + } else { + Some(name) + } } else { None } @@ -218,8 +226,8 @@ fn ty_to_string<'tcx>( /// something users are familiar with. Directly printing the `fn_sig` of closures also /// doesn't work as they actually use the "rust-call" API. fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { - let ty::Closure(_, substs) = ty.kind() else { unreachable!() }; - let fn_sig = substs.as_closure().sig(); + let ty::Closure(_, args) = ty.kind() else { unreachable!() }; + let fn_sig = args.as_closure().sig(); let args = fn_sig .inputs() .skip_binder() @@ -238,7 +246,7 @@ fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String { } else { format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None)) }; - format!("fn({}){}", args, ret) + format!("fn({args}){ret}") } impl<'tcx> InferCtxt<'tcx> { @@ -411,7 +419,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let Some(InferSource { span, kind }) = local_visitor.infer_source else { - return self.bad_inference_failure_err(failure_span, arg_data, error_code) + return self.bad_inference_failure_err(failure_span, arg_data, error_code); }; let (source_kind, name) = kind.ty_localized_msg(self); @@ -516,9 +524,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }); } } - InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => { + InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { let printer = fmt_printer(self, Namespace::ValueNS); - let def_path = printer.print_def_path(def_id, substs).unwrap().into_buffer(); + let def_path = printer.print_def_path(def_id, args).unwrap().into_buffer(); // We only care about whether we have to add `&` or `&mut ` for now. // This is the case if the last adjustment is a borrow and the @@ -651,7 +659,7 @@ enum InferSourceKind<'tcx> { /// If the method has other arguments, this is ", " and the start of the first argument, /// while for methods without arguments this is ")" and the end of the method call. successor: (&'static str, BytePos), - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, def_id: DefId, }, ClosureReturn { @@ -702,7 +710,7 @@ impl<'tcx> InferSourceKind<'tcx> { #[derive(Debug)] struct InsertableGenericArgs<'tcx> { insert_span: Span, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, generics_def_id: DefId, def_id: DefId, have_turbofish: bool, @@ -766,11 +774,11 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { ty::Closure(..) => 1000, ty::FnDef(..) => 150, ty::FnPtr(..) => 30, - ty::Adt(def, substs) => { + ty::Adt(def, args) => { 5 + self .tcx .generics_of(def.did()) - .own_substs_no_defaults(self.tcx, substs) + .own_args_no_defaults(self.tcx, args) .iter() .map(|&arg| self.arg_cost(arg)) .sum::<usize>() @@ -797,8 +805,8 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { }; variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>() } - InferSourceKind::FullyQualifiedMethodCall { substs, .. } => { - 20 + substs.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>() + InferSourceKind::FullyQualifiedMethodCall { args, .. } => { + 20 + args.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>() } InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => { 30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 } @@ -832,9 +840,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { } } - fn node_substs_opt(&self, hir_id: HirId) -> Option<SubstsRef<'tcx>> { - let substs = self.typeck_results.node_substs_opt(hir_id); - self.infcx.resolve_vars_if_possible(substs) + fn node_args_opt(&self, hir_id: HirId) -> Option<GenericArgsRef<'tcx>> { + let args = self.typeck_results.node_args_opt(hir_id); + self.infcx.resolve_vars_if_possible(args) } fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> { @@ -915,15 +923,15 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { false } - fn expr_inferred_subst_iter( + fn expr_inferred_arg_iter( &self, expr: &'tcx hir::Expr<'tcx>, ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> { let tcx = self.infcx.tcx; match expr.kind { hir::ExprKind::Path(ref path) => { - if let Some(substs) = self.node_substs_opt(expr.hir_id) { - return self.path_inferred_subst_iter(expr.hir_id, substs, path); + if let Some(args) = self.node_args_opt(expr.hir_id) { + return self.path_inferred_arg_iter(expr.hir_id, args, path); } } // FIXME(#98711): Ideally we would also deal with type relative @@ -935,7 +943,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // However, the `type_dependent_def_id` for `Self::Output` in an // impl is currently the `DefId` of `Output` in the trait definition // which makes this somewhat difficult and prevents us from just - // using `self.path_inferred_subst_iter` here. + // using `self.path_inferred_arg_iter` here. hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _) // FIXME(TaKO8Ki): Ideally we should support this. For that // we have to map back from the self type to the @@ -943,11 +951,11 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // // See the `need_type_info/issue-103053.rs` test for // a example. - if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => { + if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => { if let Some(ty) = self.opt_node_type(expr.hir_id) - && let ty::Adt(_, substs) = ty.kind() + && let ty::Adt(_, args) = ty.kind() { - return Box::new(self.resolved_path_inferred_subst_iter(path, substs)); + return Box::new(self.resolved_path_inferred_arg_iter(path, args)); } } hir::ExprKind::MethodCall(segment, ..) => { @@ -957,12 +965,12 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { if generics.has_impl_trait() { None? } - let substs = self.node_substs_opt(expr.hir_id)?; + let args = self.node_args_opt(expr.hir_id)?; let span = tcx.hir().span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); InsertableGenericArgs { insert_span, - substs, + args, generics_def_id: def_id, def_id, have_turbofish: false, @@ -977,10 +985,10 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { Box::new(iter::empty()) } - fn resolved_path_inferred_subst_iter( + fn resolved_path_inferred_arg_iter( &self, path: &'tcx hir::Path<'tcx>, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a { let tcx = self.infcx.tcx; let have_turbofish = path.segments.iter().any(|segment| { @@ -1001,7 +1009,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi()); InsertableGenericArgs { insert_span, - substs, + args, generics_def_id, def_id: path.res.def_id(), have_turbofish, @@ -1021,7 +1029,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); Some(InsertableGenericArgs { insert_span, - substs, + args, generics_def_id, def_id: res.def_id(), have_turbofish, @@ -1030,16 +1038,16 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { .chain(last_segment_using_path_data) } - fn path_inferred_subst_iter( + fn path_inferred_arg_iter( &self, hir_id: HirId, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, qpath: &'tcx hir::QPath<'tcx>, ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> { let tcx = self.infcx.tcx; match qpath { hir::QPath::Resolved(_self_ty, path) => { - Box::new(self.resolved_path_inferred_subst_iter(path, substs)) + Box::new(self.resolved_path_inferred_arg_iter(path, args)) } hir::QPath::TypeRelative(ty, segment) => { let Some(def_id) = self.typeck_results.type_dependent_def_id(hir_id) else { @@ -1055,7 +1063,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); InsertableGenericArgs { insert_span, - substs, + args, generics_def_id: def_id, def_id, have_turbofish: false, @@ -1064,15 +1072,15 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let parent_def_id = generics.parent.unwrap(); if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) { - let parent_ty = tcx.type_of(parent_def_id).subst(tcx, substs); + let parent_ty = tcx.type_of(parent_def_id).instantiate(tcx, args); match (parent_ty.kind(), &ty.kind) { ( - ty::Adt(def, substs), + ty::Adt(def, args), hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)), ) => { if tcx.res_generics_def_id(path.res) != Some(def.did()) { match path.res { - Res::Def(DefKind::TyAlias, _) => { + Res::Def(DefKind::TyAlias { .. }, _) => { // FIXME: Ideally we should support this. For that // we have to map back from the self type to the // type alias though. That's difficult. @@ -1084,14 +1092,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // so there's nothing for us to do here. Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {} _ => warn!( - "unexpected path: def={:?} substs={:?} path={:?}", - def, substs, path, + "unexpected path: def={:?} args={:?} path={:?}", + def, args, path, ), } } else { return Box::new( - self.resolved_path_inferred_subst_iter(path, substs) - .chain(segment), + self.resolved_path_inferred_arg_iter(path, args).chain(segment), ); } } @@ -1149,9 +1156,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { continue; } - let Some(param_ty) = self.opt_node_type(param.hir_id) else { - continue - }; + let Some(param_ty) = self.opt_node_type(param.hir_id) else { continue }; if self.generic_arg_contains_target(param_ty.into()) { self.update_infer_source(InferSource { @@ -1181,27 +1186,27 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { _ => intravisit::walk_expr(self, expr), } - for args in self.expr_inferred_subst_iter(expr) { + for args in self.expr_inferred_arg_iter(expr) { debug!(?args); let InsertableGenericArgs { insert_span, - substs, + args, generics_def_id, def_id, have_turbofish, } = args; let generics = tcx.generics_of(generics_def_id); if let Some(mut argument_index) = generics - .own_substs(substs) + .own_args(args) .iter() .position(|&arg| self.generic_arg_contains_target(arg)) { if generics.parent.is_none() && generics.has_self { argument_index += 1; } - let substs = self.infcx.resolve_vars_if_possible(substs); - let generic_args = &generics.own_substs_no_defaults(tcx, substs) - [generics.own_counts().lifetimes..]; + let args = self.infcx.resolve_vars_if_possible(args); + let generic_args = + &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..]; let span = match expr.kind { ExprKind::MethodCall(path, ..) => path.ident.span, _ => expr.span, @@ -1224,10 +1229,10 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { 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(_, substs), + ty::Closure(_, args), ) = (&expr.kind, node_ty.kind()) { - let output = substs.as_closure().sig().output().skip_binder(); + let output = args.as_closure().sig().output().skip_binder(); if self.generic_arg_contains_target(output.into()) { let body = self.infcx.tcx.hir().body(body); let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) { @@ -1253,22 +1258,22 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { }) .any(|generics| generics.has_impl_trait()) }; - if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind - && let Some(substs) = self.node_substs_opt(expr.hir_id) - && substs.iter().any(|arg| self.generic_arg_contains_target(arg)) + 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.infcx.tcx.trait_of_item(def_id).is_some() && !has_impl_trait(def_id) { let successor = - args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); - let substs = self.infcx.resolve_vars_if_possible(substs); + method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo())); + let args = self.infcx.resolve_vars_if_possible(args); self.update_infer_source(InferSource { span: path.ident.span, kind: InferSourceKind::FullyQualifiedMethodCall { receiver, successor, - substs, + args, def_id, } }) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 2c63a3904..6901955af 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -38,8 +38,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let (ObligationCauseCode::BindingObligation(_, binding_span) | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..)) - = *parent.code() else { + let (ObligationCauseCode::BindingObligation(_, binding_span) + | ObligationCauseCode::ExprBindingObligation(_, binding_span, ..)) = *parent.code() + else { return None; }; @@ -67,12 +68,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, .. }), .. - }) = impl_node else { + }) = impl_node + else { bug!("Node not an impl."); }; // Next, let's figure out the set of trait objects with implicit static bounds - let ty = self.tcx().type_of(*impl_def_id).subst_identity(); + let ty = self.tcx().type_of(*impl_def_id).instantiate_identity(); let mut v = super::static_impl_trait::TraitObjectVisitor(FxIndexSet::default()); v.visit_ty(ty); let mut traits = vec![]; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 4e13ec902..07f04ec1e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -29,25 +29,15 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // version new_ty of its type where the anonymous region is replaced // with the named one. let (named, anon, anon_param_info, region_info) = if sub.has_name() - && self.tcx().is_suitable_region(sup).is_some() - && self.find_param_with_region(sup, sub).is_some() + && let Some(region_info) = self.tcx().is_suitable_region(sup) + && let Some(anon_param_info) = self.find_param_with_region(sup, sub) { - ( - sub, - sup, - self.find_param_with_region(sup, sub).unwrap(), - self.tcx().is_suitable_region(sup).unwrap(), - ) + (sub, sup, anon_param_info, region_info) } else if sup.has_name() - && self.tcx().is_suitable_region(sub).is_some() - && self.find_param_with_region(sub, sup).is_some() + && let Some(region_info) = self.tcx().is_suitable_region(sub) + && let Some(anon_param_info) = self.find_param_with_region(sub, sup) { - ( - sup, - sub, - self.find_param_with_region(sub, sup).unwrap(), - self.tcx().is_suitable_region(sub).unwrap(), - ) + (sup, sub, anon_param_info, region_info) } else { return None; // inapplicable }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 0b3bc1ce6..f903f7a49 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -13,7 +13,7 @@ use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, RegionHighlightMode}; -use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, RePlaceholder, Region, TyCtxt}; use std::fmt; @@ -196,11 +196,11 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sup_placeholder: Option<Region<'tcx>>, value_pairs: &ValuePairs<'tcx>, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { - let (expected_substs, found_substs, trait_def_id) = match value_pairs { + let (expected_args, found_args, trait_def_id) = match value_pairs { ValuePairs::TraitRefs(ExpectedFound { expected, found }) if expected.def_id == found.def_id => { - (expected.substs, found.substs, expected.def_id) + (expected.args, found.args, expected.def_id) } ValuePairs::PolyTraitRefs(ExpectedFound { expected, found }) if expected.def_id() == found.def_id() => @@ -208,7 +208,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { // It's possible that the placeholders come from a binder // outside of this value pair. Use `no_bound_vars` as a // simple heuristic for that. - (expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id()) + (expected.no_bound_vars()?.args, found.no_bound_vars()?.args, expected.def_id()) } _ => return None, }; @@ -219,8 +219,8 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sub_placeholder, sup_placeholder, trait_def_id, - expected_substs, - found_substs, + expected_args, + found_args, )) } @@ -241,8 +241,8 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { sub_placeholder: Option<Region<'tcx>>, sup_placeholder: Option<Region<'tcx>>, trait_def_id: DefId, - expected_substs: SubstsRef<'tcx>, - actual_substs: SubstsRef<'tcx>, + expected_args: GenericArgsRef<'tcx>, + actual_args: GenericArgsRef<'tcx>, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let span = cause.span(); @@ -264,12 +264,12 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( self.cx.tcx, trait_def_id, - expected_substs, + expected_args, )); let actual_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef::new( self.cx.tcx, trait_def_id, - actual_substs, + actual_args, )); // Search the expected and actual trait references to see (a) @@ -413,9 +413,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { if self_ty.value.is_closure() && self.tcx().is_fn_trait(expected_trait_ref.value.def_id) { let closure_sig = self_ty.map(|closure| { - if let ty::Closure(_, substs) = closure.kind() { + if let ty::Closure(_, args) = closure.kind() { self.tcx().signature_unclosure( - substs.as_closure().sig(), + args.as_closure().sig(), rustc_hir::Unsafety::Normal, ) } else { diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index a9b485a6f..3cfda0cc5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -146,7 +146,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin { if let ObligationCauseCode::ReturnValue(hir_id) - | ObligationCauseCode::BlockTailExpression(hir_id) = cause.code() + | ObligationCauseCode::BlockTailExpression(hir_id, ..) = cause.code() { let parent_id = tcx.hir().get_parent_item(*hir_id); if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id.into()) { @@ -235,10 +235,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } let arg = match param.param.pat.simple_ident() { - Some(simple_ident) => format!("argument `{}`", simple_ident), + Some(simple_ident) => format!("argument `{simple_ident}`"), None => "the argument".to_string(), }; - let captures = format!("captures data from {}", arg); + let captures = format!("captures data from {arg}"); suggest_new_region_bound( tcx, &mut err, @@ -269,11 +269,11 @@ pub fn suggest_new_region_bound( // FIXME: account for the need of parens in `&(dyn Trait + '_)` let consider = "consider changing"; let declare = "to declare that"; - let explicit = format!("you can add an explicit `{}` lifetime bound", lifetime_name); + let explicit = format!("you can add an explicit `{lifetime_name}` lifetime bound"); let explicit_static = - arg.map(|arg| format!("explicit `'static` bound to the lifetime of {}", arg)); + arg.map(|arg| format!("explicit `'static` bound to the lifetime of {arg}")); let add_static_bound = "alternatively, add an explicit `'static` bound to this reference"; - let plus_lt = format!(" + {}", lifetime_name); + let plus_lt = format!(" + {lifetime_name}"); for fn_return in fn_returns { if fn_return.span.desugaring_kind().is_some() { // Skip `async` desugaring `impl Future`. @@ -288,7 +288,7 @@ pub fn suggest_new_region_bound( // Get the identity type for this RPIT let did = item_id.owner_id.to_def_id(); - let ty = Ty::new_opaque(tcx, did, ty::InternalSubsts::identity_for_item(tcx, did)); + let ty = Ty::new_opaque(tcx, did, ty::GenericArgs::identity_for_item(tcx, did)); if let Some(span) = opaque.bounds.iter().find_map(|arg| match arg { GenericBound::Outlives(Lifetime { @@ -333,11 +333,7 @@ pub fn suggest_new_region_bound( } else { None }; - let name = if let Some(name) = &existing_lt_name { - format!("{}", name) - } else { - format!("'a") - }; + let name = if let Some(name) = &existing_lt_name { name } else { "'a" }; // if there are more than one elided lifetimes in inputs, the explicit `'_` lifetime cannot be used. // introducing a new lifetime `'a` or making use of one from existing named lifetimes if any if let Some(id) = scope_def_id @@ -350,7 +346,7 @@ pub fn suggest_new_region_bound( if p.span.hi() - p.span.lo() == rustc_span::BytePos(1) { // Ampersand (elided without '_) (p.span.shrink_to_hi(),format!("{name} ")) } else { // Underscore (elided with '_) - (p.span, format!("{name}")) + (p.span, name.to_string()) } ) .collect::<Vec<_>>() @@ -387,12 +383,7 @@ pub fn suggest_new_region_bound( if let LifetimeName::ImplicitObjectLifetimeDefault = lt.res { err.span_suggestion_verbose( fn_return.span.shrink_to_hi(), - format!( - "{declare} the trait object {captures}, {explicit}", - declare = declare, - captures = captures, - explicit = explicit, - ), + format!("{declare} the trait object {captures}, {explicit}",), &plus_lt, Applicability::MaybeIncorrect, ); @@ -404,7 +395,7 @@ pub fn suggest_new_region_bound( if let Some(explicit_static) = &explicit_static { err.span_suggestion_verbose( lt.ident.span, - format!("{} the trait object's {}", consider, explicit_static), + format!("{consider} the trait object's {explicit_static}"), &lifetime_name, Applicability::MaybeIncorrect, ); @@ -493,7 +484,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { tcx, ctxt.param_env, ctxt.assoc_item.def_id, - self.cx.resolve_vars_if_possible(ctxt.substs), + self.cx.resolve_vars_if_possible(ctxt.args), ) else { return false; }; @@ -503,7 +494,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // Get the `Ident` of the method being called and the corresponding `impl` (to point at // `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called). - let Some((ident, self_ty)) = NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) else { + let Some((ident, self_ty)) = + NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) + else { return false; }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index c5ef48fe3..be6d1a375 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -64,8 +64,8 @@ pub fn find_param_with_region<'tcx>( let body_id = hir.maybe_body_owned_by(def_id)?; let owner_id = hir.body_owner(body_id); - let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap(); - let poly_fn_sig = tcx.fn_sig(id).subst_identity(); + let fn_decl = hir.fn_decl_by_hir_id(owner_id)?; + let poly_fn_sig = tcx.fn_sig(id).instantiate_identity(); let fn_sig = tcx.liberate_late_bound_regions(id, poly_fn_sig); let body = hir.body(body_id); @@ -123,7 +123,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { br: ty::BoundRegionKind, hir_sig: &hir::FnSig<'_>, ) -> Option<Span> { - let fn_ty = self.tcx().type_of(scope_def_id).subst_identity(); + let fn_ty = self.tcx().type_of(scope_def_id).instantiate_identity(); if let ty::FnDef(_, _) = fn_ty.kind() { let ret_ty = fn_ty.fn_sig(self.tcx()).output(); let span = hir_sig.decl.output.span(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e55e9e75f..8d3cd23b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -227,7 +227,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span, impl_item_def_id, trait_item_def_id, - &format!("`{}: {}`", sup, sub), + &format!("`{sup}: {sub}`"), ); // We should only suggest rewriting the `where` clause if the predicate is within that `where` clause if let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) @@ -243,12 +243,18 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } infer::CheckAssociatedTypeBounds { impl_item_def_id, trait_item_def_id, parent } => { let mut err = self.report_concrete_failure(*parent, sub, sup); - let trait_item_span = self.tcx.def_span(trait_item_def_id); - let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label( - trait_item_span, - format!("definition of `{}` from trait", item_name), - ); + + // Don't mention the item name if it's an RPITIT, since that'll just confuse + // folks. + if !self.tcx.is_impl_trait_in_trait(impl_item_def_id.to_def_id()) { + let trait_item_span = self.tcx.def_span(trait_item_def_id); + let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); + err.span_label( + trait_item_span, + format!("definition of `{item_name}` from trait"), + ); + } + self.suggest_copy_trait_method_bounds( trait_item_def_id, impl_item_def_id, @@ -295,34 +301,40 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // but right now it's not really very smart when it comes to implicit `Sized` // predicates and bounds on the trait itself. - let Some(impl_def_id) = - self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) else { return; }; - let Some(trait_ref) = self - .tcx - .impl_trait_ref(impl_def_id) - else { return; }; - let trait_substs = trait_ref - .subst_identity() + let Some(impl_def_id) = self.tcx.associated_item(impl_item_def_id).impl_container(self.tcx) + else { + return; + }; + let Some(trait_ref) = self.tcx.impl_trait_ref(impl_def_id) else { + return; + }; + let trait_args = trait_ref + .instantiate_identity() // Replace the explicit self type with `Self` for better suggestion rendering .with_self_ty(self.tcx, Ty::new_param(self.tcx, 0, kw::SelfUpper)) - .substs; - let trait_item_substs = ty::InternalSubsts::identity_for_item(self.tcx, impl_item_def_id) - .rebase_onto(self.tcx, impl_def_id, trait_substs); + .args; + let trait_item_args = ty::GenericArgs::identity_for_item(self.tcx, impl_item_def_id) + .rebase_onto(self.tcx, impl_def_id, trait_args); - let Ok(trait_predicates) = self - .tcx - .explicit_predicates_of(trait_item_def_id) - .instantiate_own(self.tcx, trait_item_substs) - .map(|(pred, _)| { - if pred.is_suggestable(self.tcx, false) { - Ok(pred.to_string()) - } else { - Err(()) - } - }) - .collect::<Result<Vec<_>, ()>>() else { return; }; + let Ok(trait_predicates) = + self.tcx + .explicit_predicates_of(trait_item_def_id) + .instantiate_own(self.tcx, trait_item_args) + .map(|(pred, _)| { + if pred.is_suggestable(self.tcx, false) { + Ok(pred.to_string()) + } else { + Err(()) + } + }) + .collect::<Result<Vec<_>, ()>>() + else { + return; + }; - let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { return; }; + let Some(generics) = self.tcx.hir().get_generics(impl_item_def_id) else { + return; + }; let suggestion = if trait_predicates.is_empty() { WhereClauseSuggestions::Remove { span: generics.where_clause_span } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index 63613b590..372539d73 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -47,7 +47,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.span_suggestion( sp, "use a float literal", - format!("{}.0", snippet), + format!("{snippet}.0"), MachineApplicable, ); } @@ -100,9 +100,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { // Synthesize the associated type restriction `Add<Output = Expected>`. // FIXME: extract this logic for use in other diagnostics. - let (trait_ref, assoc_substs) = proj.trait_ref_and_own_substs(tcx); + let (trait_ref, assoc_args) = proj.trait_ref_and_own_args(tcx); let item_name = tcx.item_name(proj.def_id); - let item_args = self.format_generic_args(assoc_substs); + let item_args = self.format_generic_args(assoc_args); // Here, we try to see if there's an existing // trait implementation that matches the one that @@ -134,7 +134,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if matched_end_of_args { // Append suggestion to the end of our args - let path = format!(", {}{} = {}",item_name, item_args, p); + let path = format!(", {item_name}{item_args} = {p}"); note = !suggest_constraining_type_param( tcx, generics, @@ -148,7 +148,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Suggest adding a bound to an existing trait // or if the trait doesn't exist, add the trait // and the suggested bounds. - let path = format!("<{}{} = {}>", item_name, item_args, p); + let path = format!("<{item_name}{item_args} = {p}>"); note = !suggest_constraining_type_param( tcx, generics, @@ -213,8 +213,7 @@ impl<T> Trait<T> for X { } diag.help(format!( "every closure has a distinct type and so could not always match the \ - caller-chosen type of parameter `{}`", - p + caller-chosen type of parameter `{p}`" )); } (ty::Param(p), _) | (_, ty::Param(p)) => { @@ -316,7 +315,7 @@ impl<T> Trait<T> for X { ) -> bool { let tcx = self.tcx; let assoc = tcx.associated_item(proj_ty.def_id); - let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(tcx); + let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx); if let Some(item) = tcx.hir().get_if_local(body_owner_def_id) { if let Some(hir_generics) = item.generics() { // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`. @@ -339,7 +338,7 @@ impl<T> Trait<T> for X { &trait_ref, pred.bounds, assoc, - assoc_substs, + assoc_args, ty, &msg, false, @@ -488,14 +487,14 @@ fn foo(&self) -> Self::T { String::new() } return false; }; - let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(tcx); + let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx); self.constrain_generic_bound_associated_type_structured_suggestion( diag, &trait_ref, opaque_hir_ty.bounds, assoc, - assoc_substs, + assoc_args, ty, msg, true, @@ -527,7 +526,7 @@ fn foo(&self) -> Self::T { String::new() } && !tcx.is_doc_hidden(item.def_id) }) .filter_map(|item| { - let method = tcx.fn_sig(item.def_id).subst_identity(); + let method = tcx.fn_sig(item.def_id).instantiate_identity(); match *method.output().skip_binder().kind() { ty::Alias(ty::Projection, ty::AliasTy { def_id: item_def_id, .. }) if item_def_id == proj_ty_item_def_id => @@ -597,7 +596,7 @@ fn foo(&self) -> Self::T { String::new() } if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id) { - let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity(); + let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label( item.span, @@ -618,7 +617,7 @@ fn foo(&self) -> Self::T { String::new() } })) => { for item in &items[..] { if let hir::AssocItemKind::Type = item.kind { - let assoc_ty = tcx.type_of(item.id.owner_id).subst_identity(); + let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity(); if self.infcx.can_eq(param_env, assoc_ty, found) { diag.span_label(item.span, "expected this associated type"); @@ -645,7 +644,7 @@ fn foo(&self) -> Self::T { String::new() } trait_ref: &ty::TraitRef<'tcx>, bounds: hir::GenericBounds<'_>, assoc: ty::AssocItem, - assoc_substs: &[ty::GenericArg<'tcx>], + assoc_args: &[ty::GenericArg<'tcx>], ty: Ty<'tcx>, msg: impl Fn() -> String, is_bound_surely_present: bool, @@ -671,14 +670,7 @@ fn foo(&self) -> Self::T { String::new() } _ => return false, }; - self.constrain_associated_type_structured_suggestion( - diag, - span, - assoc, - assoc_substs, - ty, - msg, - ) + self.constrain_associated_type_structured_suggestion(diag, span, assoc, assoc_args, ty, msg) } /// Given a span corresponding to a bound, provide a structured suggestion to set an @@ -688,7 +680,7 @@ fn foo(&self) -> Self::T { String::new() } diag: &mut Diagnostic, span: Span, assoc: ty::AssocItem, - assoc_substs: &[ty::GenericArg<'tcx>], + assoc_args: &[ty::GenericArg<'tcx>], ty: Ty<'tcx>, msg: impl Fn() -> String, ) -> bool { @@ -702,7 +694,7 @@ fn foo(&self) -> Self::T { String::new() } let span = Span::new(pos, pos, span.ctxt(), span.parent()); (span, format!(", {} = {}", assoc.ident(tcx), ty)) } else { - let item_args = self.format_generic_args(assoc_substs); + let item_args = self.format_generic_args(assoc_args); (span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(tcx), item_args, ty)) }; diag.span_suggestion_verbose(span, msg(), sugg, MaybeIncorrect); diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 1422bdc9e..f1d53cb59 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -105,7 +105,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with // some modifications due to that being in typeck and this being in infer. if let ObligationCauseCode::Pattern { .. } = cause.code() { - if let ty::Adt(expected_adt, substs) = exp_found.expected.kind() { + if let ty::Adt(expected_adt, args) = exp_found.expected.kind() { let compatible_variants: Vec<_> = expected_adt .variants() .iter() @@ -114,7 +114,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }) .filter_map(|variant| { let sole_field = &variant.single_field(); - let sole_field_ty = sole_field.ty(self.tcx, substs); + let sole_field_ty = sole_field.ty(self.tcx, args); if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { let variant_path = with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id)); @@ -260,7 +260,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { "suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})", cause, exp_found ); - if let ty::Adt(expected_def, expected_substs) = exp_found.expected.kind() { + if let ty::Adt(expected_def, expected_args) = exp_found.expected.kind() { if expected_def.is_enum() { return; } @@ -270,7 +270,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .fields .iter() .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) - .map(|field| (field.name, field.ty(self.tcx, expected_substs))) + .map(|field| (field.name, field.ty(self.tcx, expected_args))) .find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found)) { if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() { @@ -304,12 +304,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } match (&expected_inner.kind(), &found_inner.kind()) { - (ty::FnPtr(sig), ty::FnDef(did, substs)) => { + (ty::FnPtr(sig), ty::FnDef(did, args)) => { let expected_sig = &(self.normalize_fn_sig)(*sig); let found_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).subst(self.tcx, substs)); + &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args)); - let fn_name = self.tcx.def_path_str_with_substs(*did, substs); + let fn_name = self.tcx.def_path_str_with_args(*did, args); if !self.same_type_modulo_infer(*found_sig, *expected_sig) || !sig.is_suggestable(self.tcx, true) @@ -332,11 +332,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; diag.subdiagnostic(sugg); } - (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => { + (ty::FnDef(did1, args1), ty::FnDef(did2, args2)) => { let expected_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did1).subst(self.tcx, substs1)); + &(self.normalize_fn_sig)(self.tcx.fn_sig(*did1).instantiate(self.tcx, args1)); let found_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).subst(self.tcx, substs2)); + &(self.normalize_fn_sig)(self.tcx.fn_sig(*did2).instantiate(self.tcx, args2)); if self.same_type_modulo_infer(*expected_sig, *found_sig) { diag.subdiagnostic(FnUniqTypes); @@ -351,7 +351,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return; } - let fn_name = self.tcx.def_path_str_with_substs(*did2, substs2); + let fn_name = self.tcx.def_path_str_with_args(*did2, args2); let sug = if found.is_ref() { FunctionPointerSuggestion::CastBothRef { span, @@ -370,16 +370,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.subdiagnostic(sug); } - (ty::FnDef(did, substs), ty::FnPtr(sig)) => { + (ty::FnDef(did, args), ty::FnPtr(sig)) => { let expected_sig = - &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).subst(self.tcx, substs)); + &(self.normalize_fn_sig)(self.tcx.fn_sig(*did).instantiate(self.tcx, args)); let found_sig = &(self.normalize_fn_sig)(*sig); if !self.same_type_modulo_infer(*found_sig, *expected_sig) { return; } - let fn_name = self.tcx.def_path_str_with_substs(*did, substs); + let fn_name = self.tcx.def_path_str_with_args(*did, args); let casting = if expected.is_ref() { format!("&({fn_name} as {found_sig})") @@ -400,10 +400,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, ) -> Option<SuggestAsRefKind> { - if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) = + if let (ty::Adt(exp_def, exp_args), ty::Ref(_, found_ty, _)) = (expected.kind(), found.kind()) { - if let ty::Adt(found_def, found_substs) = *found_ty.kind() { + if let ty::Adt(found_def, found_args) = *found_ty.kind() { if exp_def == &found_def { let have_as_ref = &[ (sym::Option, SuggestAsRefKind::Option), @@ -414,7 +414,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }) { let mut show_suggestion = true; for (exp_ty, found_ty) in - std::iter::zip(exp_substs.types(), found_substs.types()) + std::iter::zip(exp_args.types(), found_args.types()) { match *exp_ty.kind() { ty::Ref(_, exp_ty, _) => { @@ -464,52 +464,53 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { span: Span, ) -> Option<TypeErrorAdditionalDiags> { let hir = self.tcx.hir(); - if let Some(node) = self.tcx.hir().find_by_def_id(cause.body_id) && - let hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_sig, _, body_id), .. - }) = node { - let body = hir.body(*body_id); - - /// Find the if expression with given span - struct IfVisitor { - pub result: bool, - pub found_if: bool, - pub err_span: Span, - } + if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(cause.body_id) { + let body = hir.body(body_id); + + /// Find the if expression with given span + struct IfVisitor { + pub result: bool, + pub found_if: bool, + pub err_span: Span, + } - impl<'v> Visitor<'v> for IfVisitor { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if self.result { return; } - match ex.kind { - hir::ExprKind::If(cond, _, _) => { - self.found_if = true; - walk_expr(self, cond); - self.found_if = false; + impl<'v> Visitor<'v> for IfVisitor { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + if self.result { + return; + } + match ex.kind { + hir::ExprKind::If(cond, _, _) => { + self.found_if = true; + walk_expr(self, cond); + self.found_if = false; + } + _ => walk_expr(self, ex), } - _ => walk_expr(self, ex), } - } - fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { - if let hir::StmtKind::Local(hir::Local { - span, pat: hir::Pat{..}, ty: None, init: Some(_), .. - }) = &ex.kind - && self.found_if - && span.eq(&self.err_span) { - self.result = true; + fn visit_stmt(&mut self, ex: &'v hir::Stmt<'v>) { + if let hir::StmtKind::Local(hir::Local { + span, pat: hir::Pat{..}, ty: None, init: Some(_), .. + }) = &ex.kind + && self.found_if + && span.eq(&self.err_span) { + self.result = true; + } + walk_stmt(self, ex); } - walk_stmt(self, ex); - } - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - hir::intravisit::walk_body(self, body); + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + hir::intravisit::walk_body(self, body); + } } - } - let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; - visitor.visit_body(&body); - if visitor.result { - return Some(TypeErrorAdditionalDiags::AddLetForLetChains{span: span.shrink_to_lo()}); + let mut visitor = IfVisitor { err_span: span, found_if: false, result: false }; + visitor.visit_body(&body); + if visitor.result { + return Some(TypeErrorAdditionalDiags::AddLetForLetChains { + span: span.shrink_to_lo(), + }); } } None @@ -525,13 +526,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag: &mut Diagnostic, ) { // 0. Extract fn_decl from hir - let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }), .. }) = hir else { return; }; + let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }), + .. + }) = hir + else { + return; + }; let hir::Body { params, .. } = self.tcx.hir().body(*body); - // 1. Get the substs of the closure. + // 1. Get the args of the closure. // 2. Assume exp_found is FnOnce / FnMut / Fn, we can extract function parameters from [1]. - let Some(expected) = exp_found.expected.skip_binder().substs.get(1) else { return; }; - let Some(found) = exp_found.found.skip_binder().substs.get(1) else { return; }; + let Some(expected) = exp_found.expected.skip_binder().args.get(1) else { + return; + }; + let Some(found) = exp_found.found.skip_binder().args.get(1) else { + return; + }; let expected = expected.unpack(); let found = found.unpack(); // 3. Extract the tuple type from Fn trait and suggest the change. @@ -564,12 +575,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if param_hir.pat.span == param_hir.ty_span { // for `|x|`, `|_|`, `|x: impl Foo|` let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; - suggestion += &format!("{}: &_", pat); + suggestion += &format!("{pat}: &_"); } else { // for `|x: ty|`, `|_: ty|` let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) else { return; }; - suggestion += &format!("{}: &{}", pat, ty); + suggestion += &format!("{pat}: &{ty}"); } has_suggestion = true; } else { @@ -620,8 +631,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, .. }), ) if last_def_id == exp_def_id => StatementAsExpression::CorrectType, ( - ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, substs: last_bounds, .. }), - ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, substs: exp_bounds, .. }), + ty::Alias(ty::Opaque, ty::AliasTy { def_id: last_def_id, args: last_bounds, .. }), + ty::Alias(ty::Opaque, ty::AliasTy { def_id: exp_def_id, args: exp_bounds, .. }), ) => { debug!( "both opaque, likely future {:?} {:?} {:?} {:?}", @@ -710,7 +721,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let hir = self.tcx.hir(); for stmt in blk.stmts.iter().rev() { - let hir::StmtKind::Local(local) = &stmt.kind else { continue; }; + let hir::StmtKind::Local(local) = &stmt.kind else { + continue; + }; local.pat.walk(&mut find_compatible_candidates); } match hir.find_parent(blk.hir_id) { |