Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should look like: <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --
Huh, looks like this is a case where doesn't kick in for some reason.
Ah, it's that the return type of an async function like this has . I don't know enough about rustc's typechecking to know whether this can be resolved haha.
It doesn't seem like the problem that caused is a thing anymore? I can remove the condition and it doesn't ICE on the example given in that issue.
do you know if stuff has changed such that is no longer necessary?
I actually have a PR almost up that does just exactly that, though if you want to put one up instead then feel free.
I'm pretty sure fixes this underlying issue. This method could use some additional cleanup as well.

Discussion:
use crate::autoderef::Autoderef; use crate::infer::InferCtxt; <del> use crate::traits::normalize_projection_type; </del> <ins> use crate::traits::normalize_to; </ins> use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::stack::ensure_sufficient_stack;

let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); <del> // Do not check on infer_types to avoid panic in evaluate_obligation. if self_ty.has_infer_types() { return; } let self_ty = self.tcx.erase_regions(self_ty); </del> let impls_future = self.type_implements_trait( future_trait, <del> self_ty.skip_binder(), </del> <ins> self.tcx.erase_late_bound_regions(self_ty), </ins> ty::List::empty(), obligation.param_env, ); <ins> if !impls_future.must_apply_modulo_regions() { return; } </ins> let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; // `<T as Future>::Output` <del> let projection_ty = ty::ProjectionTy { // `T` substs: self.tcx.mk_substs_trait( trait_pred.self_ty().skip_binder(), &self.fresh_substs_for_item(span, item_def_id)[1..], ), // `Future::Output` item_def_id, }; let mut selcx = SelectionContext::new(self); let mut obligations = vec![]; let normalized_ty = normalize_projection_type( &mut selcx, </del> <ins> let projection_ty = trait_pred.map_bound(|trait_pred| { self.tcx.mk_projection( item_def_id, // Future::Output has no substs self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]), ) }); let projection_ty = normalize_to( &mut SelectionContext::new(self), </ins> obligation.param_env, <del> projection_ty, </del> obligation.cause.clone(), <del> 0, &mut obligations, </del> <ins> projection_ty, &mut vec![], </ins> ); debug!( "suggest_await_before_try: normalized_projection_type {:?}", <del> self.resolve_vars_if_possible(normalized_ty) </del> <ins> self.resolve_vars_if_possible(projection_ty) </ins> ); let try_obligation = self.mk_trait_obligation_with_new_self_ty( obligation.param_env, <del> trait_pred.map_bound(|trait_pred| (trait_pred, normalized_ty.ty().unwrap())), </del> <ins> trait_pred.map_bound(|trait_pred| (trait_pred, projection_ty.skip_binder())), </ins> ); debug!("suggest_await_before_try: try_trait_obligation {:?}", try_obligation); if self.predicate_may_hold(&try_obligation) <del> && impls_future.must_apply_modulo_regions() </del> && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) && snippet.ends_with('?') {

<ins> // edition:2021 // run-rustfix #![allow(unused)] use std::future::Future; async fn foo() -> Result<(), i32> { func(async { Ok::<_, i32>(()) }).await?; //~^ ERROR the `?` operator can only be applied to values that implement `Try` Ok(()) } async fn func<T>(fut: impl Future<Output = T>) -> T { fut.await } fn main() {} </ins>

<ins> // edition:2021 // run-rustfix #![allow(unused)] use std::future::Future; async fn foo() -> Result<(), i32> { func(async { Ok::<_, i32>(()) })?; //~^ ERROR the `?` operator can only be applied to values that implement `Try` Ok(()) } async fn func<T>(fut: impl Future<Output = T>) -> T { fut.await } fn main() {} </ins>

<ins> error[E0277]: the `?` operator can only be applied to values that implement `Try` --> $DIR/issue-97704.rs:9:5 | LL |     func(async { Ok::<_, i32>(()) })?; |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future<Output = Result<(), i32>>` | = help: the trait `Try` is not implemented for `impl Future<Output = Result<(), i32>>` help: consider `await`ing on the `Future` | LL |     func(async { Ok::<_, i32>(()) }).await?; |                                     ++++++ error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>