diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9299527ce1798..d7f875b285775 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2333,12 +2333,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base: &'tcx hir::Expr<'tcx>, ty: Ty<'tcx>, ) { - let output_ty = match self.get_impl_future_output_ty(ty) { - Some(output_ty) => self.resolve_vars_if_possible(output_ty), - _ => return, - }; + let Some(output_ty) = self.get_impl_future_output_ty(ty) else { return; }; let mut add_label = true; - if let ty::Adt(def, _) = output_ty.skip_binder().kind() { + if let ty::Adt(def, _) = output_ty.kind() { // no field access on enum type if !def.is_enum() { if def diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index c0aff8f240f73..c6a7a9fd2635e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -925,15 +925,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = match self.tcx.asyncness(fn_id.owner) { hir::IsAsync::Async => { let infcx = self.tcx.infer_ctxt().build(); - infcx - .get_impl_future_output_ty(ty) - .unwrap_or_else(|| { - span_bug!( - fn_decl.output.span(), - "failed to get output type of async function" - ) - }) - .skip_binder() + infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| { + span_bug!( + fn_decl.output.span(), + "failed to get output type of async function" + ) + }) } hir::IsAsync::NotAsync => ty, }; diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 5ca74f713afe5..f34f826ba5f9c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1960,7 +1960,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, ) { let output_ty = match self.get_impl_future_output_ty(ty) { - Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(), + Some(output_ty) => self.resolve_vars_if_possible(output_ty), _ => return, }; let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index ecb23e2be7de3..6b6be7359a599 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -74,7 +74,7 @@ use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; use rustc_middle::ty::{ - self, error::TypeError, Binder, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, }; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; @@ -339,16 +339,15 @@ pub fn unexpected_hidden_region_diagnostic<'tcx>( } impl<'tcx> InferCtxt<'tcx> { - pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option>> { - if let ty::Opaque(def_id, substs) = ty.kind() { - let future_trait = self.tcx.require_lang_item(LangItem::Future, None); - // Future::Output - let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; + pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option> { + let ty::Opaque(def_id, substs) = *ty.kind() else { return None; }; - let bounds = self.tcx.bound_explicit_item_bounds(*def_id); + let future_trait = self.tcx.require_lang_item(LangItem::Future, None); + let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - for (predicate, _) in bounds.subst_iter_copied(self.tcx, substs) { - let output = predicate + self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( + |(predicate, _)| { + predicate .kind() .map_bound(|kind| match kind { ty::PredicateKind::Clause(ty::Clause::Projection(projection_predicate)) @@ -358,14 +357,10 @@ impl<'tcx> InferCtxt<'tcx> { } _ => None, }) - .transpose(); - if output.is_some() { - // We don't account for multiple `Future::Output = Ty` constraints. - return output; - } - } - } - None + .no_bound_vars() + .flatten() + }, + ) } } @@ -2055,8 +2050,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } match ( - self.get_impl_future_output_ty(exp_found.expected).map(Binder::skip_binder), - self.get_impl_future_output_ty(exp_found.found).map(Binder::skip_binder), + self.get_impl_future_output_ty(exp_found.expected), + self.get_impl_future_output_ty(exp_found.found), ) { (Some(exp), Some(found)) if self.same_type_modulo_infer(exp, found) => match cause .code()