compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs RUST 3,744 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,744.
1// ignore-tidy-filelength2use core::ops::ControlFlow;3use std::borrow::Cow;4use std::collections::hash_set;5use std::path::PathBuf;67use rustc_ast::ast::LitKind;8use rustc_ast::{LitIntType, TraitObjectSyntax};9use rustc_data_structures::fx::{FxHashMap, FxHashSet};10use rustc_data_structures::unord::UnordSet;11use rustc_errors::codes::*;12use rustc_errors::{13    Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions, msg,14    pluralize, struct_span_code_err,15};16use rustc_hir::attrs::diagnostic::CustomDiagnostic;17use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};18use rustc_hir::intravisit::Visitor;19use rustc_hir::{self as hir, LangItem, Node, find_attr};20use rustc_infer::infer::{InferOk, TypeTrace};21use rustc_infer::traits::ImplSource;22use rustc_infer::traits::solve::Goal;23use rustc_middle::traits::SignatureMismatchData;24use rustc_middle::traits::select::OverflowError;25use rustc_middle::ty::abstract_const::NotConstEvaluatable;26use rustc_middle::ty::error::{ExpectedFound, TypeError};27use rustc_middle::ty::print::{28    PrintPolyTraitPredicateExt, PrintPolyTraitRefExt as _, PrintTraitPredicateExt as _,29    PrintTraitRefExt as _, with_forced_trimmed_paths,30};31use rustc_middle::ty::{32    self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,33    TypeVisitableExt, Unnormalized, Upcast,34};35use rustc_middle::{bug, span_bug};36use rustc_span::def_id::CrateNum;37use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym};38use tracing::{debug, instrument};3940use super::suggestions::get_explanation_based_on_obligation;41use super::{ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate};42use crate::error_reporting::TypeErrCtxt;43use crate::error_reporting::infer::TyCategory;44use crate::error_reporting::traits::report_dyn_incompatibility;45use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, CoroClosureNotFn};46use crate::infer::{self, InferCtxt, InferCtxtExt as _};47use crate::traits::query::evaluate_obligation::InferCtxtExt as _;48use crate::traits::{49    MismatchedProjectionTypes, NormalizeExt, Obligation, ObligationCause, ObligationCauseCode,50    ObligationCtxt, PredicateObligation, SelectionContext, SelectionError, elaborate,51    specialization_graph,52};5354impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {55    /// The `root_obligation` parameter should be the `root_obligation` field56    /// from a `FulfillmentError`. If no `FulfillmentError` is available,57    /// then it should be the same as `obligation`.58    pub fn report_selection_error(59        &self,60        mut obligation: PredicateObligation<'tcx>,61        root_obligation: &PredicateObligation<'tcx>,62        error: &SelectionError<'tcx>,63    ) -> ErrorGuaranteed {64        let tcx = self.tcx;65        let mut span = obligation.cause.span;66        let mut long_ty_file = None;6768        let mut err = match *error {69            SelectionError::Unimplemented => {70                // If this obligation was generated as a result of well-formedness checking, see if we71                // can get a better error message by performing HIR-based well-formedness checking.72                if let ObligationCauseCode::WellFormed(Some(wf_loc)) =73                    root_obligation.cause.code().peel_derives()74                    && !obligation.predicate.has_non_region_infer()75                {76                    if let Some(cause) = self77                        .tcx78                        .diagnostic_hir_wf_check((tcx.erase_and_anonymize_regions(obligation.predicate), *wf_loc))79                    {80                        obligation.cause = cause.clone();81                        span = obligation.cause.span;82                    }83                }8485                if let ObligationCauseCode::CompareImplItem {86                    impl_item_def_id,87                    trait_item_def_id,88                    kind: _,89                } = *obligation.cause.code()90                {91                    debug!("ObligationCauseCode::CompareImplItemObligation");92                    return self.report_extra_impl_obligation(93                        span,94                        impl_item_def_id,95                        trait_item_def_id,96                        &format!("`{}`", obligation.predicate),97                    )98                    .emit()99                }100101                // Report a const-param specific error102                if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives()103                {104                    return self.report_const_param_not_wf(ty, &obligation).emit();105                }106107                let bound_predicate = obligation.predicate.kind();108                match bound_predicate.skip_binder() {109                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {110                        let leaf_trait_predicate =111                            self.resolve_vars_if_possible(bound_predicate.rebind(trait_predicate));112113                        // Let's use the root obligation as the main message, when we care about the114                        // most general case ("X doesn't implement Pattern<'_>") over the case that115                        // happened to fail ("char doesn't implement Fn(&mut char)").116                        //117                        // We rely on a few heuristics to identify cases where this root118                        // obligation is more important than the leaf obligation:119                        let (main_trait_predicate, main_obligation) = if let ty::PredicateKind::Clause(120                            ty::ClauseKind::Trait(root_pred)121                        ) = root_obligation.predicate.kind().skip_binder()122                            && !leaf_trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()123                            && !root_pred.self_ty().has_escaping_bound_vars()124                            // The type of the leaf predicate is (roughly) the same as the type125                            // from the root predicate, as a proxy for "we care about the root"126                            // FIXME: this doesn't account for trivial derefs, but works as a first127                            // approximation.128                            && (129                                // `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`130                                self.can_eq(131                                    obligation.param_env,132                                    leaf_trait_predicate.self_ty().skip_binder(),133                                    root_pred.self_ty().peel_refs(),134                                )135                                // `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`136                                || self.can_eq(137                                    obligation.param_env,138                                    leaf_trait_predicate.self_ty().skip_binder(),139                                    root_pred.self_ty(),140                                )141                            )142                            // The leaf trait and the root trait are different, so as to avoid143                            // talking about `&mut T: Trait` and instead remain talking about144                            // `T: Trait` instead145                            && leaf_trait_predicate.def_id() != root_pred.def_id()146                            // The root trait is not `Unsize`, as to avoid talking about it in147                            // `tests/ui/coercion/coerce-issue-49593-box-never.rs`.148                            && !self.tcx.is_lang_item(root_pred.def_id(), LangItem::Unsize)149                        {150                            (151                                self.resolve_vars_if_possible(152                                    root_obligation.predicate.kind().rebind(root_pred),153                                ),154                                root_obligation,155                            )156                        } else {157                            (leaf_trait_predicate, &obligation)158                        };159160                        if let Some(guar) = self.emit_specialized_closure_kind_error(161                            &obligation,162                            leaf_trait_predicate,163                        ) {164                            return guar;165                        }166167                        if let Err(guar) = leaf_trait_predicate.error_reported()168                        {169                            return guar;170                        }171                        // Silence redundant errors on binding access that are already172                        // reported on the binding definition (#56607).173                        if let Err(guar) = self.fn_arg_obligation(&obligation) {174                            return guar;175                        }176                        let (post_message, pre_message, type_def) = self177                            .get_parent_trait_ref(obligation.cause.code())178                            .map(|(t, s)| {179                                let t = self.tcx.short_string(t, &mut long_ty_file);180                                (181                                    format!(" in `{t}`"),182                                    format!("within `{t}`, "),183                                    s.map(|s| (format!("within this `{t}`"), s)),184                                )185                            })186                            .unwrap_or_default();187188                        let CustomDiagnostic {189                            message,190                            label,191                            notes,192                            parent_label,193                        } = self.on_unimplemented_note(main_trait_predicate, main_obligation, &mut long_ty_file);194195                        let have_alt_message = message.is_some() || label.is_some();196197                        let message = message.unwrap_or_else(|| self.get_standard_error_message(198                            main_trait_predicate,199                            None,200                            post_message,201                            &mut long_ty_file,202                        ));203                        let is_try_conversion = self.is_try_conversion(span, main_trait_predicate.def_id());204                        let is_question_mark = matches!(205                            root_obligation.cause.code().peel_derives(),206                            ObligationCauseCode::QuestionMark,207                        ) && !(208                            self.tcx.is_diagnostic_item(sym::FromResidual, main_trait_predicate.def_id())209                                || self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::Try)210                        );211                        let is_unsize =212                            self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Unsize);213                        let question_mark_message = "the question mark operation (`?`) implicitly \214                                                     performs a conversion on the error value \215                                                     using the `From` trait";216                        let (message, notes) = if is_try_conversion {217                            let ty = self.tcx.short_string(218                                main_trait_predicate.skip_binder().self_ty(),219                                &mut long_ty_file,220                            );221                            // We have a `-> Result<_, E1>` and `gives_E2()?`.222                            (223                                format!("`?` couldn't convert the error to `{ty}`"),224                                vec![question_mark_message.to_owned()],225                            )226                        } else if is_question_mark {227                            let main_trait_predicate =228                                self.tcx.short_string(main_trait_predicate, &mut long_ty_file);229                            // Similar to the case above, but in this case the conversion is for a230                            // trait object: `-> Result<_, Box<dyn Error>` and `gives_E()?` when231                            // `E: Error` isn't met.232                            (233                                format!(234                                    "`?` couldn't convert the error: `{main_trait_predicate}` is \235                                     not satisfied",236                                ),237                                vec![question_mark_message.to_owned()],238                            )239                        } else {240                            (message, notes)241                        };242243                        let (err_msg, safe_transmute_explanation) = if self.tcx.is_lang_item(244                            main_trait_predicate.def_id(),245                            LangItem::TransmuteTrait,246                        ) {247                            // Recompute the safe transmute reason and use that for the error reporting248                            let (report_obligation, report_pred) =249                                self.select_transmute_obligation_for_reporting(250                                    &obligation,251                                    main_trait_predicate,252                                    root_obligation,253                                );254255                            match self.get_safe_transmute_error_and_reason(256                                report_obligation,257                                report_pred,258                                span,259                            ) {260                                GetSafeTransmuteErrorAndReason::Silent => {261                                    return self.dcx().span_delayed_bug(262                                        span, "silent safe transmute error"263                                    );264                                }265                                GetSafeTransmuteErrorAndReason::Default => {266                                    (message, None)267                                }268                                GetSafeTransmuteErrorAndReason::Error {269                                    err_msg,270                                    safe_transmute_explanation,271                                } => (err_msg, safe_transmute_explanation),272                            }273                        } else {274                            (message, None)275                        };276277                        let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);278279                        let trait_def_id = main_trait_predicate.def_id();280                        let leaf_trait_def_id = leaf_trait_predicate.def_id();281                        if (self.tcx.is_diagnostic_item(sym::From, trait_def_id)282                            || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id))283                            && (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id)284                                || self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id))285                        {286                            let trait_ref = leaf_trait_predicate.skip_binder().trait_ref;287288                            if let Some(found_ty) = trait_ref.args.get(1).and_then(|arg| arg.as_type())289                            {290                                let ty = main_trait_predicate.skip_binder().self_ty();291292                                if let Some(cast_ty) = self.find_explicit_cast_type(293                                    obligation.param_env,294                                    found_ty,295                                    ty,296                                ) {297                                    let found_ty_str =298                                        self.tcx.short_string(found_ty, &mut long_ty_file);299                                    let cast_ty_str =300                                        self.tcx.short_string(cast_ty, &mut long_ty_file);301302                                    err.help(format!(303                                        "consider casting the `{found_ty_str}` value to `{cast_ty_str}`",304                                    ));305                                }306                            }307                        }308309310                        *err.long_ty_path() = long_ty_file;311312                        let mut suggested = false;313                        let mut noted_missing_impl = false;314                        if is_try_conversion || is_question_mark {315                            (suggested, noted_missing_impl) = self.try_conversion_context(&obligation, main_trait_predicate, &mut err);316                        }317318                        suggested |= self.detect_negative_literal(319                            &obligation,320                            main_trait_predicate,321                            &mut err,322                        );323324                        if let Some(ret_span) = self.return_type_span(&obligation) {325                            if is_try_conversion {326                                let ty = self.tcx.short_string(327                                    main_trait_predicate.skip_binder().self_ty(),328                                    err.long_ty_path(),329                                );330                                err.span_label(331                                    ret_span,332                                    format!("expected `{ty}` because of this"),333                                );334                            } else if is_question_mark {335                                let main_trait_predicate =336                                    self.tcx.short_string(main_trait_predicate, err.long_ty_path());337                                err.span_label(338                                    ret_span,339                                    format!("required `{main_trait_predicate}` because of this"),340                                );341                            }342                        }343344                        if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Tuple) {345                            self.add_tuple_trait_message(346                                obligation.cause.code().peel_derives(),347                                &mut err,348                            );349                        }350351                        let explanation = get_explanation_based_on_obligation(352                            self.tcx,353                            &obligation,354                            leaf_trait_predicate,355                            pre_message,356                            err.long_ty_path(),357                        );358359                        self.check_for_binding_assigned_block_without_tail_expression(360                            &obligation,361                            &mut err,362                            leaf_trait_predicate,363                        );364                        self.suggest_add_result_as_return_type(365                            &obligation,366                            &mut err,367                            leaf_trait_predicate,368                        );369370                        if self.suggest_add_reference_to_arg(371                            &obligation,372                            &mut err,373                            leaf_trait_predicate,374                            have_alt_message,375                        ) {376                            self.note_obligation_cause(&mut err, &obligation);377                            return err.emit();378                        }379380                        let ty_span = match leaf_trait_predicate.self_ty().skip_binder().kind() {381                            ty::Adt(def, _) if def.did().is_local()382                                && !self.can_suggest_derive(&obligation, leaf_trait_predicate) => self.tcx.def_span(def.did()),383                            _ => DUMMY_SP,384                        };385                        if let Some(s) = label {386                            // If it has a custom `#[rustc_on_unimplemented]`387                            // error message, let's display it as the label!388                            err.span_label(span, s);389                            if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_))390                                // When the self type is a type param We don't need to "the trait391                                // `std::marker::Sized` is not implemented for `T`" as we will point392                                // at the type param with a label to suggest constraining it.393                                && !self.tcx.is_diagnostic_item(sym::FromResidual, leaf_trait_predicate.def_id())394                                    // Don't say "the trait `FromResidual<Option<Infallible>>` is395                                    // not implemented for `Result<T, E>`".396                            {397                                // We do this just so that the JSON output's `help` position is the398                                // right one and not `file.rs:1:1`. The render is the same.399                                if ty_span == DUMMY_SP {400                                    err.help(explanation);401                                } else {402                                    err.span_help(ty_span, explanation);403                                }404                            }405                        } else if let Some(custom_explanation) = safe_transmute_explanation {406                            err.span_label(span, custom_explanation);407                        } else if (explanation.len() > self.tcx.sess.diagnostic_width() || ty_span != DUMMY_SP) && !noted_missing_impl {408                            // Really long types don't look good as span labels, instead move it409                            // to a `help`.410                            err.span_label(span, "unsatisfied trait bound");411412                            // We do this just so that the JSON output's `help` position is the413                            // right one and not `file.rs:1:1`. The render is the same.414                            if ty_span == DUMMY_SP {415                                err.help(explanation);416                            } else {417                                err.span_help(ty_span, explanation);418                            }419                        } else {420                            err.span_label(span, explanation);421                        }422423                        if let ObligationCauseCode::Coercion { source, target } =424                            *obligation.cause.code().peel_derives()425                        {426                            if self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Sized) {427                                self.suggest_borrowing_for_object_cast(428                                    &mut err,429                                    root_obligation,430                                    source,431                                    target,432                                );433                            }434                        }435436                        if let Some((msg, span)) = type_def {437                            err.span_label(span, msg);438                        }439                        for note in notes {440                            // If it has a custom `#[rustc_on_unimplemented]` note, let's display it441                            err.note(note);442                        }443                        if let Some(s) = parent_label {444                            let body = obligation.cause.body_id;445                            err.span_label(tcx.def_span(body), s);446                        }447448                        self.suggest_floating_point_literal(&obligation, &mut err, leaf_trait_predicate);449                        self.suggest_dereferencing_index(&obligation, &mut err, leaf_trait_predicate);450                        suggested |= self.suggest_dereferences(&obligation, &mut err, leaf_trait_predicate);451                        suggested |= self.suggest_fn_call(&obligation, &mut err, leaf_trait_predicate);452                        suggested |= self.suggest_cast_to_fn_pointer(453                            &obligation,454                            &mut err,455                            leaf_trait_predicate,456                            main_trait_predicate,457                            span,458                        );459                        suggested |=460                            self.suggest_remove_reference(&obligation, &mut err, leaf_trait_predicate);461                        suggested |= self.suggest_semicolon_removal(462                            &obligation,463                            &mut err,464                            span,465                            leaf_trait_predicate,466                        );467                        self.note_different_trait_with_same_name(&mut err, &obligation, leaf_trait_predicate);468                        self.note_adt_version_mismatch(&mut err, leaf_trait_predicate);469                        self.suggest_remove_await(&obligation, &mut err);470                        self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);471472                        if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Try) {473                            self.suggest_await_before_try(474                                &mut err,475                                &obligation,476                                leaf_trait_predicate,477                                span,478                            );479                        }480481                        if self.suggest_add_clone_to_arg(&obligation, &mut err, leaf_trait_predicate) {482                            return err.emit();483                        }484485                        if self.suggest_impl_trait(&mut err, &obligation, leaf_trait_predicate) {486                            return err.emit();487                        }488489                        if is_unsize {490                            // If the obligation failed due to a missing implementation of the491                            // `Unsize` trait, give a pointer to why that might be the case492                            err.note(493                                "all implementations of `Unsize` are provided \494                                automatically by the compiler, see \495                                <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> \496                                for more information",497                            );498                        }499500                        let is_fn_trait = tcx.is_fn_trait(leaf_trait_predicate.def_id());501                        let is_target_feature_fn = if let ty::FnDef(def_id, _) =502                            *leaf_trait_predicate.skip_binder().self_ty().kind()503                        {504                            !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()505                        } else {506                            false507                        };508                        if is_fn_trait && is_target_feature_fn {509                            err.note(510                                "`#[target_feature]` functions do not implement the `Fn` traits",511                            );512                            err.note(513                                "try casting the function to a `fn` pointer or wrapping it in a closure",514                            );515                        }516517                        self.note_field_shadowed_by_private_candidate_in_cause(518                            &mut err,519                            &obligation.cause,520                            obligation.param_env,521                        );522                        self.try_to_add_help_message(523                            &root_obligation,524                            &obligation,525                            leaf_trait_predicate,526                            &mut err,527                            span,528                            is_fn_trait,529                            suggested,530                        );531532                        // Changing mutability doesn't make a difference to whether we have533                        // an `Unsize` impl (Fixes ICE in #71036)534                        if !is_unsize {535                            self.suggest_change_mut(&obligation, &mut err, leaf_trait_predicate);536                        }537538                        // If this error is due to `!: Trait` not implemented but `(): Trait` is539                        // implemented, and fallback has occurred, then it could be due to a540                        // variable that used to fallback to `()` now falling back to `!`. Issue a541                        // note informing about the change in behaviour.542                        if leaf_trait_predicate.skip_binder().self_ty().is_never()543                            && self.diverging_fallback_has_occurred544                        {545                            let predicate = leaf_trait_predicate.map_bound(|trait_pred| {546                                trait_pred.with_replaced_self_ty(self.tcx, tcx.types.unit)547                            });548                            let unit_obligation = obligation.with(tcx, predicate);549                            if self.predicate_may_hold(&unit_obligation) {550                                err.note(551                                    "this error might have been caused by changes to \552                                    Rust's type-inference algorithm (see issue #148922 \553                                    <https://github.com/rust-lang/rust/issues/148922> \554                                    for more information)",555                                );556                                err.help("you might have intended to use the type `()` here instead");557                            }558                        }559560                        self.explain_hrtb_projection(&mut err, leaf_trait_predicate, obligation.param_env, &obligation.cause);561                        self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_predicate);562563                        // Return early if the trait is Debug or Display and the invocation564                        // originates within a standard library macro, because the output565                        // is otherwise overwhelming and unhelpful (see #85844 for an566                        // example).567568                        let in_std_macro =569                            match obligation.cause.span.ctxt().outer_expn_data().macro_def_id {570                                Some(macro_def_id) => {571                                    let crate_name = tcx.crate_name(macro_def_id.krate);572                                    STDLIB_STABLE_CRATES.contains(&crate_name)573                                }574                                None => false,575                            };576577                        if in_std_macro578                            && matches!(579                                self.tcx.get_diagnostic_name(leaf_trait_predicate.def_id()),580                                Some(sym::Debug | sym::Display)581                            )582                        {583                            return err.emit();584                        }585586                        err587                    }588589                    ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {590                        self.report_host_effect_error(bound_predicate.rebind(predicate), &obligation, span)591                    }592593                    ty::PredicateKind::Subtype(predicate) => {594                        // Errors for Subtype predicates show up as595                        // `FulfillmentErrorCode::SubtypeError`,596                        // not selection error.597                        span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)598                    }599600                    ty::PredicateKind::Coerce(predicate) => {601                        // Errors for Coerce predicates show up as602                        // `FulfillmentErrorCode::SubtypeError`,603                        // not selection error.604                        span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)605                    }606607                    ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))608                    | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => {609                        span_bug!(610                            span,611                            "outlives clauses should not error outside borrowck. obligation: `{:?}`",612                            obligation613                        )614                    }615616                    ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {617                        span_bug!(618                            span,619                            "projection clauses should be implied from elsewhere. obligation: `{:?}`",620                            obligation621                        )622                    }623624                    ty::PredicateKind::DynCompatible(trait_def_id) => {625                        let violations = self.tcx.dyn_compatibility_violations(trait_def_id);626                        let mut err = report_dyn_incompatibility(627                            self.tcx,628                            span,629                            None,630                            trait_def_id,631                            violations,632                        );633                        if let hir::Node::Item(item) =634                            self.tcx.hir_node_by_def_id(obligation.cause.body_id)635                            && let hir::ItemKind::Impl(impl_) = item.kind636                            && let None = impl_.of_trait637                            && let hir::TyKind::TraitObject(_, tagged_ptr) = impl_.self_ty.kind638                            && let TraitObjectSyntax::None = tagged_ptr.tag()639                            && impl_.self_ty.span.edition().at_least_rust_2021()640                        {641                            // Silence the dyn-compatibility error in favor of the missing dyn on642                            // self type error. #131051.643                            err.downgrade_to_delayed_bug();644                        }645                        err646                    }647648                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {649                        let ty = self.resolve_vars_if_possible(ty);650                        if self.next_trait_solver() {651                            if let Err(guar) = ty.error_reported() {652                                return guar;653                            }654655                            // FIXME: we'll need a better message which takes into account656                            // which bounds actually failed to hold.657                            self.dcx().struct_span_err(658                                span,659                                format!("the type `{ty}` is not well-formed"),660                            )661                        } else {662                            // WF predicates cannot themselves make663                            // errors. They can only block due to664                            // ambiguity; otherwise, they always665                            // degenerate into other obligations666                            // (which may fail).667                            span_bug!(span, "WF predicate not satisfied for {:?}", ty);668                        }669                    }670671                    // Errors for `ConstEvaluatable` predicates show up as672                    // `SelectionError::ConstEvalFailure`,673                    // not `Unimplemented`.674                    ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))675                    // Errors for `ConstEquate` predicates show up as676                    // `SelectionError::ConstEvalFailure`,677                    // not `Unimplemented`.678                    | ty::PredicateKind::ConstEquate { .. }679                    // Ambiguous predicates should never error680                    | ty::PredicateKind::Ambiguous681                    // We never return Err when proving UnstableFeature goal.682                    | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })683                    | ty::PredicateKind::NormalizesTo { .. }684                    | ty::PredicateKind::AliasRelate { .. }685                    | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {686                        span_bug!(687                            span,688                            "Unexpected `Predicate` for `SelectionError`: `{:?}`",689                            obligation690                        )691                    }692                }693            }694695            SelectionError::SignatureMismatch(box SignatureMismatchData {696                found_trait_ref,697                expected_trait_ref,698                terr: terr @ TypeError::CyclicTy(_),699            }) => self.report_cyclic_signature_error(700                &obligation,701                found_trait_ref,702                expected_trait_ref,703                terr,704            ),705            SelectionError::SignatureMismatch(box SignatureMismatchData {706                found_trait_ref,707                expected_trait_ref,708                terr: _,709            }) => {710                match self.report_signature_mismatch_error(711                    &obligation,712                    span,713                    found_trait_ref,714                    expected_trait_ref,715                ) {716                    Ok(err) => err,717                    Err(guar) => return guar,718                }719            }720721            SelectionError::TraitDynIncompatible(did) => {722                let violations = self.tcx.dyn_compatibility_violations(did);723                report_dyn_incompatibility(self.tcx, span, None, did, violations)724            }725726            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => {727                bug!(728                    "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"729                )730            }731            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {732                match self.report_not_const_evaluatable_error(&obligation, span) {733                    Ok(err) => err,734                    Err(guar) => return guar,735                }736            }737738            // Already reported in the query.739            SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) |740            // Already reported.741            SelectionError::Overflow(OverflowError::Error(guar)) => {742                self.set_tainted_by_errors(guar);743                return guar744            },745746            SelectionError::Overflow(_) => {747                bug!("overflow should be handled before the `report_selection_error` path");748            }749750            SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => {751                let expected_ty_str = self.tcx.short_string(expected_ty, &mut long_ty_file);752                let ct_str = self.tcx.short_string(ct, &mut long_ty_file);753                let mut diag = self.dcx().struct_span_err(754                    span,755                    format!("the constant `{ct_str}` is not of type `{expected_ty_str}`"),756                );757                diag.long_ty_path = long_ty_file;758759                self.note_type_err(760                    &mut diag,761                    &obligation.cause,762                    None,763                    None,764                    TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)),765                    false,766                    None,767                );768                diag769            }770        };771772        self.note_obligation_cause(&mut err, &obligation);773        err.emit()774    }775}776777impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {778    pub(super) fn apply_do_not_recommend(779        &self,780        obligation: &mut PredicateObligation<'tcx>,781    ) -> bool {782        let mut base_cause = obligation.cause.code().clone();783        let mut applied_do_not_recommend = false;784        loop {785            if let ObligationCauseCode::ImplDerived(ref c) = base_cause {786                if self.tcx.do_not_recommend_impl(c.impl_or_alias_def_id) {787                    let code = (*c.derived.parent_code).clone();788                    obligation.cause.map_code(|_| code);789                    obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);790                    applied_do_not_recommend = true;791                }792            }793            if let Some(parent_cause) = base_cause.parent() {794                base_cause = parent_cause.clone();795            } else {796                break;797            }798        }799800        applied_do_not_recommend801    }802803    fn report_host_effect_error(804        &self,805        predicate: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,806        main_obligation: &PredicateObligation<'tcx>,807        span: Span,808    ) -> Diag<'a> {809        // FIXME(const_trait_impl): We should recompute the predicate with `[const]`810        // if it's `const`, and if it holds, explain that this bound only811        // *conditionally* holds.812        let trait_ref = predicate.map_bound(|predicate| ty::TraitPredicate {813            trait_ref: predicate.trait_ref,814            polarity: ty::PredicatePolarity::Positive,815        });816        let mut file = None;817818        let err_msg = self.get_standard_error_message(819            trait_ref,820            Some(predicate.constness()),821            String::new(),822            &mut file,823        );824        let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);825        *diag.long_ty_path() = file;826        let obligation = Obligation::new(827            self.tcx,828            ObligationCause::dummy(),829            main_obligation.param_env,830            trait_ref,831        );832        if !self.predicate_may_hold(&obligation) {833            diag.downgrade_to_delayed_bug();834        }835836        if let Ok(Some(ImplSource::UserDefined(impl_data))) =837            self.enter_forall(trait_ref, |trait_ref_for_select| {838                SelectionContext::new(self).select(&obligation.with(self.tcx, trait_ref_for_select))839            })840        {841            let impl_did = impl_data.impl_def_id;842            let trait_did = trait_ref.def_id();843            let impl_span = self.tcx.def_span(impl_did);844            let trait_name = self.tcx.item_name(trait_did);845846            if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {847                if !impl_did.is_local() {848                    diag.span_note(849                        impl_span,850                        format!("trait `{trait_name}` is implemented but not `const`"),851                    );852                }853854                if let Some(command) =855                    find_attr!(self.tcx, impl_did, OnConst {directive, ..} => directive.as_deref())856                        .flatten()857                {858                    let (_, format_args) = self.on_unimplemented_components(859                        trait_ref,860                        main_obligation,861                        diag.long_ty_path(),862                    );863                    let CustomDiagnostic { message, label, notes, parent_label: _ } =864                        command.eval(None, &format_args);865866                    if let Some(message) = message {867                        diag.primary_message(message);868                    }869                    if let Some(label) = label {870                        diag.span_label(span, label);871                    }872                    for note in notes {873                        diag.note(note);874                    }875                } else if let Some(impl_did) = impl_did.as_local()876                    && let item = self.tcx.hir_expect_item(impl_did)877                    && let hir::ItemKind::Impl(item) = item.kind878                    && let Some(of_trait) = item.of_trait879                {880                    // trait is const, impl is local and not const881                    diag.span_suggestion_verbose(882                        of_trait.trait_ref.path.span.shrink_to_lo(),883                        format!("make the `impl` of trait `{trait_name}` `const`"),884                        "const ".to_string(),885                        Applicability::MaybeIncorrect,886                    );887                }888            }889        } else if let ty::Param(param) = trait_ref.self_ty().skip_binder().kind()890            && let Some(generics) =891                self.tcx.hir_node_by_def_id(main_obligation.cause.body_id).generics()892        {893            let constraint = ty::print::with_no_trimmed_paths!(format!(894                "[const] {}",895                trait_ref.map_bound(|tr| tr.trait_ref).print_trait_sugared(),896            ));897            ty::suggest_constraining_type_param(898                self.tcx,899                generics,900                &mut diag,901                param.name.as_str(),902                &constraint,903                Some(trait_ref.def_id()),904                None,905            );906        }907        diag908    }909910    fn emit_specialized_closure_kind_error(911        &self,912        obligation: &PredicateObligation<'tcx>,913        mut trait_pred: ty::PolyTraitPredicate<'tcx>,914    ) -> Option<ErrorGuaranteed> {915        // If we end up on an `AsyncFnKindHelper` goal, try to unwrap the parent916        // `AsyncFn*` goal.917        if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::AsyncFnKindHelper) {918            let mut code = obligation.cause.code();919            // Unwrap a `FunctionArg` cause, which has been refined from a derived obligation.920            if let ObligationCauseCode::FunctionArg { parent_code, .. } = code {921                code = &**parent_code;922            }923            // If we have a derived obligation, then the parent will be a `AsyncFn*` goal.924            if let Some((_, Some(parent))) = code.parent_with_predicate() {925                trait_pred = parent;926            }927        }928929        let self_ty = trait_pred.self_ty().skip_binder();930931        let (expected_kind, trait_prefix) =932            if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {933                (expected_kind, "")934            } else if let Some(expected_kind) =935                self.tcx.async_fn_trait_kind_from_def_id(trait_pred.def_id())936            {937                (expected_kind, "Async")938            } else {939                return None;940            };941942        let (closure_def_id, found_args, has_self_borrows) = match *self_ty.kind() {943            ty::Closure(def_id, args) => {944                (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), false)945            }946            ty::CoroutineClosure(def_id, args) => (947                def_id,948                args.as_coroutine_closure()949                    .coroutine_closure_sig()950                    .map_bound(|sig| sig.tupled_inputs_ty),951                !args.as_coroutine_closure().tupled_upvars_ty().is_ty_var()952                    && args.as_coroutine_closure().has_self_borrows(),953            ),954            _ => return None,955        };956957        let expected_args = trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));958959        // Verify that the arguments are compatible. If the signature is960        // mismatched, then we have a totally different error to report.961        if self.enter_forall(found_args, |found_args| {962            self.enter_forall(expected_args, |expected_args| {963                !self.can_eq(obligation.param_env, expected_args, found_args)964            })965        }) {966            return None;967        }968969        if let Some(found_kind) = self.closure_kind(self_ty)970            && !found_kind.extends(expected_kind)971        {972            let mut err = self.report_closure_error(973                &obligation,974                closure_def_id,975                found_kind,976                expected_kind,977                trait_prefix,978            );979            self.note_obligation_cause(&mut err, &obligation);980            return Some(err.emit());981        }982983        // If the closure has captures, then perhaps the reason that the trait984        // is unimplemented is because async closures don't implement `Fn`/`FnMut`985        // if they have captures.986        if has_self_borrows && expected_kind != ty::ClosureKind::FnOnce {987            let coro_kind = match self988                .tcx989                .coroutine_kind(self.tcx.coroutine_for_closure(closure_def_id))990                .unwrap()991            {992                rustc_hir::CoroutineKind::Desugared(desugaring, _) => desugaring.to_string(),993                coro => coro.to_string(),994            };995            let mut err = self.dcx().create_err(CoroClosureNotFn {996                span: self.tcx.def_span(closure_def_id),997                kind: expected_kind.as_str(),998                coro_kind,999            });1000            self.note_obligation_cause(&mut err, &obligation);1001            return Some(err.emit());1002        }10031004        None1005    }10061007    fn fn_arg_obligation(1008        &self,1009        obligation: &PredicateObligation<'tcx>,1010    ) -> Result<(), ErrorGuaranteed> {1011        if let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()1012            && let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id)1013            && let arg = arg.peel_borrows()1014            && let hir::ExprKind::Path(hir::QPath::Resolved(1015                None,1016                hir::Path { res: hir::def::Res::Local(hir_id), .. },1017            )) = arg.kind1018            && let Node::Pat(pat) = self.tcx.hir_node(*hir_id)1019            && let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)1020            && preds.contains(&obligation.as_goal())1021        {1022            return Err(*guar);1023        }1024        Ok(())1025    }10261027    fn detect_negative_literal(1028        &self,1029        obligation: &PredicateObligation<'tcx>,1030        trait_pred: ty::PolyTraitPredicate<'tcx>,1031        err: &mut Diag<'_>,1032    ) -> bool {1033        if let ObligationCauseCode::UnOp { hir_id, .. } = obligation.cause.code()1034            && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)1035            && let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = expr.kind1036            && let hir::ExprKind::Lit(lit) = inner.kind1037            && let LitKind::Int(_, LitIntType::Unsuffixed) = lit.node1038        {1039            err.span_suggestion_verbose(1040                lit.span.shrink_to_hi(),1041                "consider specifying an integer type that can be negative",1042                match trait_pred.skip_binder().self_ty().kind() {1043                    ty::Uint(ty::UintTy::Usize) => "isize",1044                    ty::Uint(ty::UintTy::U8) => "i8",1045                    ty::Uint(ty::UintTy::U16) => "i16",1046                    ty::Uint(ty::UintTy::U32) => "i32",1047                    ty::Uint(ty::UintTy::U64) => "i64",1048                    ty::Uint(ty::UintTy::U128) => "i128",1049                    _ => "i64",1050                }1051                .to_string(),1052                Applicability::MaybeIncorrect,1053            );1054            return true;1055        }1056        false1057    }10581059    /// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,1060    /// identify those method chain sub-expressions that could or could not have been annotated1061    /// with `?`.1062    fn try_conversion_context(1063        &self,1064        obligation: &PredicateObligation<'tcx>,1065        trait_pred: ty::PolyTraitPredicate<'tcx>,1066        err: &mut Diag<'_>,1067    ) -> (bool, bool) {1068        let span = obligation.cause.span;1069        /// Look for the (direct) sub-expr of `?`, and return it if it's a `.` method call.1070        struct FindMethodSubexprOfTry {1071            search_span: Span,1072        }1073        impl<'v> Visitor<'v> for FindMethodSubexprOfTry {1074            type Result = ControlFlow<&'v hir::Expr<'v>>;1075            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result {1076                if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind1077                    && ex.span.with_lo(ex.span.hi() - BytePos(1)).source_equal(self.search_span)1078                    && let hir::ExprKind::Call(_, [expr, ..]) = expr.kind1079                {1080                    ControlFlow::Break(expr)1081                } else {1082                    hir::intravisit::walk_expr(self, ex)1083                }1084            }1085        }1086        let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);1087        let Some(body_id) = self.tcx.hir_node(hir_id).body_id() else { return (false, false) };1088        let ControlFlow::Break(expr) =1089            (FindMethodSubexprOfTry { search_span: span }).visit_body(self.tcx.hir_body(body_id))1090        else {1091            return (false, false);1092        };1093        let Some(typeck) = &self.typeck_results else {1094            return (false, false);1095        };1096        let ObligationCauseCode::QuestionMark = obligation.cause.code().peel_derives() else {1097            return (false, false);1098        };1099        let self_ty = trait_pred.skip_binder().self_ty();1100        let found_ty = trait_pred.skip_binder().trait_ref.args.get(1).and_then(|a| a.as_type());1101        let noted_missing_impl =1102            self.note_missing_impl_for_question_mark(err, self_ty, found_ty, trait_pred);11031104        let mut prev_ty = self.resolve_vars_if_possible(1105            typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1106        );11071108        // We always look at the `E` type, because that's the only one affected by `?`. If the1109        // incorrect `Result<T, E>` is because of the `T`, we'll get an E0308 on the whole1110        // expression, after the `?` has "unwrapped" the `T`.1111        let get_e_type = |prev_ty: Ty<'tcx>| -> Option<Ty<'tcx>> {1112            let ty::Adt(def, args) = prev_ty.kind() else {1113                return None;1114            };1115            let Some(arg) = args.get(1) else {1116                return None;1117            };1118            if !self.tcx.is_diagnostic_item(sym::Result, def.did()) {1119                return None;1120            }1121            arg.as_type()1122        };11231124        let mut suggested = false;1125        let mut chain = vec![];11261127        // The following logic is similar to `point_at_chain`, but that's focused on associated types1128        let mut expr = expr;1129        while let hir::ExprKind::MethodCall(path_segment, rcvr_expr, args, span) = expr.kind {1130            // Point at every method call in the chain with the `Result` type.1131            // let foo = bar.iter().map(mapper)?;1132            //               ------ -----------1133            expr = rcvr_expr;1134            chain.push((span, prev_ty));11351136            let next_ty = self.resolve_vars_if_possible(1137                typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1138            );11391140            let is_diagnostic_item = |symbol: Symbol, ty: Ty<'tcx>| {1141                let ty::Adt(def, _) = ty.kind() else {1142                    return false;1143                };1144                self.tcx.is_diagnostic_item(symbol, def.did())1145            };1146            // For each method in the chain, see if this is `Result::map_err` or1147            // `Option::ok_or_else` and if it is, see if the closure passed to it has an incorrect1148            // trailing `;`.1149            if let Some(ty) = get_e_type(prev_ty)1150                && let Some(found_ty) = found_ty1151                // Ideally we would instead use `FnCtxt::lookup_method_for_diagnostic` for 100%1152                // accurate check, but we are in the wrong stage to do that and looking for1153                // `Result::map_err` by checking the Self type and the path segment is enough.1154                // sym::ok_or_else1155                && (1156                    ( // Result::map_err1157                        path_segment.ident.name == sym::map_err1158                            && is_diagnostic_item(sym::Result, next_ty)1159                    ) || ( // Option::ok_or_else1160                        path_segment.ident.name == sym::ok_or_else1161                            && is_diagnostic_item(sym::Option, next_ty)1162                    )1163                )1164                // Found `Result<_, ()>?`1165                && let ty::Tuple(tys) = found_ty.kind()1166                && tys.is_empty()1167                // The current method call returns `Result<_, ()>`1168                && self.can_eq(obligation.param_env, ty, found_ty)1169                // There's a single argument in the method call and it is a closure1170                && let [arg] = args1171                && let hir::ExprKind::Closure(closure) = arg.kind1172                // The closure has a block for its body with no tail expression1173                && let body = self.tcx.hir_body(closure.body)1174                && let hir::ExprKind::Block(block, _) = body.value.kind1175                && let None = block.expr1176                // The last statement is of a type that can be converted to the return error type1177                && let [.., stmt] = block.stmts1178                && let hir::StmtKind::Semi(expr) = stmt.kind1179                && let expr_ty = self.resolve_vars_if_possible(1180                    typeck.expr_ty_adjusted_opt(expr)1181                        .unwrap_or(Ty::new_misc_error(self.tcx)),1182                )1183                && self1184                    .infcx1185                    .type_implements_trait(1186                        self.tcx.get_diagnostic_item(sym::From).unwrap(),1187                        [self_ty, expr_ty],1188                        obligation.param_env,1189                    )1190                    .must_apply_modulo_regions()1191            {1192                suggested = true;1193                err.span_suggestion_short(1194                    stmt.span.with_lo(expr.span.hi()),1195                    "remove this semicolon",1196                    String::new(),1197                    Applicability::MachineApplicable,1198                );1199            }12001201            prev_ty = next_ty;12021203            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind1204                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path1205                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)1206            {1207                let parent = self.tcx.parent_hir_node(binding.hir_id);1208                // We've reached the root of the method call chain...1209                if let hir::Node::LetStmt(local) = parent1210                    && let Some(binding_expr) = local.init1211                {1212                    // ...and it is a binding. Get the binding creation and continue the chain.1213                    expr = binding_expr;1214                }1215                if let hir::Node::Param(_param) = parent {1216                    // ...and it is an fn argument.1217                    break;1218                }1219            }1220        }1221        // `expr` is now the "root" expression of the method call chain, which can be any1222        // expression kind, like a method call or a path. If this expression is `Result<T, E>` as1223        // well, then we also point at it.1224        prev_ty = self.resolve_vars_if_possible(1225            typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1226        );1227        chain.push((expr.span, prev_ty));12281229        let mut prev = None;1230        let mut iter = chain.into_iter().rev().peekable();1231        while let Some((span, err_ty)) = iter.next() {1232            let is_last = iter.peek().is_none();1233            let err_ty = get_e_type(err_ty);1234            let err_ty = match (err_ty, prev) {1235                (Some(err_ty), Some(prev)) if !self.can_eq(obligation.param_env, err_ty, prev) => {1236                    err_ty1237                }1238                (Some(err_ty), None) => err_ty,1239                _ => {1240                    prev = err_ty;1241                    continue;1242                }1243            };12441245            let implements_from = self1246                .infcx1247                .type_implements_trait(1248                    self.tcx.get_diagnostic_item(sym::From).unwrap(),1249                    [self_ty, err_ty],1250                    obligation.param_env,1251                )1252                .must_apply_modulo_regions();12531254            let err_ty_str = self.tcx.short_string(err_ty, err.long_ty_path());1255            let label = if !implements_from && is_last {1256                format!(1257                    "this can't be annotated with `?` because it has type `Result<_, {err_ty_str}>`"1258                )1259            } else {1260                format!("this has type `Result<_, {err_ty_str}>`")1261            };12621263            if !suggested || !implements_from {1264                err.span_label(span, label);1265            }1266            prev = Some(err_ty);1267        }1268        (suggested, noted_missing_impl)1269    }12701271    fn note_missing_impl_for_question_mark(1272        &self,1273        err: &mut Diag<'_>,1274        self_ty: Ty<'_>,1275        found_ty: Option<Ty<'_>>,1276        trait_pred: ty::PolyTraitPredicate<'tcx>,1277    ) -> bool {1278        match (self_ty.kind(), found_ty) {1279            (ty::Adt(def, _), Some(ty))1280                if let ty::Adt(found, _) = ty.kind()1281                    && def.did().is_local()1282                    && found.did().is_local() =>1283            {1284                err.span_note(1285                    self.tcx.def_span(def.did()),1286                    format!("`{self_ty}` needs to implement `From<{ty}>`"),1287                );1288            }1289            (ty::Adt(def, _), None) if def.did().is_local() => {1290                let trait_path = self.tcx.short_string(1291                    trait_pred.skip_binder().trait_ref.print_only_trait_path(),1292                    err.long_ty_path(),1293                );1294                err.span_note(1295                    self.tcx.def_span(def.did()),1296                    format!("`{self_ty}` needs to implement `{trait_path}`"),1297                );1298            }1299            (ty::Adt(def, _), Some(ty)) if def.did().is_local() => {1300                err.span_note(1301                    self.tcx.def_span(def.did()),1302                    format!("`{self_ty}` needs to implement `From<{ty}>`"),1303                );1304            }1305            (_, Some(ty))1306                if let ty::Adt(def, _) = ty.kind()1307                    && def.did().is_local() =>1308            {1309                err.span_note(1310                    self.tcx.def_span(def.did()),1311                    format!("`{ty}` needs to implement `Into<{self_ty}>`"),1312                );1313            }1314            _ => return false,1315        }1316        true1317    }13181319    fn report_const_param_not_wf(1320        &self,1321        ty: Ty<'tcx>,1322        obligation: &PredicateObligation<'tcx>,1323    ) -> Diag<'a> {1324        let def_id = obligation.cause.body_id;1325        let span = self.tcx.ty_span(def_id);13261327        let mut file = None;1328        let ty_str = self.tcx.short_string(ty, &mut file);1329        let mut diag = match ty.kind() {1330            ty::Float(_) => {1331                struct_span_code_err!(1332                    self.dcx(),1333                    span,1334                    E0741,1335                    "`{ty_str}` is forbidden as the type of a const generic parameter",1336                )1337            }1338            ty::FnPtr(..) => {1339                struct_span_code_err!(1340                    self.dcx(),1341                    span,1342                    E0741,1343                    "using function pointers as const generic parameters is forbidden",1344                )1345            }1346            ty::RawPtr(_, _) => {1347                struct_span_code_err!(1348                    self.dcx(),1349                    span,1350                    E0741,1351                    "using raw pointers as const generic parameters is forbidden",1352                )1353            }1354            ty::Adt(def, _) => {1355                // We should probably see if we're *allowed* to derive `ConstParamTy` on the type...1356                let mut diag = struct_span_code_err!(1357                    self.dcx(),1358                    span,1359                    E0741,1360                    "`{ty_str}` must implement `ConstParamTy` to be used as the type of a const generic parameter",1361                );1362                // Only suggest derive if this isn't a derived obligation,1363                // and the struct is local.1364                if let Some(span) = self.tcx.hir_span_if_local(def.did())1365                    && obligation.cause.code().parent().is_none()1366                {1367                    if ty.is_structural_eq_shallow(self.tcx) {1368                        diag.span_suggestion(1369                            span.shrink_to_lo(),1370                            format!("add `#[derive(ConstParamTy)]` to the {}", def.descr()),1371                            "#[derive(ConstParamTy)]\n",1372                            Applicability::MachineApplicable,1373                        );1374                    } else {1375                        // FIXME(adt_const_params): We should check there's not already an1376                        // overlapping `Eq`/`PartialEq` impl.1377                        diag.span_suggestion(1378                            span.shrink_to_lo(),1379                            format!(1380                                "add `#[derive(ConstParamTy, PartialEq, Eq)]` to the {}",1381                                def.descr()1382                            ),1383                            "#[derive(ConstParamTy, PartialEq, Eq)]\n",1384                            Applicability::MachineApplicable,1385                        );1386                    }1387                }1388                diag1389            }1390            _ => {1391                struct_span_code_err!(1392                    self.dcx(),1393                    span,1394                    E0741,1395                    "`{ty_str}` can't be used as a const parameter type",1396                )1397            }1398        };1399        diag.long_ty_path = file;14001401        let mut code = obligation.cause.code();1402        let mut pred = obligation.predicate.as_trait_clause();1403        while let Some((next_code, next_pred)) = code.parent_with_predicate() {1404            if let Some(pred) = pred {1405                self.enter_forall(pred, |pred| {1406                    let ty = self.tcx.short_string(pred.self_ty(), diag.long_ty_path());1407                    let trait_path = self1408                        .tcx1409                        .short_string(pred.print_modifiers_and_trait_path(), diag.long_ty_path());1410                    diag.note(format!("`{ty}` must implement `{trait_path}`, but it does not"));1411                })1412            }1413            code = next_code;1414            pred = next_pred;1415        }14161417        diag1418    }1419}14201421impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {1422    fn can_match_trait(1423        &self,1424        param_env: ty::ParamEnv<'tcx>,1425        goal: ty::TraitPredicate<'tcx>,1426        assumption: ty::PolyTraitPredicate<'tcx>,1427    ) -> bool {1428        // Fast path1429        if goal.polarity != assumption.polarity() {1430            return false;1431        }14321433        let trait_assumption = self.instantiate_binder_with_fresh_vars(1434            DUMMY_SP,1435            infer::BoundRegionConversionTime::HigherRankedType,1436            assumption,1437        );14381439        self.can_eq(param_env, goal.trait_ref, trait_assumption.trait_ref)1440    }14411442    fn can_match_host_effect(1443        &self,1444        param_env: ty::ParamEnv<'tcx>,1445        goal: ty::HostEffectPredicate<'tcx>,1446        assumption: ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>,1447    ) -> bool {1448        let assumption = self.instantiate_binder_with_fresh_vars(1449            DUMMY_SP,1450            infer::BoundRegionConversionTime::HigherRankedType,1451            assumption,1452        );14531454        assumption.constness.satisfies(goal.constness)1455            && self.can_eq(param_env, goal.trait_ref, assumption.trait_ref)1456    }14571458    fn as_host_effect_clause(1459        predicate: ty::Predicate<'tcx>,1460    ) -> Option<ty::Binder<'tcx, ty::HostEffectPredicate<'tcx>>> {1461        predicate.as_clause().and_then(|clause| match clause.kind().skip_binder() {1462            ty::ClauseKind::HostEffect(pred) => Some(clause.kind().rebind(pred)),1463            _ => None,1464        })1465    }14661467    fn can_match_projection(1468        &self,1469        param_env: ty::ParamEnv<'tcx>,1470        goal: ty::ProjectionPredicate<'tcx>,1471        assumption: ty::PolyProjectionPredicate<'tcx>,1472    ) -> bool {1473        let assumption = self.instantiate_binder_with_fresh_vars(1474            DUMMY_SP,1475            infer::BoundRegionConversionTime::HigherRankedType,1476            assumption,1477        );14781479        self.can_eq(param_env, goal.projection_term, assumption.projection_term)1480            && self.can_eq(param_env, goal.term, assumption.term)1481    }14821483    // returns if `cond` not occurring implies that `error` does not occur - i.e., that1484    // `error` occurring implies that `cond` occurs.1485    #[instrument(level = "debug", skip(self), ret)]1486    pub(super) fn error_implies(1487        &self,1488        cond: Goal<'tcx, ty::Predicate<'tcx>>,1489        error: Goal<'tcx, ty::Predicate<'tcx>>,1490    ) -> bool {1491        if cond == error {1492            return true;1493        }14941495        // FIXME: We could be smarter about this, i.e. if cond's param-env is a1496        // subset of error's param-env. This only matters when binders will carry1497        // predicates though, and obviously only matters for error reporting.1498        if cond.param_env != error.param_env {1499            return false;1500        }1501        let param_env = error.param_env;15021503        if let Some(error) = error.predicate.as_trait_clause() {1504            self.enter_forall(error, |error| {1505                elaborate(self.tcx, std::iter::once(cond.predicate))1506                    .filter_map(|implied| implied.as_trait_clause())1507                    .any(|implied| self.can_match_trait(param_env, error, implied))1508            })1509        } else if let Some(error) = Self::as_host_effect_clause(error.predicate) {1510            self.enter_forall(error, |error| {1511                elaborate(self.tcx, std::iter::once(cond.predicate))1512                    .filter_map(Self::as_host_effect_clause)1513                    .any(|implied| self.can_match_host_effect(param_env, error, implied))1514            })1515        } else if let Some(error) = error.predicate.as_projection_clause() {1516            self.enter_forall(error, |error| {1517                elaborate(self.tcx, std::iter::once(cond.predicate))1518                    .filter_map(|implied| implied.as_projection_clause())1519                    .any(|implied| self.can_match_projection(param_env, error, implied))1520            })1521        } else {1522            false1523        }1524    }15251526    #[instrument(level = "debug", skip_all)]1527    pub(super) fn report_projection_error(1528        &self,1529        obligation: &PredicateObligation<'tcx>,1530        error: &MismatchedProjectionTypes<'tcx>,1531    ) -> ErrorGuaranteed {1532        let predicate = self.resolve_vars_if_possible(obligation.predicate);15331534        if let Err(e) = predicate.error_reported() {1535            return e;1536        }15371538        self.probe(|_| {1539            // try to find the mismatched types to report the error with.1540            //1541            // this can fail if the problem was higher-ranked, in which1542            // cause I have no idea for a good error message.1543            let bound_predicate = predicate.kind();1544            let (values, err) = match bound_predicate.skip_binder() {1545                ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {1546                    let ocx = ObligationCtxt::new(self);15471548                    let data = self.instantiate_binder_with_fresh_vars(1549                        obligation.cause.span,1550                        infer::BoundRegionConversionTime::HigherRankedType,1551                        bound_predicate.rebind(data),1552                    );1553                    let unnormalized_term = data.projection_term.to_term(self.tcx);1554                    // FIXME(-Znext-solver): For diagnostic purposes, it would be nice1555                    // to deeply normalize this type.1556                    let normalized_term = ocx.normalize(1557                        &obligation.cause,1558                        obligation.param_env,1559                        Unnormalized::new_wip(unnormalized_term),1560                    );15611562                    // constrain inference variables a bit more to nested obligations from normalize so1563                    // we can have more helpful errors.1564                    //1565                    // we intentionally drop errors from normalization here,1566                    // since the normalization is just done to improve the error message.1567                    let _ = ocx.try_evaluate_obligations();15681569                    if let Err(new_err) =1570                        ocx.eq(&obligation.cause, obligation.param_env, data.term, normalized_term)1571                    {1572                        (1573                            Some((1574                                data.projection_term,1575                                self.resolve_vars_if_possible(normalized_term),1576                                data.term,1577                            )),1578                            new_err,1579                        )1580                    } else {1581                        (None, error.err)1582                    }1583                }1584                ty::PredicateKind::AliasRelate(lhs, rhs, _) => {1585                    let derive_better_type_error =1586                        |alias_term: ty::AliasTerm<'tcx>, expected_term: ty::Term<'tcx>| {1587                            let ocx = ObligationCtxt::new(self);15881589                            let normalized_term = ocx.normalize(1590                                &ObligationCause::dummy(),1591                                obligation.param_env,1592                                Unnormalized::new_wip(alias_term.to_term(self.tcx)),1593                            );15941595                            if let Err(terr) = ocx.eq(1596                                &ObligationCause::dummy(),1597                                obligation.param_env,1598                                expected_term,1599                                normalized_term,1600                            ) {1601                                Some((terr, self.resolve_vars_if_possible(normalized_term)))1602                            } else {1603                                None1604                            }1605                        };16061607                    if let Some(lhs) = lhs.to_alias_term(self.tcx)1608                        && let ty::AliasTermKind::ProjectionTy { .. }1609                        | ty::AliasTermKind::ProjectionConst { .. } = lhs.kind(self.tcx)1610                        && let Some((better_type_err, expected_term)) =1611                            derive_better_type_error(lhs, rhs)1612                    {1613                        (1614                            Some((lhs, self.resolve_vars_if_possible(expected_term), rhs)),1615                            better_type_err,1616                        )1617                    } else if let Some(rhs) = rhs.to_alias_term(self.tcx)1618                        && let ty::AliasTermKind::ProjectionTy { .. }1619                        | ty::AliasTermKind::ProjectionConst { .. } = rhs.kind(self.tcx)1620                        && let Some((better_type_err, expected_term)) =1621                            derive_better_type_error(rhs, lhs)1622                    {1623                        (1624                            Some((rhs, self.resolve_vars_if_possible(expected_term), lhs)),1625                            better_type_err,1626                        )1627                    } else {1628                        (None, error.err)1629                    }1630                }1631                _ => (None, error.err),1632            };16331634            let mut file = None;1635            let (msg, span, closure_span) = values1636                .and_then(|(predicate, normalized_term, expected_term)| {1637                    self.maybe_detailed_projection_msg(1638                        obligation.cause.span,1639                        predicate,1640                        normalized_term,1641                        expected_term,1642                        &mut file,1643                    )1644                })1645                .unwrap_or_else(|| {1646                    (1647                        with_forced_trimmed_paths!(format!(1648                            "type mismatch resolving `{}`",1649                            self.tcx1650                                .short_string(self.resolve_vars_if_possible(predicate), &mut file),1651                        )),1652                        obligation.cause.span,1653                        None,1654                    )1655                });1656            let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}");1657            *diag.long_ty_path() = file;1658            if let Some(span) = closure_span {1659                // Mark the closure decl so that it is seen even if we are pointing at the return1660                // type or expression.1661                //1662                // error[E0271]: expected `{closure@foo.rs:41:16}` to be a closure that returns1663                //               `Unit3`, but it returns `Unit4`1664                //   --> $DIR/foo.rs:43:171665                //    |1666                // LL |     let v = Unit2.m(1667                //    |                   - required by a bound introduced by this call1668                // ...1669                // LL |             f: |x| {1670                //    |                --- /* this span */1671                // LL |                 drop(x);1672                // LL |                 Unit41673                //    |                 ^^^^^ expected `Unit3`, found `Unit4`1674                //    |1675                diag.span_label(span, "this closure");1676                if !span.overlaps(obligation.cause.span) {1677                    // Point at the binding corresponding to the closure where it is used.1678                    diag.span_label(obligation.cause.span, "closure used here");1679                }1680            }16811682            let secondary_span = self.probe(|_| {1683                let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =1684                    predicate.kind().skip_binder()1685                else {1686                    return None;1687                };16881689                let trait_ref = self.enter_forall_and_leak_universe(1690                    predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),1691                );1692                let Ok(Some(ImplSource::UserDefined(impl_data))) =1693                    SelectionContext::new(self).select(&obligation.with(self.tcx, trait_ref))1694                else {1695                    return None;1696                };16971698                let Ok(node) =1699                    specialization_graph::assoc_def(self.tcx, impl_data.impl_def_id, proj.def_id())1700                else {1701                    return None;1702                };17031704                if !node.is_final() {1705                    return None;1706                }17071708                match self.tcx.hir_get_if_local(node.item.def_id) {1709                    Some(1710                        hir::Node::TraitItem(hir::TraitItem {1711                            kind: hir::TraitItemKind::Type(_, Some(ty)),1712                            ..1713                        })1714                        | hir::Node::ImplItem(hir::ImplItem {1715                            kind: hir::ImplItemKind::Type(ty),1716                            ..1717                        }),1718                    ) => Some((1719                        ty.span,1720                        with_forced_trimmed_paths!(Cow::from(format!(1721                            "type mismatch resolving `{}`",1722                            self.tcx.short_string(1723                                self.resolve_vars_if_possible(predicate),1724                                diag.long_ty_path()1725                            ),1726                        ))),1727                        true,1728                    )),1729                    _ => None,1730                }1731            });17321733            self.note_type_err(1734                &mut diag,1735                &obligation.cause,1736                secondary_span,1737                values.map(|(_, normalized_ty, expected_ty)| {1738                    obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new(1739                        expected_ty,1740                        normalized_ty,1741                    )))1742                }),1743                err,1744                false,1745                Some(span),1746            );1747            self.note_obligation_cause(&mut diag, obligation);1748            diag.emit()1749        })1750    }17511752    fn maybe_detailed_projection_msg(1753        &self,1754        mut span: Span,1755        projection_term: ty::AliasTerm<'tcx>,1756        normalized_ty: ty::Term<'tcx>,1757        expected_ty: ty::Term<'tcx>,1758        long_ty_path: &mut Option<PathBuf>,1759    ) -> Option<(String, Span, Option<Span>)> {1760        let trait_def_id = projection_term.trait_def_id(self.tcx);1761        let self_ty = projection_term.self_ty();17621763        with_forced_trimmed_paths! {1764            if self.tcx.is_lang_item(projection_term.def_id(), LangItem::FnOnceOutput) {1765                let (span, closure_span) = if let ty::Closure(def_id, _) = *self_ty.kind() {1766                    let def_span = self.tcx.def_span(def_id);1767                    if let Some(local_def_id) = def_id.as_local()1768                        && let node = self.tcx.hir_node_by_def_id(local_def_id)1769                        && let Some(fn_decl) = node.fn_decl()1770                        && let Some(id) = node.body_id()1771                    {1772                        span = match fn_decl.output {1773                            hir::FnRetTy::Return(ty) => ty.span,1774                            hir::FnRetTy::DefaultReturn(_) => {1775                                let body = self.tcx.hir_body(id);1776                                match body.value.kind {1777                                    hir::ExprKind::Block(1778                                        hir::Block { expr: Some(expr), .. },1779                                        _,1780                                    ) => expr.span,1781                                    hir::ExprKind::Block(1782                                        hir::Block {1783                                            expr: None, stmts: [.., last], ..1784                                        },1785                                        _,1786                                    ) => last.span,1787                                    _ => body.value.span,1788                                }1789                            }1790                        };1791                    }1792                    (span, Some(def_span))1793                } else {1794                    (span, None)1795                };1796                let item = match self_ty.kind() {1797                    ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),1798                    _ => self.tcx.short_string(self_ty, long_ty_path),1799                };1800                let expected_ty = self.tcx.short_string(expected_ty, long_ty_path);1801                let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path);1802                Some((format!(1803                    "expected `{item}` to return `{expected_ty}`, but it returns `{normalized_ty}`",1804                ), span, closure_span))1805            } else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) {1806                let self_ty = self.tcx.short_string(self_ty, long_ty_path);1807                let expected_ty = self.tcx.short_string(expected_ty, long_ty_path);1808                let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path);1809                Some((format!(1810                    "expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \1811                     resolves to `{normalized_ty}`"1812                ), span, None))1813            } else if Some(trait_def_id) == self.tcx.get_diagnostic_item(sym::Iterator) {1814                let self_ty = self.tcx.short_string(self_ty, long_ty_path);1815                let expected_ty = self.tcx.short_string(expected_ty, long_ty_path);1816                let normalized_ty = self.tcx.short_string(normalized_ty, long_ty_path);1817                Some((format!(1818                    "expected `{self_ty}` to be an iterator that yields `{expected_ty}`, but it \1819                     yields `{normalized_ty}`"1820                ), span, None))1821            } else {1822                None1823            }1824        }1825    }18261827    pub fn fuzzy_match_tys(1828        &self,1829        mut a: Ty<'tcx>,1830        mut b: Ty<'tcx>,1831        ignoring_lifetimes: bool,1832    ) -> Option<CandidateSimilarity> {1833        /// returns the fuzzy category of a given type, or None1834        /// if the type can be equated to any type.1835        fn type_category(tcx: TyCtxt<'_>, t: Ty<'_>) -> Option<u32> {1836            match t.kind() {1837                ty::Bool => Some(0),1838                ty::Char => Some(1),1839                ty::Str => Some(2),1840                ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => Some(2),1841                ty::Int(..)1842                | ty::Uint(..)1843                | ty::Float(..)1844                | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) => Some(4),1845                ty::Ref(..) | ty::RawPtr(..) => Some(5),1846                ty::Array(..) | ty::Slice(..) => Some(6),1847                ty::FnDef(..) | ty::FnPtr(..) => Some(7),1848                ty::Dynamic(..) => Some(8),1849                ty::Closure(..) => Some(9),1850                ty::Tuple(..) => Some(10),1851                ty::Param(..) => Some(11),1852                ty::Alias(ty::AliasTy { kind: ty::Projection { .. }, .. }) => Some(12),1853                ty::Alias(ty::AliasTy { kind: ty::Inherent { .. }, .. }) => Some(13),1854                ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) => Some(14),1855                ty::Alias(ty::AliasTy { kind: ty::Free { .. }, .. }) => Some(15),1856                ty::Never => Some(16),1857                ty::Adt(..) => Some(17),1858                ty::Coroutine(..) => Some(18),1859                ty::Foreign(..) => Some(19),1860                ty::CoroutineWitness(..) => Some(20),1861                ty::CoroutineClosure(..) => Some(21),1862                ty::Pat(..) => Some(22),1863                ty::UnsafeBinder(..) => Some(23),1864                ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,1865            }1866        }18671868        let strip_references = |mut t: Ty<'tcx>| -> Ty<'tcx> {1869            loop {1870                match t.kind() {1871                    ty::Ref(_, inner, _) | ty::RawPtr(inner, _) => t = *inner,1872                    _ => break t,1873                }1874            }1875        };18761877        if !ignoring_lifetimes {1878            a = strip_references(a);1879            b = strip_references(b);1880        }18811882        let cat_a = type_category(self.tcx, a)?;1883        let cat_b = type_category(self.tcx, b)?;1884        if a == b {1885            Some(CandidateSimilarity::Exact { ignoring_lifetimes })1886        } else if cat_a == cat_b {1887            match (a.kind(), b.kind()) {1888                (ty::Adt(def_a, _), ty::Adt(def_b, _)) => def_a == def_b,1889                (ty::Foreign(def_a), ty::Foreign(def_b)) => def_a == def_b,1890                // Matching on references results in a lot of unhelpful1891                // suggestions, so let's just not do that for now.1892                //1893                // We still upgrade successful matches to `ignoring_lifetimes: true`1894                // to prioritize that impl.1895                (ty::Ref(..) | ty::RawPtr(..), ty::Ref(..) | ty::RawPtr(..)) => {1896                    self.fuzzy_match_tys(a, b, true).is_some()1897                }1898                _ => true,1899            }1900            .then_some(CandidateSimilarity::Fuzzy { ignoring_lifetimes })1901        } else if ignoring_lifetimes {1902            None1903        } else {1904            self.fuzzy_match_tys(a, b, true)1905        }1906    }19071908    pub(super) fn describe_closure(&self, kind: hir::ClosureKind) -> &'static str {1909        match kind {1910            hir::ClosureKind::Closure => "a closure",1911            hir::ClosureKind::Coroutine(hir::CoroutineKind::Coroutine(_)) => "a coroutine",1912            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1913                hir::CoroutineDesugaring::Async,1914                hir::CoroutineSource::Block,1915            )) => "an async block",1916            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1917                hir::CoroutineDesugaring::Async,1918                hir::CoroutineSource::Fn,1919            )) => "an async function",1920            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1921                hir::CoroutineDesugaring::Async,1922                hir::CoroutineSource::Closure,1923            ))1924            | hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Async) => {1925                "an async closure"1926            }1927            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1928                hir::CoroutineDesugaring::AsyncGen,1929                hir::CoroutineSource::Block,1930            )) => "an async gen block",1931            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1932                hir::CoroutineDesugaring::AsyncGen,1933                hir::CoroutineSource::Fn,1934            )) => "an async gen function",1935            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1936                hir::CoroutineDesugaring::AsyncGen,1937                hir::CoroutineSource::Closure,1938            ))1939            | hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::AsyncGen) => {1940                "an async gen closure"1941            }1942            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1943                hir::CoroutineDesugaring::Gen,1944                hir::CoroutineSource::Block,1945            )) => "a gen block",1946            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1947                hir::CoroutineDesugaring::Gen,1948                hir::CoroutineSource::Fn,1949            )) => "a gen function",1950            hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(1951                hir::CoroutineDesugaring::Gen,1952                hir::CoroutineSource::Closure,1953            ))1954            | hir::ClosureKind::CoroutineClosure(hir::CoroutineDesugaring::Gen) => "a gen closure",1955        }1956    }19571958    pub(super) fn find_similar_impl_candidates(1959        &self,1960        trait_pred: ty::PolyTraitPredicate<'tcx>,1961    ) -> Vec<ImplCandidate<'tcx>> {1962        let mut candidates: Vec<_> = self1963            .tcx1964            .all_impls(trait_pred.def_id())1965            .filter_map(|def_id| {1966                let imp = self.tcx.impl_trait_header(def_id);1967                if imp.polarity != ty::ImplPolarity::Positive1968                    || !self.tcx.is_user_visible_dep(def_id.krate)1969                {1970                    return None;1971                }1972                let imp = imp.trait_ref.skip_binder();19731974                self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map(1975                    |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id },1976                )1977            })1978            .collect();1979        if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) {1980            // If any of the candidates is a perfect match, we don't want to show all of them.1981            // This is particularly relevant for the case of numeric types (as they all have the1982            // same category).1983            candidates.retain(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. }));1984        }1985        candidates1986    }19871988    pub(super) fn report_similar_impl_candidates(1989        &self,1990        impl_candidates: &[ImplCandidate<'tcx>],1991        obligation: &PredicateObligation<'tcx>,1992        trait_pred: ty::PolyTraitPredicate<'tcx>,1993        body_def_id: LocalDefId,1994        err: &mut Diag<'_>,1995        other: bool,1996        param_env: ty::ParamEnv<'tcx>,1997    ) -> bool {1998        let parent_map = self.tcx.visible_parent_map(());1999        let alternative_candidates = |def_id: DefId| {2000            let mut impl_candidates: Vec<_> = self

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.