Repository: rust-lang/rust
File: compiler/rustc_hir_analysis/src/collect.rs (Rust)

Code before:
                }
                ty::LateParamRegionKind::Named(def_id) => {
                    bound_vars.iter().enumerate().find_map(|(idx, bv)| match bv {
                        ty::BoundVariableKind::Region(
                            br_kind @ ty::BoundRegionKind::Named(did),
                        ) if did == def_id => Some(ty::BoundRegion {
                            var: ty::BoundVar::from_usize(idx),
                            kind: br_kind,
                        }),
                        _ => None,
                    })
                }
                ty::LateParamRegionKind::ClosureEnv => {
                    bound_vars.iter().enumerate().find_map(|(idx, bv)| match bv {
                        ty::BoundVariableKind::Region(
                            br_kind @ ty::BoundRegionKind::ClosureEnv,
                        ) => Some(ty::BoundRegion {
                            var: ty::BoundVar::from_usize(idx),
                            kind: br_kind,
                        }),
                        _ => None,
                    })
                }
            };

            br.map(|br| ty::Region::new_bound(tcx, ty::INNERMOST, br))
                .unwrap_or_else(|| ty::Region::new_error(tcx, guar))
        }
        _ => r,
    });

    ty::Binder::bind_with_vars(fn_sig, bound_vars)
}

pub fn suggest_impl_trait<'tcx>(
    infcx: &InferCtxt<'tcx>,
    param_env: ty::ParamEnv<'tcx>,
    ret_ty: Ty<'tcx>,
) -> Option<String> {
    let format_as_assoc: fn(_, _, _, _, _) -> _ =
        |tcx: TyCtxt<'tcx>,
         _: ty::GenericArgsRef<'tcx>,
         trait_def_id: DefId,
         assoc_item_def_id: DefId,
         item_ty: Ty<'tcx>| {
            let trait_name = tcx.item_name(trait_def_id);
            let assoc_name = tcx.item_name(assoc_item_def_id);
            Some(format!("impl {trait_name}<{assoc_name} = {item_ty}>"))
        };
    let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
        |tcx: TyCtxt<'tcx>,

Review comment (bug):
`ty::INNERMOST` is wrong, u need to use the binder from the closure argument.

Also, can you move this into a utility function `fn late_param_regions_to_bound` or sth like this. I think this code is too general (and somewhat subtle to understand) for it to be inline here

Code after:
        }
        _ => r,
    });

    let mut visitor = HirPlaceholderCollector::default();
    visitor.visit_ty_unambig(infer_ret_ty);

    let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
    let ret_ty = fn_sig.output();

    // Don't leak types into signatures unless they're nameable!
    // For example, if a function returns itself, we don't want that
    // recursive function definition to leak out into the fn sig.
    let mut recovered_ret_ty = None;
    if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
        diag.span_suggestion_verbose(
            infer_ret_ty.span,
            "replace with the correct return type",
            suggestable_ret_ty,
            Applicability::MachineApplicable,
        );
        recovered_ret_ty = Some(suggestable_ret_ty);
    } else if let Some(sugg) = suggest_impl_trait(
        &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
        tcx.param_env(def_id),
        ret_ty,
    ) {
        diag.span_suggestion_verbose(
            infer_ret_ty.span,
            "replace with an appropriate return type",
            sugg,
            Applicability::MachineApplicable,
        );
    } else if ret_ty.is_closure() {
        diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
    }

    // Also note how `Fn` traits work just in case!
    if ret_ty.is_closure() {
        diag.note(
            "for more information on `Fn` traits and closure types, see \
                     https://doc.rust-lang.org/book/ch13-01-closures.html",
        );
    }
    let guar = diag.emit();

    // If we return a dummy binder here, we can ICE later in borrowck when it encounters
    // `ReLateParam` regions (e.g. in a local type annotation) which weren't registered via the
    // signature binder. See #135845.
    let bound_vars = tcx.late_bound_vars(hir_id);
    let scope = def_id.to_def_id();