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

Code before:
            self.tcx,
            ObligationCause::dummy(),
            param_env,
            trait_ref,
        )) {
            diag.downgrade_to_delayed_bug();
        }
        for candidate in self.find_similar_impl_candidates(trait_ref) {
            let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue };
            let impl_did = candidate.impl_def_id;
            let trait_did = candidate.trait_ref.def_id;
            let impl_span = self.tcx.def_span(impl_did);
            let trait_name = self.tcx.item_name(trait_did);

            if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
                if let Some(impl_did) = impl_did.as_local()
                    && let item = self.tcx.hir_expect_item(impl_did)
                    && let hir::ItemKind::Impl(item) = item.kind
                    && let Some(of_trait) = item.of_trait
                {
                    // trait is const, impl is local and not const
                    diag.span_suggestion_verbose(
                        of_trait.path.span.shrink_to_lo(),
                        format!("make the `impl` of trait `{trait_name}` `const`"),
                        "const ".to_string(),
                        Applicability::MachineApplicable,
                    );
                } else {
                    diag.span_note(
                        impl_span,
                        format!("trait `{trait_name}` is implemented but not `const`"),
                    );
                }
            }
        }
        diag
    }

    fn emit_specialized_closure_kind_error(
        &self,
        obligation: &PredicateObligation<'tcx>,
        mut trait_pred: ty::PolyTraitPredicate<'tcx>,
    ) -> Option<ErrorGuaranteed> {
        // If we end up on an `AsyncFnKindHelper` goal, try to unwrap the parent
        // `AsyncFn*` goal.
        if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::AsyncFnKindHelper) {
            let mut code = obligation.cause.code();
            // Unwrap a `FunctionArg` cause, which has been refined from a derived obligation.
            if let ObligationCauseCode::FunctionArg { parent_code, .. } = code {
                code = &**parent_code;
            }

Review comment (suggestion):
I'm not sure if `MachineApplicable` is right here - depending on the impl, it's likely to lead to more errors that we won't be able to fix automatically.

Code after:
        }

        applied_do_not_recommend
    }

    fn report_host_effect_error(
        &self,
        predicate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,
        param_env: ty::ParamEnv<'tcx>,
        span: Span,
    ) -> Diag<'a> {
        // FIXME(const_trait_impl): We should recompute the predicate with `[const]`
        // if it's `const`, and if it holds, explain that this bound only
        // *conditionally* holds. If that fails, we should also do selection
        // to drill this down to an impl or built-in source, so we can
        // point at it and explain that while the trait *is* implemented,
        // that implementation is not const.
        let trait_ref = predicate.map_bound(|predicate| ty::TraitPredicate {
            trait_ref: predicate.trait_ref,
            polarity: ty::PredicatePolarity::Positive,
        });
        let mut file = None;
        let err_msg = self.get_standard_error_message(
            trait_ref,
            None,
            Some(predicate.constness()),
            None,
            String::new(),
            &mut file,
        );
        let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);
        *diag.long_ty_path() = file;
        if !self.predicate_may_hold(&Obligation::new(
            self.tcx,
            ObligationCause::dummy(),
            param_env,
            trait_ref,
        )) {
            diag.downgrade_to_delayed_bug();
        }
        for candidate in self.find_similar_impl_candidates(trait_ref) {
            let CandidateSimilarity::Exact { .. } = candidate.similarity else { continue };
            let impl_did = candidate.impl_def_id;
            let trait_did = candidate.trait_ref.def_id;
            let impl_span = self.tcx.def_span(impl_did);
            let trait_name = self.tcx.item_name(trait_did);

            if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {
                if let Some(impl_did) = impl_did.as_local()
                    && let item = self.tcx.hir_expect_item(impl_did)
                    && let hir::ItemKind::Impl(item) = item.kind