Repository: rust-lang/rust
File: compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs (Rust)

Code before:
            self.mk_trait_obligation_with_new_self_ty(obligation.param_env, trait_pred_and_self);
        if !self.predicate_must_hold_modulo_regions(&new_obligation) {
            return false;
        }

        // If this is a zero-argument async closure directly passed as an argument
        // and the expected type is `Future`, suggest using `async {}` block instead
        // of `async || {}`.
        if let ty::CoroutineClosure(def_id, args) = *self_ty.kind()
            && let sig = args.as_coroutine_closure().coroutine_closure_sig().skip_binder()
            && let ty::Tuple(inputs) = *sig.tupled_inputs_ty.kind()
            && inputs.is_empty()
            && self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Future)
            && let Some(hir::Node::Expr(hir::Expr {
                kind:
                    hir::ExprKind::Closure(hir::Closure {
                        kind: hir::ClosureKind::CoroutineClosure(CoroutineDesugaring::Async),
                        fn_arg_span: Some(arg_span),
                        ..
                    }),
                ..
            })) = self.tcx.hir_get_if_local(def_id)
            && obligation.cause.span.contains(*arg_span)
        {
            err.span_suggestion_verbose(
                arg_span.with_hi(arg_span.hi() + rustc_span::BytePos(1)),
                "use `async {}` instead of `async || {}` to introduce an async block",
                "",
                Applicability::MachineApplicable,
            );
            return true;
        }

        // Get the name of the callable and the arguments to be used in the suggestion.
        let msg = match def_id_or_name {
            DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
                DefKind::Ctor(CtorOf::Struct, _) => {
                    Cow::from("use parentheses to construct this tuple struct")
                }
                DefKind::Ctor(CtorOf::Variant, _) => {
                    Cow::from("use parentheses to construct this tuple variant")
                }
                kind => Cow::from(format!(
                    "use parentheses to call this {}",
                    self.tcx.def_kind_descr(kind, def_id)
                )),
            },
            DefIdOrName::Name(name) => Cow::from(format!("use parentheses to call this {name}")),
        };

        let args = inputs

Review comment (bug):
It's an edge-case but the suggestion would be broken if there's no whitespace, like:
```rs
takes_future(async||{
```

Code after:
        if let ty::CoroutineClosure(def_id, args) = *self_ty.kind()
            && let sig = args.as_coroutine_closure().coroutine_closure_sig().skip_binder()
            && let ty::Tuple(inputs) = *sig.tupled_inputs_ty.kind()
            && inputs.is_empty()
            && self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Future)
            && let Some(hir::Node::Expr(hir::Expr {
                kind:
                    hir::ExprKind::Closure(hir::Closure {
                        kind: hir::ClosureKind::CoroutineClosure(CoroutineDesugaring::Async),
                        fn_arg_span: Some(arg_span),
                        ..
                    }),
                ..
            })) = self.tcx.hir_get_if_local(def_id)
            && obligation.cause.span.contains(*arg_span)
        {
            let sm = self.tcx.sess.source_map();
            let removal_span = if let Ok(snippet) =
                sm.span_to_snippet(arg_span.with_hi(arg_span.hi() + rustc_span::BytePos(1)))
                && snippet.ends_with(' ')
            {
                // There's a space after `||`, include it in the removal
                arg_span.with_hi(arg_span.hi() + rustc_span::BytePos(1))
            } else {
                *arg_span
            };
            err.span_suggestion_verbose(
                removal_span,
                "use `async {}` instead of `async || {}` to introduce an async block",
                "",
                Applicability::MachineApplicable,
            );
            return true;
        }

        // Get the name of the callable and the arguments to be used in the suggestion.
        let msg = match def_id_or_name {
            DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) {
                DefKind::Ctor(CtorOf::Struct, _) => {
                    Cow::from("use parentheses to construct this tuple struct")
                }
                DefKind::Ctor(CtorOf::Variant, _) => {
                    Cow::from("use parentheses to construct this tuple variant")
                }
                kind => Cow::from(format!(
                    "use parentheses to call this {}",
                    self.tcx.def_kind_descr(kind, def_id)
                )),
            },
            DefIdOrName::Name(name) => Cow::from(format!("use parentheses to call this {name}")),
        };