From d1b2d29528b7794b41e66fc2136e395a02f8529b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:59:35 +0200 Subject: Merging upstream version 1.73.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_infer/src/errors/mod.rs | 19 +- .../rustc_infer/src/errors/note_and_explain.rs | 2 +- compiler/rustc_infer/src/infer/at.rs | 28 +++ .../src/infer/canonical/canonicalizer.rs | 14 +- compiler/rustc_infer/src/infer/canonical/mod.rs | 4 +- .../src/infer/canonical/query_response.rs | 6 +- .../rustc_infer/src/infer/canonical/substitute.rs | 2 +- compiler/rustc_infer/src/infer/combine.rs | 8 +- compiler/rustc_infer/src/infer/equate.rs | 12 +- .../rustc_infer/src/infer/error_reporting/mod.rs | 245 +++++++++++++-------- .../src/infer/error_reporting/need_type_info.rs | 125 ++++++----- .../mismatched_static_lifetime.rs | 10 +- .../nice_region_error/named_anon_conflict.rs | 22 +- .../nice_region_error/placeholder_error.rs | 24 +- .../nice_region_error/static_impl_trait.rs | 37 ++-- .../error_reporting/nice_region_error/util.rs | 6 +- .../rustc_infer/src/infer/error_reporting/note.rs | 74 ++++--- .../src/infer/error_reporting/note_and_explain.rs | 42 ++-- .../src/infer/error_reporting/suggest.rs | 141 ++++++------ compiler/rustc_infer/src/infer/freshen.rs | 2 +- compiler/rustc_infer/src/infer/generalize.rs | 22 +- .../src/infer/lexical_region_resolve/mod.rs | 9 +- compiler/rustc_infer/src/infer/mod.rs | 84 +++++-- compiler/rustc_infer/src/infer/nll_relate/mod.rs | 2 +- compiler/rustc_infer/src/infer/opaque_types.rs | 54 +++-- .../rustc_infer/src/infer/outlives/components.rs | 26 +-- .../rustc_infer/src/infer/outlives/obligations.rs | 16 +- .../src/infer/outlives/test_type_match.rs | 2 +- compiler/rustc_infer/src/infer/outlives/verify.rs | 4 +- .../src/infer/region_constraints/leak_check.rs | 8 +- .../src/infer/region_constraints/mod.rs | 8 +- compiler/rustc_infer/src/infer/type_variable.rs | 2 +- compiler/rustc_infer/src/traits/engine.rs | 2 +- .../rustc_infer/src/traits/error_reporting/mod.rs | 6 +- compiler/rustc_infer/src/traits/mod.rs | 40 ++-- compiler/rustc_infer/src/traits/project.rs | 8 +- .../rustc_infer/src/traits/structural_impls.rs | 10 +- compiler/rustc_infer/src/traits/util.rs | 13 +- 38 files changed, 642 insertions(+), 497 deletions(-) (limited to 'compiler/rustc_infer') diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 7e1fa08f2..a7e045e1e 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -210,10 +210,8 @@ impl<'a> SourceKindMultiSuggestion<'a> { _ => ("", ""), }; let (start_span, start_span_code, end_span) = match should_wrap_expr { - Some(end_span) => { - (data.span(), format!("{}{}{}{{ ", arrow, ty_info, post), Some(end_span)) - } - None => (data.span(), format!("{}{}{}", arrow, ty_info, post), None), + Some(end_span) => (data.span(), format!("{arrow}{ty_info}{post}{{ "), Some(end_span)), + None => (data.span(), format!("{arrow}{ty_info}{post}"), None), }; Self::ClosureReturn { start_span, start_span_code, end_span } } @@ -363,7 +361,8 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { let ( hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. }, hir::Ty { kind: hir::TyKind::Ref(lifetime_sup, _), .. }, - ) = (self.ty_sub, self.ty_sup) else { + ) = (self.ty_sub, self.ty_sup) + else { return false; }; @@ -403,9 +402,9 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { debug!(?lifetime_sub.ident.span); let make_suggestion = |ident: Ident| { let sugg = if ident.name == kw::Empty { - format!("{}, ", suggestion_param_name) + format!("{suggestion_param_name}, ") } else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() { - format!("{} ", suggestion_param_name) + format!("{suggestion_param_name} ") } else { suggestion_param_name.clone() }; @@ -418,9 +417,9 @@ impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { let new_param_suggestion = if let Some(first) = generics.params.iter().find(|p| !p.name.ident().span.is_empty()) { - (first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name)) + (first.span.shrink_to_lo(), format!("{suggestion_param_name}, ")) } else { - (generics.span, format!("<{}>", suggestion_param_name)) + (generics.span, format!("<{suggestion_param_name}>")) }; suggestions.push(new_param_suggestion); @@ -1319,7 +1318,7 @@ impl AddToDiagnostic for SuggestTuplePatternMany { message, self.compatible_variants.into_iter().map(|variant| { vec![ - (self.cause_span.shrink_to_lo(), format!("{}(", variant)), + (self.cause_span.shrink_to_lo(), format!("{variant}(")), (self.cause_span.shrink_to_hi(), ")".to_string()), ] }), diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index 7328241df..bd168f047 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -80,7 +80,7 @@ impl<'a> DescriptionCtx<'a> { // We shouldn't really be having unification failures with ReVar // and ReLateBound though. ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { - (alt_span, "revar", format!("{:?}", region)) + (alt_span, "revar", format!("{region:?}")) } }; Some(DescriptionCtx { span, kind, arg }) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 433735e82..6d5db3336 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -481,3 +481,31 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> { TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) } } } + +impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialTraitRef<'tcx> { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: ExistentialTraitRef(ExpectedFound::new(a_is_expected, a, b)), + } + } +} + +impl<'tcx> ToTrace<'tcx> for ty::PolyExistentialProjection<'tcx> { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: ExistentialProjection(ExpectedFound::new(a_is_expected, a, b)), + } + } +} diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index e57532e2d..9d7a9fefd 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -11,7 +11,7 @@ use crate::infer::canonical::{ use crate::infer::InferCtxt; use rustc_middle::ty::flags::FlagComputation; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::subst::GenericArg; +use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; use std::sync::atomic::Ordering; @@ -205,7 +205,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // `delay_span_bug` to allow type error over an ICE. canonicalizer.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, - format!("unexpected region in query response: `{:?}`", r), + format!("unexpected region in query response: `{r:?}`"), ); r } @@ -562,15 +562,9 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { V: TypeFoldable>, { let needs_canonical_flags = if canonicalize_region_mode.any() { - TypeFlags::HAS_INFER | - TypeFlags::HAS_FREE_REGIONS | // `HAS_RE_PLACEHOLDER` implies `HAS_FREE_REGIONS` - TypeFlags::HAS_TY_PLACEHOLDER | - TypeFlags::HAS_CT_PLACEHOLDER + TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER | TypeFlags::HAS_FREE_REGIONS } else { - TypeFlags::HAS_INFER - | TypeFlags::HAS_RE_PLACEHOLDER - | TypeFlags::HAS_TY_PLACEHOLDER - | TypeFlags::HAS_CT_PLACEHOLDER + TypeFlags::HAS_INFER | TypeFlags::HAS_PLACEHOLDER }; // Fast path: nothing that needs to be canonicalized. diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index f765c41a3..8ca2e4030 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -25,7 +25,7 @@ use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; use rustc_index::IndexVec; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::subst::GenericArg; +use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, List, Ty, TyCtxt}; use rustc_span::source_map::Span; @@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> { universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> CanonicalVarValues<'tcx> { CanonicalVarValues { - var_values: self.tcx.mk_substs_from_iter( + var_values: self.tcx.mk_args_from_iter( variables .iter() .map(|info| self.instantiate_canonical_var(span, info, &universe_map)), diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 9c3ab04de..ed1010821 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -25,8 +25,8 @@ use rustc_middle::arena::ArenaAllocatable; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::{Span, Symbol}; use std::fmt::Debug; use std::iter; @@ -484,7 +484,7 @@ impl<'tcx> InferCtxt<'tcx> { // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. let result_subst = CanonicalVarValues { - var_values: self.tcx.mk_substs_from_iter( + var_values: self.tcx.mk_args_from_iter( query_response.variables.iter().enumerate().map(|(index, info)| { if info.is_existential() { match opt_values[BoundVar::new(index)] { @@ -520,7 +520,7 @@ impl<'tcx> InferCtxt<'tcx> { self.at(cause, param_env) .eq( DefineOpaqueTypes::Yes, - Ty::new_opaque(self.tcx, a.def_id.to_def_id(), a.substs), + Ty::new_opaque(self.tcx, a.def_id.to_def_id(), a.args), b, )? .obligations, diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index cac3b4072..f368b30fb 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -8,7 +8,7 @@ use crate::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; -use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; /// FIXME(-Ztrait-solver=next): This or public because it is shared with the diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a9cdb8c51..ddc8e7e50 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -177,7 +177,7 @@ impl<'tcx> InferCtxt<'tcx> { self.tcx.check_tys_might_be_eq(canonical).map_err(|_| { self.tcx.sess.delay_span_bug( DUMMY_SP, - format!("cannot relate consts of different types (a={:?}, b={:?})", a, b,), + format!("cannot relate consts of different types (a={a:?}, b={b:?})",), ) }) }); @@ -254,7 +254,7 @@ impl<'tcx> InferCtxt<'tcx> { /// in `ct` with `ct` itself. /// /// This is especially important as unevaluated consts use their parents generics. - /// They therefore often contain unused substs, making these errors far more likely. + /// They therefore often contain unused args, making these errors far more likely. /// /// A good example of this is the following: /// @@ -272,12 +272,12 @@ impl<'tcx> InferCtxt<'tcx> { /// ``` /// /// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics - /// of `fn bind` (meaning that its substs contain `N`). + /// of `fn bind` (meaning that its args contain `N`). /// /// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`. /// The assignment `arr = bind(arr)` now tries to equate `N` with `3 + 4`. /// - /// As `3 + 4` contains `N` in its substs, this must not succeed. + /// As `3 + 4` contains `N` in its args, this must not succeed. /// /// See `tests/ui/const-generics/occurs-check/` for more examples where this is relevant. #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 495c250a7..1dbab48fd 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -5,7 +5,7 @@ use super::combine::{CombineFields, ObligationEmittingRelation}; use super::Subtype; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::subst::SubstsRef; +use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; @@ -43,12 +43,12 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.a_is_expected } - fn relate_item_substs( + fn relate_item_args( &mut self, _item_def_id: DefId, - a_subst: SubstsRef<'tcx>, - b_subst: SubstsRef<'tcx>, - ) -> RelateResult<'tcx, SubstsRef<'tcx>> { + a_arg: GenericArgsRef<'tcx>, + b_arg: GenericArgsRef<'tcx>, + ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> { // N.B., once we are equating types, we don't care about // variance, so don't try to lookup the variance here. This // also avoids some cycles (e.g., #41849) since looking up @@ -56,7 +56,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { // performing trait matching (which then performs equality // unification). - relate::relate_substs(self, a_subst, b_subst) + relate::relate_args(self, a_arg, b_arg) } fn relate_with_variance>( 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, 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, 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> { - 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 { - 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>, ) -> Option { - 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: 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::() @@ -797,8 +805,8 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { }; variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::() } - InferSourceKind::FullyQualifiedMethodCall { substs, .. } => { - 20 + substs.iter().map(|arg| ctx.arg_cost(arg)).sum::() + InferSourceKind::FullyQualifiedMethodCall { args, .. } => { + 20 + args.iter().map(|arg| ctx.arg_cost(arg)).sum::() } 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> { - 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> { + 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> { @@ -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> + '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> + '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> + '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>, value_pairs: &ValuePairs<'tcx>, ) -> Option> { - 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>, sup_placeholder: Option>, 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::>() @@ -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 { - 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::, ()>>() 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::, ()>>() + 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`. // 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 Trait 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 Trait 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 `::Foo`. @@ -339,7 +338,7 @@ impl Trait 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 { - 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 { 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) { diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 05769b790..689945d64 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -11,7 +11,7 @@ //! //! To handle closures, freshened types also have to contain the signature and kind of any //! closure in the local inference context, as otherwise the cache key might be invalidated. -//! The way this is done is somewhat hacky - the closure signature is appended to the substs, +//! The way this is done is somewhat hacky - the closure signature is appended to the args, //! as well as the closure kind "encoded" as a type. Also, special handling is needed when //! the closure signature contains a reference to the original closure. //! diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs index 780250167..cf674d5dd 100644 --- a/compiler/rustc_infer/src/infer/generalize.rs +++ b/compiler/rustc_infer/src/infer/generalize.rs @@ -173,21 +173,21 @@ where true } - fn relate_item_substs( + fn relate_item_args( &mut self, item_def_id: DefId, - a_subst: ty::SubstsRef<'tcx>, - b_subst: ty::SubstsRef<'tcx>, - ) -> RelateResult<'tcx, ty::SubstsRef<'tcx>> { + a_subst: ty::GenericArgsRef<'tcx>, + b_subst: ty::GenericArgsRef<'tcx>, + ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> { if self.ambient_variance == ty::Variance::Invariant { // Avoid fetching the variance if we are in an invariant // context; no need, and it can induce dependency cycles // (e.g., #41849). - relate::relate_substs(self, a_subst, b_subst) + relate::relate_args(self, a_subst, b_subst) } else { let tcx = self.tcx(); let opt_variances = tcx.variances_of(item_def_id); - relate::relate_substs_with_variances( + relate::relate_args_with_variances( self, item_def_id, opt_variances, @@ -405,16 +405,16 @@ where } // FIXME: remove this branch once `structurally_relate_consts` is fully // structural. - ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { - let substs = self.relate_with_variance( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => { + let args = self.relate_with_variance( ty::Variance::Invariant, ty::VarianceDiagInfo::default(), - substs, - substs, + args, + args, )?; Ok(ty::Const::new_unevaluated( self.tcx(), - ty::UnevaluatedConst { def, substs }, + ty::UnevaluatedConst { def, args }, c.ty(), )) } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 485e34fe2..60d9d6578 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -837,9 +837,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.var_infos[node_idx].origin.span(), format!( "collect_error_for_expanding_node() could not find \ - error for var {:?} in universe {:?}, lower_bounds={:#?}, \ - upper_bounds={:#?}", - node_idx, node_universe, lower_bounds, upper_bounds + error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \ + upper_bounds={upper_bounds:#?}" ), ); } @@ -943,6 +942,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { generic_ty: Ty<'tcx>, min: ty::Region<'tcx>, ) -> bool { + if let ty::ReError(_) = *min { + return true; + } + match bound { VerifyBound::IfEq(verify_if_eq_b) => { let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b); diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fca32b73d..aaabf1482 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -30,11 +30,11 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BoundVarReplacerDelegate; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::relate::RelateResult; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; pub use rustc_middle::ty::IntVarValue; use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid}; +use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef}; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -332,6 +332,39 @@ pub struct InferCtxt<'tcx> { next_trait_solver: bool, } +impl<'tcx> ty::InferCtxtLike> for InferCtxt<'tcx> { + fn universe_of_ty(&self, ty: ty::InferTy) -> Option { + use InferTy::*; + match ty { + // FIXME(BoxyUwU): this is kind of jank and means that printing unresolved + // ty infers will give you the universe of the var it resolved to not the universe + // it actually had. It also means that if you have a `?0.1` and infer it to `u8` then + // try to print out `?0.1` it will just print `?0`. + TyVar(ty_vid) => match self.probe_ty_var(ty_vid) { + Err(universe) => Some(universe), + Ok(_) => None, + }, + IntVar(_) | FloatVar(_) | FreshTy(_) | FreshIntTy(_) | FreshFloatTy(_) => None, + } + } + + fn universe_of_ct(&self, ct: ty::InferConst<'tcx>) -> Option { + use ty::InferConst::*; + match ct { + // Same issue as with `universe_of_ty` + Var(ct_vid) => match self.probe_const_var(ct_vid) { + Err(universe) => Some(universe), + Ok(_) => None, + }, + Fresh(_) => None, + } + } + + fn universe_of_lt(&self, lt: ty::RegionVid) -> Option { + Some(self.universe_of_region_vid(lt)) + } +} + /// See the `error_reporting` module for more details. #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)] pub enum ValuePairs<'tcx> { @@ -341,6 +374,8 @@ pub enum ValuePairs<'tcx> { TraitRefs(ExpectedFound>), PolyTraitRefs(ExpectedFound>), Sigs(ExpectedFound>), + ExistentialTraitRef(ExpectedFound>), + ExistentialProjection(ExpectedFound>), } impl<'tcx> ValuePairs<'tcx> { @@ -1068,6 +1103,11 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().universe(r) } + /// Return the universe that the region variable `r` was created in. + pub fn universe_of_region_vid(&self, vid: ty::RegionVid) -> ty::UniverseIndex { + self.inner.borrow_mut().unwrap_region_constraints().var_universe(vid) + } + /// Number of region variables created so far. pub fn num_region_vars(&self) -> usize { self.inner.borrow_mut().unwrap_region_constraints().num_region_vars() @@ -1146,8 +1186,8 @@ impl<'tcx> InferCtxt<'tcx> { /// Given a set of generics defined on a type or impl, returns a substitution mapping each /// type/region parameter to a fresh inference variable. - pub fn fresh_substs_for_item(&self, span: Span, def_id: DefId) -> SubstsRef<'tcx> { - InternalSubsts::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) + pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> { + GenericArgs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param)) } /// Returns `true` if errors have been reported since this infcx was @@ -1436,8 +1476,8 @@ impl<'tcx> InferCtxt<'tcx> { /// Obtains the latest type of the given closure; this may be a /// closure in the current function, in which case its /// `ClosureKind` may not yet be known. - pub fn closure_kind(&self, closure_substs: SubstsRef<'tcx>) -> Option { - let closure_kind_ty = closure_substs.as_closure().kind_ty(); + pub fn closure_kind(&self, closure_args: GenericArgsRef<'tcx>) -> Option { + let closure_kind_ty = closure_args.as_closure().kind_ty(); let closure_kind_ty = self.shallow_resolve(closure_kind_ty); closure_kind_ty.to_opt_closure_kind() } @@ -1496,7 +1536,7 @@ impl<'tcx> InferCtxt<'tcx> { /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is /// returned. /// - /// This handles inferences variables within both `param_env` and `substs` by + /// This handles inferences variables within both `param_env` and `args` by /// performing the operation on their respective canonical forms. #[instrument(skip(self), level = "debug")] pub fn const_eval_resolve( @@ -1505,34 +1545,34 @@ impl<'tcx> InferCtxt<'tcx> { unevaluated: ty::UnevaluatedConst<'tcx>, span: Option, ) -> EvalToValTreeResult<'tcx> { - let mut substs = self.resolve_vars_if_possible(unevaluated.substs); - debug!(?substs); + let mut args = self.resolve_vars_if_possible(unevaluated.args); + debug!(?args); - // Postpone the evaluation of constants whose substs depend on inference + // Postpone the evaluation of constants whose args depend on inference // variables let tcx = self.tcx; - if substs.has_non_region_infer() { + if args.has_non_region_infer() { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { - let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs)); + let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args)); if let Err(e) = ct.error_reported() { return Err(ErrorHandled::Reported(e.into())); } else if ct.has_non_region_infer() || ct.has_non_region_param() { return Err(ErrorHandled::TooGeneric); } else { - substs = replace_param_and_infer_substs_with_placeholder(tcx, substs); + args = replace_param_and_infer_args_with_placeholder(tcx, args); } } else { - substs = InternalSubsts::identity_for_item(tcx, unevaluated.def); + args = GenericArgs::identity_for_item(tcx, unevaluated.def); param_env = tcx.param_env(unevaluated.def); } } let param_env_erased = tcx.erase_regions(param_env); - let substs_erased = tcx.erase_regions(substs); + let args_erased = tcx.erase_regions(args); debug!(?param_env_erased); - debug!(?substs_erased); + debug!(?args_erased); - let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, substs: substs_erased }; + let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, args: args_erased }; // The return value is the evaluated value which doesn't contain any reference to inference // variables, thus we don't need to substitute back the original values. @@ -1921,13 +1961,13 @@ impl RegionVariableOrigin { } } -/// Replaces substs that reference param or infer variables with suitable +/// Replaces args that reference param or infer variables with suitable /// placeholders. This function is meant to remove these param and infer -/// substs when they're not actually needed to evaluate a constant. -fn replace_param_and_infer_substs_with_placeholder<'tcx>( +/// args when they're not actually needed to evaluate a constant. +fn replace_param_and_infer_args_with_placeholder<'tcx>( tcx: TyCtxt<'tcx>, - substs: SubstsRef<'tcx>, -) -> SubstsRef<'tcx> { + args: GenericArgsRef<'tcx>, +) -> GenericArgsRef<'tcx> { struct ReplaceParamAndInferWithPlaceholder<'tcx> { tcx: TyCtxt<'tcx>, idx: u32, @@ -1985,5 +2025,5 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( } } - substs.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 }) + args.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 }) } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 71c07f31b..c80491643 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -557,7 +557,7 @@ where // Forbid inference variables in the RHS. self.infcx.tcx.sess.delay_span_bug( self.delegate.span(), - format!("unexpected inference var {:?}", b,), + format!("unexpected inference var {b:?}",), ); Ok(a) } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 5927f79a1..1c3a5c360 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -64,7 +64,7 @@ impl<'tcx> InferCtxt<'tcx> { ct_op: |ct| ct, ty_op: |ty| match *ty.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) - if replace_opaque_type(def_id) => + if replace_opaque_type(def_id) && !ty.has_escaping_bound_vars() => { let def_span = self.tcx.def_span(def_id); let span = if span.contains(def_span) { def_span } else { span }; @@ -103,7 +103,7 @@ impl<'tcx> InferCtxt<'tcx> { } let (a, b) = if a_is_expected { (a, b) } else { (b, a) }; let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) if def_id.is_local() => { + ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); match self.defining_use_anchor { DefiningAnchor::Bind(_) => { @@ -165,7 +165,7 @@ impl<'tcx> InferCtxt<'tcx> { } } Some(self.register_hidden_type( - OpaqueTypeKey { def_id, substs }, + OpaqueTypeKey { def_id, args }, cause.clone(), param_env, b, @@ -214,12 +214,12 @@ impl<'tcx> InferCtxt<'tcx> { /// fn foo<'a, 'b>(..) -> (Foo1<'a>, Foo2<'b>) { .. } /// // ^^^^ ^^ /// // | | - /// // | substs + /// // | args /// // def_id /// ``` /// /// As indicating in the comments above, each of those references - /// is (in the compiler) basically a substitution (`substs`) + /// is (in the compiler) basically a substitution (`args`) /// applied to the type of a suitable `def_id` (which identifies /// `Foo1` or `Foo2`). /// @@ -278,7 +278,7 @@ impl<'tcx> InferCtxt<'tcx> { /// /// We generally prefer to make `<=` constraints, since they /// integrate best into the region solver. To do that, we find the - /// "minimum" of all the arguments that appear in the substs: that + /// "minimum" of all the arguments that appear in the args: that /// is, some region which is less than all the others. In the case /// of `Foo1<'a>`, that would be `'a` (it's the only choice, after /// all). Then we apply that as a least bound to the variables @@ -350,7 +350,7 @@ impl<'tcx> InferCtxt<'tcx> { // opaque type definition. let choice_regions: Lrc>> = Lrc::new( opaque_type_key - .substs + .args .iter() .enumerate() .filter(|(i, _)| variances[*i] == ty::Variance::Invariant) @@ -445,28 +445,32 @@ where } match ty.kind() { - ty::Closure(_, ref substs) => { + ty::Closure(_, ref args) => { // Skip lifetime parameters of the enclosing item(s) - substs.as_closure().tupled_upvars_ty().visit_with(self); - substs.as_closure().sig_as_fn_ptr_ty().visit_with(self); + for upvar in args.as_closure().upvar_tys() { + upvar.visit_with(self); + } + args.as_closure().sig_as_fn_ptr_ty().visit_with(self); } - ty::Generator(_, ref substs, _) => { + ty::Generator(_, ref args, _) => { // Skip lifetime parameters of the enclosing item(s) // Also skip the witness type, because that has no free regions. - substs.as_generator().tupled_upvars_ty().visit_with(self); - substs.as_generator().return_ty().visit_with(self); - substs.as_generator().yield_ty().visit_with(self); - substs.as_generator().resume_ty().visit_with(self); + for upvar in args.as_generator().upvar_tys() { + upvar.visit_with(self); + } + args.as_generator().return_ty().visit_with(self); + args.as_generator().yield_ty().visit_with(self); + args.as_generator().resume_ty().visit_with(self); } - ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref substs, .. }) => { + ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref args, .. }) => { // Skip lifetime parameters that are not captures. let variances = self.tcx.variances_of(*def_id); - for (v, s) in std::iter::zip(variances, substs.iter()) { + for (v, s) in std::iter::zip(variances, args.iter()) { if *v != ty::Variance::Bivariant { s.visit_with(self); } @@ -519,7 +523,7 @@ impl<'tcx> InferCtxt<'tcx> { self.add_item_bounds_for_hidden_type( opaque_type_key.def_id.to_def_id(), - opaque_type_key.substs, + opaque_type_key.args, cause, param_env, hidden_ty, @@ -582,7 +586,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn add_item_bounds_for_hidden_type( &self, def_id: DefId, - substs: ty::SubstsRef<'tcx>, + args: ty::GenericArgsRef<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, hidden_ty: Ty<'tcx>, @@ -591,7 +595,7 @@ impl<'tcx> InferCtxt<'tcx> { let tcx = self.tcx; let item_bounds = tcx.explicit_item_bounds(def_id); - for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) { + for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) { let predicate = predicate.fold_with(&mut BottomUpFolder { tcx, ty_op: |ty| match *ty.kind() { @@ -614,17 +618,11 @@ impl<'tcx> InferCtxt<'tcx> { } // Replace all other mentions of the same opaque type with the hidden type, // as the bounds must hold on the hidden type after all. - ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, substs: substs2, .. }) - if def_id == def_id2 && substs == substs2 => + ty::Alias(ty::Opaque, ty::AliasTy { def_id: def_id2, args: args2, .. }) + if def_id == def_id2 && args == args2 => { hidden_ty } - // FIXME(RPITIT): This can go away when we move to associated types - // FIXME(inherent_associated_types): Extend this to support `ty::Inherent`, too. - ty::Alias( - ty::Projection, - ty::AliasTy { def_id: def_id2, substs: substs2, .. }, - ) if def_id == def_id2 && substs == substs2 => hidden_ty, _ => ty, }, lt_op: |lt| lt, diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index cb63d2f18..2ac9568f6 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -3,8 +3,8 @@ // RFC for reference. use rustc_data_structures::sso::SsoHashSet; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::{GenericArg, GenericArgKind}; use smallvec::{smallvec, SmallVec}; #[derive(Debug)] @@ -71,15 +71,15 @@ fn compute_components<'tcx>( // in the `subtys` iterator (e.g., when encountering a // projection). match *ty.kind() { - ty::FnDef(_, substs) => { - // HACK(eddyb) ignore lifetimes found shallowly in `substs`. - // This is inconsistent with `ty::Adt` (including all substs) - // and with `ty::Closure` (ignoring all substs other than + ty::FnDef(_, args) => { + // HACK(eddyb) ignore lifetimes found shallowly in `args`. + // This is inconsistent with `ty::Adt` (including all args) + // and with `ty::Closure` (ignoring all args other than // upvars, of which a `ty::FnDef` doesn't have any), but // consistent with previous (accidental) behavior. // See https://github.com/rust-lang/rust/issues/70917 // for further background and discussion. - for child in substs { + for child in args { match child.unpack() { GenericArgKind::Type(ty) => { compute_components(tcx, ty, out, visited); @@ -97,14 +97,14 @@ fn compute_components<'tcx>( compute_components(tcx, element, out, visited); } - ty::Closure(_, ref substs) => { - let tupled_ty = substs.as_closure().tupled_upvars_ty(); + ty::Closure(_, ref args) => { + let tupled_ty = args.as_closure().tupled_upvars_ty(); compute_components(tcx, tupled_ty, out, visited); } - ty::Generator(_, ref substs, _) => { + ty::Generator(_, ref args, _) => { // Same as the closure case - let tupled_ty = substs.as_generator().tupled_upvars_ty(); + let tupled_ty = args.as_generator().tupled_upvars_ty(); compute_components(tcx, tupled_ty, out, visited); // We ignore regions in the generator interior as we don't @@ -189,7 +189,7 @@ fn compute_components<'tcx>( } } -/// Collect [Component]s for *all* the substs of `parent`. +/// Collect [Component]s for *all* the args of `parent`. /// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. @@ -201,7 +201,7 @@ pub(super) fn compute_alias_components_recursive<'tcx>( ) { let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; - for (index, child) in alias_ty.substs.iter().enumerate() { + for (index, child) in alias_ty.args.iter().enumerate() { if opt_variances.get(index) == Some(&ty::Bivariant) { continue; } @@ -225,7 +225,7 @@ pub(super) fn compute_alias_components_recursive<'tcx>( } } -/// Collect [Component]s for *all* the substs of `parent`. +/// Collect [Component]s for *all* the args of `parent`. /// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 73df6d03f..f36802e12 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -68,8 +68,8 @@ use crate::infer::{ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::ty::GenericArgKind; +use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt}; use smallvec::smallvec; use super::env::OutlivesEnvironment; @@ -253,7 +253,7 @@ where // this point it never will be self.tcx.sess.delay_span_bug( origin.span(), - format!("unresolved inference variable in outlives: {:?}", v), + format!("unresolved inference variable in outlives: {v:?}"), ); } } @@ -279,7 +279,7 @@ where alias_ty: ty::AliasTy<'tcx>, ) { // An optimization for a common case with opaque types. - if alias_ty.substs.is_empty() { + if alias_ty.args.is_empty() { return; } @@ -348,7 +348,7 @@ where { debug!("no declared bounds"); let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id)); - self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances); + self.args_must_outlive(alias_ty.args, origin, region, opt_variances); return; } @@ -395,15 +395,15 @@ where } #[instrument(level = "debug", skip(self))] - fn substs_must_outlive( + fn args_must_outlive( &mut self, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, opt_variances: Option<&[ty::Variance]>, ) { let constraint = origin.to_constraint_category(); - for (index, k) in substs.iter().enumerate() { + for (index, k) in args.iter().enumerate() { match k.unpack() { GenericArgKind::Lifetime(lt) => { let variance = if let Some(variances) = opt_variances { diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index cd2462d3c..fefa89595 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -157,7 +157,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { a: T, b: T, ) -> RelateResult<'tcx, T> { - // Opaque types substs have lifetime parameters. + // Opaque types args have lifetime parameters. // We must not check them to be equal, as we never insert anything to make them so. if variance != ty::Bivariant { self.relate(a, b) } else { Ok(a) } } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index 1a5e2b520..4279d0ab7 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -179,7 +179,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // this point it never will be self.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, - format!("unresolved inference variable in outlives: {:?}", v), + format!("unresolved inference variable in outlives: {v:?}"), ); // add a bound that never holds VerifyBound::AnyBound(vec![]) @@ -295,7 +295,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { let bounds = tcx.item_bounds(alias_ty.def_id); trace!("{:#?}", bounds.skip_binder()); bounds - .subst_iter(tcx, alias_ty.substs) + .iter_instantiated(tcx, alias_ty.args) .filter_map(|p| p.as_type_outlives_clause()) .filter_map(|p| p.no_bound_vars()) .map(|OutlivesPredicate(_, r)| r) diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index dd65f66cc..b6ff8f2f5 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -425,9 +425,11 @@ impl<'tcx> MiniGraph<'tcx> { } } } else { - for (constraint, _origin) in ®ion_constraints.data().constraints { - each_constraint(constraint) - } + region_constraints + .data() + .constraints + .keys() + .for_each(|constraint| each_constraint(constraint)); } } diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 613da8a0b..708c51cab 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -704,8 +704,8 @@ impl fmt::Debug for RegionSnapshot { impl<'tcx> fmt::Debug for GenericKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - GenericKind::Param(ref p) => write!(f, "{:?}", p), - GenericKind::Alias(ref p) => write!(f, "{:?}", p), + GenericKind::Param(ref p) => write!(f, "{p:?}"), + GenericKind::Alias(ref p) => write!(f, "{p:?}"), } } } @@ -713,8 +713,8 @@ impl<'tcx> fmt::Debug for GenericKind<'tcx> { impl<'tcx> fmt::Display for GenericKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - GenericKind::Param(ref p) => write!(f, "{}", p), - GenericKind::Alias(ref p) => write!(f, "{}", p), + GenericKind::Param(ref p) => write!(f, "{p}"), + GenericKind::Alias(ref p) => write!(f, "{p}"), } } } diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 01c11d163..bc83f8d3f 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -125,7 +125,7 @@ pub enum TypeVariableOriginKind { OpaqueTypeInference(DefId), TypeParameterDefinition(Symbol, DefId), - /// One of the upvars or closure kind parameters in a `ClosureSubsts` + /// One of the upvars or closure kind parameters in a `ClosureArgs` /// (before it has been determined). // FIXME(eddyb) distinguish upvar inference variables from the rest. ClosureSynthetic, diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 11f434694..64b9714c7 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -25,7 +25,7 @@ pub trait TraitEngine<'tcx>: 'tcx { cause, recursion_depth: 0, param_env, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx), + predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx), }, ); } diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 9f440f398..e72a43630 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -28,11 +28,11 @@ impl<'tcx> InferCtxt<'tcx> { if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) { if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) { let item_name = self.tcx.item_name(impl_item_def_id.to_def_id()); - err.span_label(span, format!("definition of `{}` from trait", item_name)); + err.span_label(span, format!("definition of `{item_name}` from trait")); } } - err.span_label(error_span, format!("impl has extra requirement {}", requirement)); + err.span_label(error_span, format!("impl has extra requirement {requirement}")); err } @@ -56,7 +56,7 @@ pub fn report_object_safety_error<'tcx>( "the trait `{}` cannot be made into an object", trait_str ); - err.span_label(span, format!("`{}` cannot be made into an object", trait_str)); + err.span_label(span, format!("`{trait_str}` cannot be made into an object")); let mut reported_violations = FxIndexSet::default(); let mut multi_span = vec![]; diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 626dd9359..a5b2ccce8 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -9,6 +9,7 @@ mod structural_impls; pub mod util; use std::cmp; +use std::hash::{Hash, Hasher}; use hir::def_id::LocalDefId; use rustc_hir as hir; @@ -36,7 +37,7 @@ pub use rustc_middle::traits::*; /// either identifying an `impl` (e.g., `impl Eq for i32`) that /// satisfies the obligation, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone)] pub struct Obligation<'tcx, T> { /// The reason we have to prove this thing. pub cause: ObligationCause<'tcx>, @@ -55,6 +56,27 @@ pub struct Obligation<'tcx, T> { pub recursion_depth: usize, } +impl<'tcx, T: PartialEq> PartialEq> for Obligation<'tcx, T> { + #[inline] + fn eq(&self, other: &Obligation<'tcx, T>) -> bool { + // Ignore `cause` and `recursion_depth`. This is a small performance + // win for a few crates, and a huge performance win for the crate in + // https://github.com/rust-lang/rustc-perf/pull/1680, which greatly + // stresses the trait system. + self.param_env == other.param_env && self.predicate == other.predicate + } +} + +impl Eq for Obligation<'_, T> {} + +impl Hash for Obligation<'_, T> { + fn hash(&self, state: &mut H) -> () { + // See the comment on `Obligation::eq`. + self.param_env.hash(state); + self.predicate.hash(state); + } +} + impl<'tcx, P> From> for solve::Goal<'tcx, P> { fn from(value: Obligation<'tcx, P>) -> Self { solve::Goal { param_env: value.param_env, predicate: value.predicate } @@ -77,25 +99,9 @@ impl<'tcx> PredicateObligation<'tcx> { recursion_depth: self.recursion_depth, }) } - - pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> { - self.param_env = self.param_env.without_const(); - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() { - self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const())))); - } - self - } } impl<'tcx> PolyTraitObligation<'tcx> { - /// Returns `true` if the trait predicate is considered `const` in its ParamEnv. - pub fn is_const(&self) -> bool { - matches!( - (self.predicate.skip_binder().constness, self.param_env.constness()), - (ty::BoundConstness::ConstIfConst, hir::Constness::Const) - ) - } - pub fn derived_cause( &self, variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index e375d6119..afba2e50a 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -190,7 +190,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { } let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy { ty: value, complete: None }); - assert!(!fresh_key, "never started projecting `{:?}`", key); + assert!(!fresh_key, "never started projecting `{key:?}`"); } /// Mark the relevant projection cache key as having its derived obligations @@ -229,7 +229,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { /// be different). pub fn ambiguous(&mut self, key: ProjectionCacheKey<'tcx>) { let fresh = self.map().insert(key, ProjectionCacheEntry::Ambiguous); - assert!(!fresh, "never started projecting `{:?}`", key); + assert!(!fresh, "never started projecting `{key:?}`"); } /// Indicates that while trying to normalize `key`, `key` was required to @@ -237,14 +237,14 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { /// an error here. pub fn recur(&mut self, key: ProjectionCacheKey<'tcx>) { let fresh = self.map().insert(key, ProjectionCacheEntry::Recur); - assert!(!fresh, "never started projecting `{:?}`", key); + assert!(!fresh, "never started projecting `{key:?}`"); } /// Indicates that trying to normalize `key` resulted in /// error. pub fn error(&mut self, key: ProjectionCacheKey<'tcx>) { let fresh = self.map().insert(key, ProjectionCacheEntry::Error); - assert!(!fresh, "never started projecting `{:?}`", key); + assert!(!fresh, "never started projecting `{key:?}`"); } } diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 1563d92af..8a7c59da0 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -38,17 +38,17 @@ impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> { impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - super::CodeSelectionError(ref e) => write!(f, "{:?}", e), - super::CodeProjectionError(ref e) => write!(f, "{:?}", e), + super::CodeSelectionError(ref e) => write!(f, "{e:?}"), + super::CodeProjectionError(ref e) => write!(f, "{e:?}"), super::CodeSubtypeError(ref a, ref b) => { - write!(f, "CodeSubtypeError({:?}, {:?})", a, b) + write!(f, "CodeSubtypeError({a:?}, {b:?})") } super::CodeConstEquateError(ref a, ref b) => { - write!(f, "CodeConstEquateError({:?}, {:?})", a, b) + write!(f, "CodeConstEquateError({a:?}, {b:?})") } super::CodeAmbiguity { overflow: false } => write!(f, "Ambiguity"), super::CodeAmbiguity { overflow: true } => write!(f, "Overflow"), - super::CodeCycle(ref cycle) => write!(f, "Cycle({:?})", cycle), + super::CodeCycle(ref cycle) => write!(f, "Cycle({cycle:?})"), } } } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 074ff7ec9..93dfbe63b 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -25,6 +25,13 @@ impl<'tcx> PredicateSet<'tcx> { Self { tcx, set: Default::default() } } + /// Adds a predicate to the set. + /// + /// Returns whether the predicate was newly inserted. That is: + /// - If the set did not previously contain this predicate, `true` is returned. + /// - If the set already contained this predicate, `false` is returned, + /// and the set is not modified: original predicate is not replaced, + /// and the predicate passed as argument is dropped. pub fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool { // We have to be careful here because we want // @@ -257,11 +264,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { }; let obligations = - predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| { - // when parent predicate is non-const, elaborate it to non-const predicates. - if data.constness == ty::BoundConstness::NotConst { - clause = clause.without_const(tcx); - } + predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| { elaboratable.child_with_derived_cause( clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)), span, -- cgit v1.2.3