compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs RUST 4,172 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 4,172.
1// ignore-tidy-file-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_attr_ir::diagnostic::CustomDiagnostic;10use rustc_attr_ir::find_attr;11use rustc_attr_ir::lang_items::LangItem;12use rustc_data_structures::fx::{FxHashMap, FxHashSet};13use rustc_data_structures::unord::UnordSet;14use rustc_errors::codes::*;15use rustc_errors::{16    Applicability, Diag, ErrorGuaranteed, MultiSpan, StringPart, Sublevel, msg, pluralize,17    struct_span_code_err,18};19use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};20use rustc_hir::intravisit::Visitor;21use rustc_hir::{self as hir, Node, expr_needs_parens};22use rustc_infer::infer::{InferOk, TypeTrace};23use rustc_infer::traits::solve::Goal;24use rustc_infer::traits::{ImplSource, TraitErrors, WellFormedLoc};25use rustc_middle::traits::SignatureMismatchData;26use rustc_middle::traits::select::OverflowError;27use rustc_middle::ty::abstract_const::NotConstEvaluatable;28use rustc_middle::ty::error::{ExpectedFound, TypeError};29use rustc_middle::ty::print::{30    PrintPolyTraitClauseExt, PrintPolyTraitRefExt as _, PrintTraitClauseExt as _,31    PrintTraitRefExt as _, with_forced_trimmed_paths,32};33use rustc_middle::ty::transmute::{Answer, Reason};34use rustc_middle::ty::{35    self, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder,36    TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast,37};38use rustc_span::def_id::CrateNum;39use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, bug, span_bug, sym};40use tracing::{debug, instrument};4142use super::suggestions::get_explanation_based_on_obligation;43use super::{ArgKind, CandidateSimilarity, GetSafeTransmuteErrorAndReason, ImplCandidate};44use crate::diagnostics::{45    AssocTypeWithSameName, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,46    CoroClosureNotFn,47};48use crate::error_reporting::TypeErrCtxt;49use crate::error_reporting::infer::TyCategory;50use crate::error_reporting::traits::report_dyn_incompatibility;51use crate::infer::{self, InferCtxt, InferCtxtExt as _};52use crate::traits::query::evaluate_obligation::InferCtxtExt as _;53use crate::traits::{54    MismatchedProjectionTypes, NormalizeExt, Obligation, ObligationCause, ObligationCauseCode,55    ObligationCtxt, PredicateObligation, SelectionContext, SelectionError, elaborate,56    specialization_graph,57};5859impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {60    /// Checks for an explicit `Self: Trait` bound on an associated type impl.61    fn is_explicit_self_trait_bound_on_impl_assoc_type(62        &self,63        body_def_id: LocalDefId,64        cause_code: &ObligationCauseCode<'tcx>,65        trait_def_id: DefId,66    ) -> bool {67        let ObligationCauseCode::WhereClause(item_def_id, span) = *cause_code.peel_derives() else {68            return false;69        };70        // Continue only if there is an impl associated type corresponding to the expected trait item.71        if !self.tcx.opt_associated_item(body_def_id.to_def_id()).is_some_and(|assoc_item| {72            assoc_item.trait_item_def_id().is_some_and(|trait_item_def_id| {73                trait_item_def_id == item_def_id74                    && matches!(assoc_item.kind, ty::AssocKind::Type { .. })75            })76        }) {77            return false;78        }7980        self.tcx.clauses_of(item_def_id).instantiate_own_identity().any(|(clause, clause_span)| {81            clause_span == span82                && clause.skip_norm_wip().as_trait_clause().is_some_and(|trait_pred| {83                    trait_pred.def_id() == trait_def_id84                        && trait_pred.skip_binder().self_ty().is_self_param()85                })86        })87    }8889    /// The `root_obligation` parameter should be the `root_obligation` field90    /// from a `FulfillmentError`. If no `FulfillmentError` is available,91    /// then it should be the same as `obligation`.92    pub fn report_selection_error(93        &self,94        mut obligation: PredicateObligation<'tcx>,95        root_obligation: &PredicateObligation<'tcx>,96        error: &SelectionError<'tcx>,97    ) -> ErrorGuaranteed {98        let tcx = self.tcx;99        let mut span = obligation.cause.span;100        let mut long_ty_file = None;101102        let mut err = match *error {103            SelectionError::Unimplemented => {104                // If this obligation was generated as a result of well-formedness checking, see if we105                // can get a better error message by performing HIR-based well-formedness checking.106                if let ObligationCauseCode::WellFormed(wf_loc) =107                    root_obligation.cause.code().peel_derives()108                    && !obligation.predicate.has_non_region_infer()109                    && !matches!(wf_loc, WellFormedLoc::None)110                {111                    if let Some(cause) = self.tcx.diagnostic_hir_wf_check((112                        tcx.erase_and_anonymize_regions(obligation.predicate),113                        *wf_loc,114                    )) {115                        obligation.cause = cause.clone();116                        span = obligation.cause.span;117                    }118                }119120                if let ObligationCauseCode::CompareImplItem {121                    impl_item_def_id,122                    trait_item_def_id,123                    kind: _,124                } = *obligation.cause.code()125                {126                    debug!("ObligationCauseCode::CompareImplItemObligation");127                    return self128                        .report_extra_impl_obligation(129                            span,130                            impl_item_def_id,131                            trait_item_def_id,132                            &format!("`{}`", obligation.predicate),133                        )134                        .emit_err();135                }136137                // Report a const-param specific error138                if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives()139                {140                    return self.report_const_param_not_wf(ty, &obligation).emit_err();141                }142143                let bound_predicate = obligation.predicate.kind();144                match bound_predicate.skip_binder() {145                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {146                        let leaf_trait_predicate = self.deeply_resolve_ignoring_regions(147                            bound_predicate.rebind(trait_predicate),148                        );149150                        // Let's use the root obligation as the main message, when we care about the151                        // most general case ("X doesn't implement Pattern<'_>") over the case that152                        // happened to fail ("char doesn't implement Fn(&mut char)").153                        //154                        // We rely on a few heuristics to identify cases where this root155                        // obligation is more important than the leaf obligation:156                        let (main_trait_predicate, main_obligation) =157                            if let ty::PredicateKind::Clause(158                            ty::ClauseKind::Trait(root_pred)159                        ) = root_obligation.predicate.kind().skip_binder()160                            && !leaf_trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()161                            && !root_pred.self_ty().has_escaping_bound_vars()162                            // The type of the leaf predicate is (roughly) the same as the type163                            // from the root predicate, as a proxy for "we care about the root"164                            // FIXME: this doesn't account for trivial derefs, but works as a first165                            // approximation.166                            && (167                                // `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`168                                self.can_eq(169                                    obligation.param_env,170                                    leaf_trait_predicate.self_ty().skip_binder(),171                                    root_pred.self_ty().peel_refs(),172                                )173                                // `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`174                                || self.can_eq(175                                    obligation.param_env,176                                    leaf_trait_predicate.self_ty().skip_binder(),177                                    root_pred.self_ty(),178                                )179                            )180                            // The leaf trait and the root trait are different, so as to avoid181                            // talking about `&mut T: Trait` and instead remain talking about182                            // `T: Trait` instead183                            && leaf_trait_predicate.def_id() != root_pred.def_id()184                            // The root trait is not `Unsize`, as to avoid talking about it in185                            // `tests/ui/coercion/coerce-issue-49593-box-never.rs`.186                            && !self.tcx.is_lang_item(root_pred.def_id(), LangItem::Unsize)187                            {188                                (189                                    self.deeply_resolve_ignoring_regions(190                                        root_obligation.predicate.kind().rebind(root_pred),191                                    ),192                                    root_obligation,193                                )194                            } else {195                                (leaf_trait_predicate, &obligation)196                            };197198                        if let Some(guar) = self199                            .emit_specialized_closure_kind_error(&obligation, leaf_trait_predicate)200                        {201                            return guar;202                        }203204                        if let Err(guar) = leaf_trait_predicate.error_reported() {205                            return guar;206                        }207                        if self.is_explicit_self_trait_bound_on_impl_assoc_type(208                            obligation.cause.body_def_id,209                            obligation.cause.code(),210                            leaf_trait_predicate.def_id(),211                        ) && let ty::Param(param_ty) =212                            *leaf_trait_predicate.skip_binder().self_ty().kind()213                        {214                            span = param_ty.span_from_generics(215                                self.tcx,216                                obligation.cause.body_def_id.to_def_id(),217                            );218                        }219                        // Silence redundant errors on binding access that are already220                        // reported on the binding definition (#56607).221                        if let Err(guar) = self.fn_arg_obligation(&obligation) {222                            return guar;223                        }224                        let (post_message, pre_message, type_def) = self225                            .get_parent_trait_ref(obligation.cause.code())226                            .map(|(t, s)| {227                                let t = self.tcx.short_string(t, &mut long_ty_file);228                                (229                                    format!(" in `{t}`"),230                                    format!("within `{t}`, "),231                                    s.map(|s| (format!("within this `{t}`"), s)),232                                )233                            })234                            .unwrap_or_default();235236                        let CustomDiagnostic { message, label, notes, parent_label } = self237                            .on_unimplemented_note(238                                main_trait_predicate,239                                main_obligation,240                                &mut long_ty_file,241                            );242243                        let have_alt_message = message.is_some() || label.is_some();244245                        let message = message.unwrap_or_else(|| {246                            self.get_standard_error_message(247                                main_trait_predicate,248                                None,249                                post_message,250                                &mut long_ty_file,251                            )252                        });253                        let is_try_conversion =254                            self.is_try_conversion(span, main_trait_predicate.def_id());255                        let is_question_mark = matches!(256                            root_obligation.cause.code().peel_derives(),257                            ObligationCauseCode::QuestionMark,258                        ) && !(self259                            .tcx260                            .is_diagnostic_item(sym::FromResidual, main_trait_predicate.def_id())261                            || self.tcx.is_lang_item(main_trait_predicate.def_id(), LangItem::Try));262                        let is_unsize =263                            self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Unsize);264                        let question_mark_message = "the question mark operation (`?`) implicitly \265                                                     performs a conversion on the error value \266                                                     using the `From` trait";267                        let (message, notes) = if is_try_conversion {268                            let ty = self.tcx.short_string(269                                main_trait_predicate.skip_binder().self_ty(),270                                &mut long_ty_file,271                            );272                            // We have a `-> Result<_, E1>` and `gives_E2()?`.273                            (274                                format!("`?` couldn't convert the error to `{ty}`"),275                                vec![question_mark_message.to_owned()],276                            )277                        } else if is_question_mark {278                            let main_trait_predicate =279                                self.tcx.short_string(main_trait_predicate, &mut long_ty_file);280                            // Similar to the case above, but in this case the conversion is for a281                            // trait object: `-> Result<_, Box<dyn Error>` and `gives_E()?` when282                            // `E: Error` isn't met.283                            (284                                format!(285                                    "`?` couldn't convert the error: `{main_trait_predicate}` is \286                                     not satisfied",287                                ),288                                vec![question_mark_message.to_owned()],289                            )290                        } else {291                            (message, notes)292                        };293294                        let (err_msg, safe_transmute_explanation) = if self295                            .tcx296                            .is_lang_item(main_trait_predicate.def_id(), LangItem::TransmuteTrait)297                        {298                            // Recompute the safe transmute reason and use that for the error reporting299                            let (report_obligation, report_pred) = self300                                .select_transmute_obligation_for_reporting(301                                    &obligation,302                                    main_trait_predicate,303                                    root_obligation,304                                );305306                            match self.get_safe_transmute_error_and_reason(307                                report_obligation,308                                report_pred,309                                span,310                            ) {311                                GetSafeTransmuteErrorAndReason::Silent => {312                                    return self313                                        .dcx()314                                        .span_delayed_bug(span, "silent safe transmute error");315                                }316                                GetSafeTransmuteErrorAndReason::Default => (message, None),317                                GetSafeTransmuteErrorAndReason::Error {318                                    err_msg,319                                    safe_transmute_explanation,320                                } => (err_msg, safe_transmute_explanation),321                            }322                        } else {323                            (message, None)324                        };325326                        let mut err = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);327328                        let trait_def_id = main_trait_predicate.def_id();329                        let leaf_trait_def_id = leaf_trait_predicate.def_id();330                        if (self.tcx.is_diagnostic_item(sym::From, trait_def_id)331                            || self.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id))332                            && (self.tcx.is_diagnostic_item(sym::From, leaf_trait_def_id)333                                || self.tcx.is_diagnostic_item(sym::TryFrom, leaf_trait_def_id))334                            && let Some(trait_ref) =335                                leaf_trait_predicate.no_bound_vars().map(|pred| pred.trait_ref)336                            && let Some(found_ty) =337                                trait_ref.args.get(1).and_then(|arg| arg.as_type())338                            && let Some(ty) =339                                main_trait_predicate.no_bound_vars().map(|pred| pred.self_ty())340                            && let Some(cast_ty) =341                                self.find_explicit_cast_type(obligation.param_env, found_ty, ty)342                        {343                            let found_ty_str = self.tcx.short_string(found_ty, &mut long_ty_file);344                            let cast_ty_str = self.tcx.short_string(cast_ty, &mut long_ty_file);345346                            err.help(format!(347                                "consider casting the `{found_ty_str}` value to `{cast_ty_str}`",348                            ));349                        }350351                        *err.long_ty_path() = long_ty_file;352353                        let mut suggested = false;354                        let mut noted_missing_impl = false;355                        if is_try_conversion || is_question_mark {356                            (suggested, noted_missing_impl) = self.try_conversion_context(357                                &obligation,358                                main_trait_predicate,359                                &mut err,360                            );361                        }362363                        suggested |= self.detect_negative_literal(364                            &obligation,365                            main_trait_predicate,366                            &mut err,367                        );368369                        if let Some(ret_span) = self.return_type_span(&obligation) {370                            if is_try_conversion {371                                let ty = self.tcx.short_string(372                                    main_trait_predicate.skip_binder().self_ty(),373                                    err.long_ty_path(),374                                );375                                err.span_label(376                                    ret_span,377                                    format!("expected `{ty}` because of this"),378                                );379                            } else if is_question_mark {380                                let main_trait_predicate =381                                    self.tcx.short_string(main_trait_predicate, err.long_ty_path());382                                err.span_label(383                                    ret_span,384                                    format!("required `{main_trait_predicate}` because of this"),385                                );386                            }387                        }388389                        if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Tuple) {390                            self.add_tuple_trait_message(391                                obligation.cause.code().peel_derives(),392                                &mut err,393                            );394                        }395396                        let explanation = get_explanation_based_on_obligation(397                            self.tcx,398                            &obligation,399                            leaf_trait_predicate,400                            pre_message,401                            err.long_ty_path(),402                        );403404                        self.check_for_binding_assigned_block_without_tail_expression(405                            &obligation,406                            &mut err,407                            leaf_trait_predicate,408                        );409                        self.suggest_add_result_as_return_type(410                            &obligation,411                            &mut err,412                            leaf_trait_predicate,413                        );414415                        if self.suggest_add_reference_to_arg(416                            &obligation,417                            &mut err,418                            leaf_trait_predicate,419                            have_alt_message,420                        ) {421                            self.note_obligation_cause(&mut err, &obligation);422                            return err.emit_err();423                        }424425                        let ty_span = match leaf_trait_predicate.self_ty().skip_binder().kind() {426                            ty::Adt(def, _)427                                if def.did().is_local()428                                    && !self429                                        .can_suggest_derive(&obligation, leaf_trait_predicate) =>430                            {431                                self.tcx.def_span(def.did())432                            }433                            ty::Closure(def_id, _) => self.tcx.def_span(*def_id),434                            _ => DUMMY_SP,435                        };436                        if let Some(s) = label {437                            // If it has a custom `#[rustc_on_unimplemented]`438                            // error message, let's display it as the label!439                            err.span_label(span, s);440                            if !matches!(leaf_trait_predicate.skip_binder().self_ty().kind(), ty::Param(_))441                                // When the self type is a type param We don't need to "the trait442                                // `std::marker::Sized` is not implemented for `T`" as we will point443                                // at the type param with a label to suggest constraining it.444                                && !self.tcx.is_diagnostic_item(sym::FromResidual, leaf_trait_predicate.def_id())445                            // Don't say "the trait `FromResidual<Option<!>>` is446                            // not implemented for `Result<T, E>`".447                            {448                                // We do this just so that the JSON output's `help` position is the449                                // right one and not `file.rs:1:1`. The render is the same.450                                if ty_span == DUMMY_SP {451                                    err.help(explanation);452                                } else {453                                    err.span_help(ty_span, explanation);454                                }455                            }456                        } else if let Some(custom_explanation) = safe_transmute_explanation {457                            err.span_label(span, custom_explanation);458                        } else if (explanation.len() > self.tcx.sess.diagnostic_width()459                            || ty_span != DUMMY_SP)460                            && !noted_missing_impl461                        {462                            // Really long types don't look good as span labels, instead move it463                            // to a `help`.464                            err.span_label(span, "unsatisfied trait bound");465466                            // We do this just so that the JSON output's `help` position is the467                            // right one and not `file.rs:1:1`. The render is the same.468                            if ty_span == DUMMY_SP {469                                err.help(explanation);470                            } else {471                                err.span_help(ty_span, explanation);472                            }473                        } else {474                            err.span_label(span, explanation);475                        }476477                        if let ObligationCauseCode::Coercion { source, target } =478                            *obligation.cause.code().peel_derives()479                        {480                            if self.tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Sized)481                            {482                                self.suggest_borrowing_for_object_cast(483                                    &mut err,484                                    root_obligation,485                                    source,486                                    target,487                                );488                            }489                        }490491                        if let Some((msg, span)) = type_def {492                            err.span_label(span, msg);493                        }494                        // `#[rustc_on_unimplemented]` notes for derivable traits (e.g. `Debug`'s495                        // "add `#[derive(Debug)]` to `X` or manually `impl Debug for X`") duplicate496                        // the `consider annotating X with #[derive(..)]` suggestion that497                        // `suggest_derive` emits below, so skip them when that suggestion will be498                        // shown. We keep the note otherwise (e.g. when a field isn't `Debug`, so499                        // the derive can't be suggested) to avoid leaving the diagnostic without500                        // actionable guidance.501                        let derive_suggestion_will_be_shown = main_trait_predicate502                            == leaf_trait_predicate503                            && self.can_suggest_derive(&obligation, leaf_trait_predicate);504                        if !derive_suggestion_will_be_shown {505                            for note in notes {506                                // If it has a custom `#[rustc_on_unimplemented]` note, let's display507                                // it.508                                err.note(note);509                            }510                        }511                        if let Some(s) = parent_label {512                            let body = obligation.cause.body_def_id;513                            err.span_label(tcx.def_span(body), s);514                        }515516                        self.suggest_floating_point_literal(517                            &obligation,518                            &mut err,519                            leaf_trait_predicate,520                        );521                        self.suggest_dereferencing_index(522                            &obligation,523                            &mut err,524                            leaf_trait_predicate,525                        );526                        suggested |=527                            self.suggest_dereferences(&obligation, &mut err, leaf_trait_predicate)528                                || self.suggest_remove_reference(529                                    &obligation,530                                    &mut err,531                                    leaf_trait_predicate,532                                );533534                        suggested |=535                            self.suggest_fn_call(&obligation, &mut err, leaf_trait_predicate);536                        suggested |= self.suggest_cast_to_fn_pointer(537                            &obligation,538                            &mut err,539                            leaf_trait_predicate,540                            main_trait_predicate,541                            span,542                        );543544                        suggested |= self.suggest_semicolon_removal(545                            &obligation,546                            &mut err,547                            span,548                            leaf_trait_predicate,549                        );550                        self.note_different_trait_with_same_name(551                            &mut err,552                            &obligation,553                            leaf_trait_predicate,554                        );555                        self.note_adt_version_mismatch(&mut err, leaf_trait_predicate);556                        self.suggest_remove_await(&obligation, &mut err);557                        self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);558559                        if tcx.is_lang_item(leaf_trait_predicate.def_id(), LangItem::Try) {560                            self.suggest_await_before_try(561                                &mut err,562                                &obligation,563                                leaf_trait_predicate,564                                span,565                            );566                        }567568                        if self.suggest_add_clone_to_arg(569                            &obligation,570                            &mut err,571                            leaf_trait_predicate,572                        ) {573                            return err.emit_err();574                        }575576                        if self.suggest_impl_trait(&mut err, &obligation, leaf_trait_predicate) {577                            return err.emit_err();578                        }579580                        if is_unsize {581                            // If the obligation failed due to a missing implementation of the582                            // `Unsize` trait, give a pointer to why that might be the case583                            err.note(584                                "all implementations of `Unsize` are provided \585                                automatically by the compiler, see \586                                <https://doc.rust-lang.org/stable/std/marker/trait.Unsize.html> \587                                for more information",588                            );589                        }590591                        let is_fn_trait = tcx.is_fn_trait(leaf_trait_predicate.def_id());592                        let is_target_feature_fn = if let ty::FnDef(def_id, _) =593                            *leaf_trait_predicate.skip_binder().self_ty().kind()594                        {595                            !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()596                        } else {597                            false598                        };599                        if is_fn_trait && is_target_feature_fn {600                            err.note(601                                "`#[target_feature(..)]` functions do not implement the `Fn` traits",602                            );603                            err.note(604                                "try casting the function to a `fn` pointer or wrapping it in a closure",605                            );606                        }607608                        self.note_field_shadowed_by_private_candidate_in_cause(609                            &mut err,610                            &obligation.cause,611                            obligation.param_env,612                        );613                        self.try_to_add_help_message(614                            &root_obligation,615                            &obligation,616                            leaf_trait_predicate,617                            &mut err,618                            span,619                            is_fn_trait,620                            suggested,621                        );622623                        // Changing mutability doesn't make a difference to whether we have624                        // an `Unsize` impl (Fixes ICE in #71036)625                        if !is_unsize {626                            self.suggest_change_mut(&obligation, &mut err, leaf_trait_predicate);627                        }628629                        // If this error is due to `!: Trait` not implemented but `(): Trait` is630                        // implemented, and fallback has occurred, then it could be due to a631                        // variable that used to fallback to `()` now falling back to `!`. Issue a632                        // note informing about the change in behaviour.633                        if leaf_trait_predicate.skip_binder().self_ty().is_never()634                            && self.diverging_fallback_has_occurred635                        {636                            let predicate = leaf_trait_predicate.map_bound(|trait_pred| {637                                trait_pred.with_replaced_self_ty(self.tcx, tcx.types.unit)638                            });639                            let unit_obligation = obligation.with(tcx, predicate);640                            if self.predicate_may_hold(&unit_obligation) {641                                err.note(642                                    "this error might have been caused by changes to \643                                    Rust's type-inference algorithm (see issue #148922 \644                                    <https://github.com/rust-lang/rust/issues/148922> \645                                    for more information)",646                                );647                                err.help(648                                    "you might have intended to use the type `()` here instead",649                                );650                            }651                        }652653                        self.explain_hrtb_projection(654                            &mut err,655                            leaf_trait_predicate,656                            obligation.param_env,657                            &obligation.cause,658                        );659                        self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_predicate);660661                        // Return early if the trait is Debug or Display and the invocation662                        // originates within a standard library macro, because the output663                        // is otherwise overwhelming and unhelpful (see #85844 for an664                        // example).665666                        let in_std_macro =667                            match obligation.cause.span.ctxt().outer_expn_data().macro_def_id {668                                Some(macro_def_id) => {669                                    let crate_name = tcx.crate_name(macro_def_id.krate);670                                    STDLIB_STABLE_CRATES.contains(&crate_name)671                                }672                                None => false,673                            };674675                        if in_std_macro676                            && matches!(677                                self.tcx.get_diagnostic_name(leaf_trait_predicate.def_id()),678                                Some(sym::Debug | sym::Display)679                            )680                        {681                            return err.emit_err();682                        }683684                        err685                    }686687                    ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(clause)) => self688                        .report_host_effect_error(689                            bound_predicate.rebind(clause),690                            &obligation,691                            span,692                        ),693694                    ty::PredicateKind::Subtype(predicate) => {695                        // Errors for Subtype predicates show up as696                        // `FulfillmentErrorCode::SubtypeError`,697                        // not selection error.698                        span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)699                    }700701                    ty::PredicateKind::Coerce(predicate) => {702                        // Errors for Coerce predicates show up as703                        // `FulfillmentErrorCode::SubtypeError`,704                        // not selection error.705                        span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)706                    }707708                    ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))709                        if self.next_trait_solver() =>710                    {711                        // We normalize `TypeOutlives` in the next solver, which is fallible712                        return self.dcx().span_delayed_bug(713                            span,714                            "type outlives claues errored outside borrowck without any other error",715                        );716                    }717                    ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))718                    | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => {719                        span_bug!(720                            span,721                            "outlives clauses should not error outside borrowck. obligation: `{:?}`",722                            obligation723                        )724                    }725726                    ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {727                        span_bug!(728                            span,729                            "projection clauses should be implied from elsewhere. obligation: `{:?}`",730                            obligation731                        )732                    }733734                    ty::PredicateKind::DynCompatible(trait_def_id) => {735                        let violations = self.tcx.dyn_compatibility_violations(trait_def_id);736                        let mut err = report_dyn_incompatibility(737                            self.tcx,738                            span,739                            None,740                            trait_def_id,741                            violations,742                        );743                        if let hir::Node::Item(item) =744                            self.tcx.hir_node_by_def_id(obligation.cause.body_def_id)745                            && let hir::ItemKind::Impl(impl_) = item.kind746                            && let None = impl_.of_trait747                            && let hir::TyKind::TraitObject(_, tagged_ptr) = impl_.self_ty.kind748                            && let TraitObjectSyntax::None = tagged_ptr.tag()749                            && impl_.self_ty.span.edition().at_least_rust_2021()750                        {751                            // Silence the dyn-compatibility error in favor of the missing dyn on752                            // self type error. #131051.753                            err.downgrade_to_delayed_bug();754                        }755                        err756                    }757758                    ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {759                        let ty = self.deeply_resolve_ignoring_regions(ty);760                        if self.next_trait_solver() {761                            if let Err(guar) = ty.error_reported() {762                                return guar;763                            }764765                            // FIXME: we'll need a better message which takes into account766                            // which bounds actually failed to hold.767                            self.dcx().struct_span_err(768                                span,769                                format!("the type `{ty}` is not well-formed"),770                            )771                        } else {772                            // WF predicates cannot themselves make773                            // errors. They can only block due to774                            // ambiguity; otherwise, they always775                            // degenerate into other obligations776                            // (which may fail).777                            span_bug!(span, "WF predicate not satisfied for {:?}", ty);778                        }779                    }780781                    // Errors for `ConstEvaluatable`, `ConstEquate` predicates show up as782                    // `SelectionError::ConstEvalFailure`, not `Unimplemented`.783                    // Ambiguous predicates should never error.784                    // We never return `Err` when proving `UnstableFeature` goal.785                    ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))786                    | ty::PredicateKind::ConstEquate { .. }787                    | ty::PredicateKind::Ambiguous788                    | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature { .. })789                    | ty::PredicateKind::NormalizesTo { .. }790                    | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType { .. }) => {791                        span_bug!(792                            span,793                            "Unexpected `Predicate` for `SelectionError`: `{:?}`",794                            obligation795                        )796                    }797                }798            }799800            SelectionError::SignatureMismatch(SignatureMismatchData {801                found_trait_ref,802                expected_trait_ref,803                terr: terr @ TypeError::CyclicTy(_),804            }) => self.report_cyclic_signature_error(805                &obligation,806                found_trait_ref,807                expected_trait_ref,808                terr,809            ),810            SelectionError::SignatureMismatch(SignatureMismatchData {811                found_trait_ref,812                expected_trait_ref,813                terr: _,814            }) => {815                match self.report_signature_mismatch_error(816                    &obligation,817                    span,818                    found_trait_ref,819                    expected_trait_ref,820                ) {821                    Ok(err) => err,822                    Err(guar) => return guar,823                }824            }825826            SelectionError::TraitDynIncompatible(did) => {827                let violations = self.tcx.dyn_compatibility_violations(did);828                report_dyn_incompatibility(self.tcx, span, None, did, violations)829            }830831            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsInfer) => {832                bug!(833                    "MentionsInfer should have been handled in `traits/fulfill.rs` or `traits/select/mod.rs`"834                )835            }836            SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => {837                match self.report_not_const_evaluatable_error(&obligation, span) {838                    Ok(err) => err,839                    Err(guar) => return guar,840                }841            }842843            // Already reported in the query.844            SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar))845            | SelectionError::Overflow(OverflowError::Error(guar)) => {846                self.set_tainted_by_errors(guar);847                return guar;848            }849850            SelectionError::Overflow(_) => {851                bug!("overflow should be handled before the `report_selection_error` path");852            }853854            SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty } => {855                let expected_ty_str = self.tcx.short_string(expected_ty, &mut long_ty_file);856                let ct_str = self.tcx.short_string(ct, &mut long_ty_file);857                let mut diag = self.dcx().struct_span_err(858                    span,859                    format!("the constant `{ct_str}` is not of type `{expected_ty_str}`"),860                );861                diag.long_ty_path = long_ty_file;862863                self.note_type_err(864                    &mut diag,865                    &obligation.cause,866                    None,867                    None,868                    TypeError::Sorts(ty::error::ExpectedFound::new(expected_ty, ct_ty)),869                    false,870                    None,871                );872                diag873            }874        };875876        self.note_obligation_cause(&mut err, &obligation);877        self.silence_redundant_cause(&mut err, &obligation, &root_obligation);878        err.emit_err()879    }880}881882impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {883    pub(super) fn apply_do_not_recommend(884        &self,885        obligation: &mut PredicateObligation<'tcx>,886        root_obligation: &PredicateObligation<'tcx>,887    ) -> bool {888        let mut base_cause = obligation.cause.code().clone();889        let mut applied_do_not_recommend = false;890        loop {891            if let ObligationCauseCode::ImplDerived(ref c) = base_cause {892                if self.tcx.do_not_recommend_impl(c.impl_or_alias_def_id) {893                    let code = (*c.derived.parent_code).clone();894                    // Keep more precise spans that still point within the parent obligation,895                    // but do not let hidden impl details move the span outside of it.896                    if code == *root_obligation.cause.code()897                        && root_obligation.cause.span.eq_ctxt(obligation.cause.span)898                        && !root_obligation.cause.span.contains(obligation.cause.span)899                    {900                        obligation.cause.span = root_obligation.cause.span;901                    }902                    obligation.cause.map_code(|_| code);903                    obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx);904                    applied_do_not_recommend = true;905                }906            }907            if let Some(parent_cause) = base_cause.parent() {908                base_cause = parent_cause.clone();909            } else {910                break;911            }912        }913914        applied_do_not_recommend915    }916917    fn report_host_effect_error(918        &self,919        clause: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>,920        main_obligation: &PredicateObligation<'tcx>,921        span: Span,922    ) -> Diag<'a> {923        // FIXME(const_trait_impl): We should recompute the clause with `[const]`924        // if it's `const`, and if it holds, explain that this bound only925        // *conditionally* holds.926        let trait_ref = clause.map_bound(|clause| ty::TraitClause {927            trait_ref: clause.trait_ref,928            polarity: ty::ClausePolarity::Positive,929        });930        let mut file = None;931932        let err_msg = self.get_standard_error_message(933            trait_ref,934            Some(clause.constness()),935            String::new(),936            &mut file,937        );938        let mut diag = struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg);939        *diag.long_ty_path() = file;940        let obligation = Obligation::new(941            self.tcx,942            ObligationCause::dummy(),943            main_obligation.param_env,944            trait_ref,945        );946        if !self.predicate_may_hold(&obligation) {947            diag.downgrade_to_delayed_bug();948        }949950        if let Ok(Some(ImplSource::UserDefined(impl_data))) =951            SelectionContext::new(self).poly_select(&obligation.with(self.tcx, trait_ref))952        {953            let impl_did = impl_data.impl_def_id;954            let trait_did = trait_ref.def_id();955            let impl_span = self.tcx.def_span(impl_did);956            let trait_name = self.tcx.item_name(trait_did);957958            if self.tcx.is_const_trait(trait_did) && !self.tcx.is_const_trait_impl(impl_did) {959                if !impl_did.is_local() {960                    diag.span_note(961                        impl_span,962                        format!("trait `{trait_name}` is implemented but not `const`"),963                    );964                }965966                if let Some(command) =967                    find_attr!(self.tcx, impl_did, OnConst {directive, ..} => directive.as_deref())968                        .flatten()969                {970                    let (_, mut format_args) = self.on_unimplemented_components(971                        trait_ref,972                        main_obligation,973                        diag.long_ty_path(),974                        false,975                    );976                    if let ty::Adt(def, args) = trait_ref.self_ty().skip_binder().kind() {977                        for param in self.tcx.generics_of(def.did()).own_params.iter() {978                            match param.kind {979                                GenericParamDefKind::Type { .. }980                                | GenericParamDefKind::Const { .. } => {981                                    format_args982                                        .generic_args983                                        .push((param.name, args[param.index as usize].to_string()));984                                }985                                _ => continue,986                            }987                        }988                    }989                    let CustomDiagnostic { message, label, notes, parent_label: _ } =990                        command.eval(None, &format_args);991992                    if let Some(message) = message {993                        diag.primary_message(message);994                    }995                    if let Some(label) = label {996                        diag.span_label(span, label);997                    }998                    for note in notes {999                        diag.note(note);1000                    }1001                } else if let Some(impl_did) = impl_did.as_local()1002                    && let item = self.tcx.hir_expect_item(impl_did)1003                    && let hir::ItemKind::Impl(impl_) = item.kind1004                    && impl_.of_trait.is_some()1005                {1006                    // trait is const, impl is local and not const1007                    diag.span_suggestion_verbose(1008                        item.span.shrink_to_lo(),1009                        format!("make the `impl` of trait `{trait_name}` `const`"),1010                        "const ".to_string(),1011                        Applicability::MaybeIncorrect,1012                    );1013                }1014            }1015        } else if let ty::Param(param) = trait_ref.self_ty().skip_binder().kind()1016            && let Some(generics) =1017                self.tcx.hir_node_by_def_id(main_obligation.cause.body_def_id).generics()1018        {1019            let constraint = ty::print::with_no_trimmed_paths!(format!(1020                "[const] {}",1021                trait_ref.map_bound(|tr| tr.trait_ref).print_trait_sugared(),1022            ));1023            ty::suggest_constraining_type_param(1024                self.tcx,1025                generics,1026                &mut diag,1027                param.name.as_str(),1028                &constraint,1029                Some(trait_ref.def_id()),1030                None,1031            );1032        }1033        diag1034    }10351036    fn emit_specialized_closure_kind_error(1037        &self,1038        obligation: &PredicateObligation<'tcx>,1039        mut trait_pred: ty::PolyTraitClause<'tcx>,1040    ) -> Option<ErrorGuaranteed> {1041        // If we end up on an `AsyncFnKindHelper` goal, try to unwrap the parent1042        // `AsyncFn*` goal.1043        if self.tcx.is_lang_item(trait_pred.def_id(), LangItem::AsyncFnKindHelper) {1044            let mut code = obligation.cause.code();1045            // Unwrap a `FunctionArg` cause, which has been refined from a derived obligation.1046            if let ObligationCauseCode::FunctionArg { parent_code, .. } = code {1047                code = &**parent_code;1048            }1049            // If we have a derived obligation, then the parent will be a `AsyncFn*` goal.1050            if let Some((_, Some(parent))) = code.parent_with_predicate() {1051                trait_pred = parent;1052            }1053        }10541055        let original_self_ty = trait_pred.self_ty().skip_binder();1056        let peeled_self_ty = original_self_ty.peel_refs();10571058        let is_ref_to_closure = matches!(original_self_ty.kind(), ty::Ref(..))1059            && matches!(peeled_self_ty.kind(), ty::Closure(..));10601061        let self_ty = if is_ref_to_closure { peeled_self_ty } else { original_self_ty };10621063        let (expected_kind, is_async) =1064            if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {1065                (expected_kind, false)1066            } else if let Some(expected_kind) =1067                self.tcx.async_fn_trait_kind_from_def_id(trait_pred.def_id())1068            {1069                (expected_kind, true)1070            } else {1071                return None;1072            };1073        let trait_prefix = if is_async { "Async" } else { "" };10741075        let (closure_def_id, found_args, has_self_borrows) = match *self_ty.kind() {1076            ty::Closure(def_id, args) => {1077                (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), false)1078            }1079            ty::CoroutineClosure(def_id, args) => (1080                def_id,1081                args.as_coroutine_closure()1082                    .coroutine_closure_sig()1083                    .map_bound(|sig| sig.tupled_inputs_ty),1084                !args.as_coroutine_closure().tupled_upvars_ty().is_ty_var()1085                    && args.as_coroutine_closure().has_self_borrows(),1086            ),1087            _ => return None,1088        };10891090        let expected_args = trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));10911092        // Verify that the arguments are compatible. If the signature is1093        // mismatched, then we have a totally different error to report.1094        if self.enter_forall(found_args, |found_args| {1095            self.enter_forall(expected_args, |expected_args| {1096                !self.can_eq(obligation.param_env, expected_args, found_args)1097            })1098        }) {1099            return None;1100        }11011102        let mut found_kind = self.closure_kind(self_ty);1103        let mut kind_origin = None;11041105        if found_kind.is_none()1106            && is_ref_to_closure1107            && !is_async1108            && let Some(local_def_id) = closure_def_id.as_local()1109            && let Some((inferred_kind, origin)) = (self.infer_closure_kind)(local_def_id)1110        {1111            found_kind = Some(inferred_kind);1112            kind_origin = origin;1113        }11141115        if let Some(found_kind) = found_kind1116            && !found_kind.extends(expected_kind)1117        {1118            let mut err = self.report_closure_error(1119                &obligation,1120                closure_def_id,1121                found_kind,1122                expected_kind,1123                trait_prefix,1124                kind_origin,1125            );1126            self.suggest_change_mut_ref_for_closure(&mut err, &obligation);1127            self.note_obligation_cause(&mut err, &obligation);1128            return Some(err.emit_err());1129        }11301131        // If the closure has captures, then perhaps the reason that the trait1132        // is unimplemented is because async closures don't implement `Fn`/`FnMut`1133        // if they have captures.1134        if has_self_borrows && expected_kind != ty::ClosureKind::FnOnce {1135            let coro_kind = match self1136                .tcx1137                .coroutine_kind(self.tcx.coroutine_for_closure(closure_def_id))1138                .unwrap()1139            {1140                rustc_hir::CoroutineKind::Desugared(desugaring, _) => desugaring.to_string(),1141                coro => coro.to_string(),1142            };1143            let mut err = self.dcx().create_err(CoroClosureNotFn {1144                span: self.tcx.def_span(closure_def_id),1145                kind: expected_kind.as_str(),1146                coro_kind,1147            });1148            self.note_obligation_cause(&mut err, &obligation);1149            return Some(err.emit_err());1150        }11511152        None1153    }11541155    fn fn_arg_obligation(1156        &self,1157        obligation: &PredicateObligation<'tcx>,1158    ) -> Result<(), ErrorGuaranteed> {1159        if let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()1160            && let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id)1161            && let arg = arg.peel_borrows()1162            && let hir::ExprKind::Path(hir::QPath::Resolved(1163                None,1164                hir::Path { res: hir::def::Res::Local(hir_id), .. },1165            )) = arg.kind1166            && let Node::Pat(pat) = self.tcx.hir_node(*hir_id)1167            && let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)1168            && preds.contains(&obligation.as_goal())1169        {1170            return Err(*guar);1171        }1172        Ok(())1173    }11741175    fn detect_negative_literal(1176        &self,1177        obligation: &PredicateObligation<'tcx>,1178        trait_pred: ty::PolyTraitClause<'tcx>,1179        err: &mut Diag<'_>,1180    ) -> bool {1181        if let ObligationCauseCode::UnOp { hir_id, .. } = obligation.cause.code()1182            && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)1183            && let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = expr.kind1184            && let hir::ExprKind::Lit(lit) = inner.kind1185            && let LitKind::Int(_, LitIntType::Unsuffixed) = lit.node1186        {1187            err.span_suggestion_verbose(1188                lit.span.shrink_to_hi(),1189                "consider specifying an integer type that can be negative",1190                match trait_pred.skip_binder().self_ty().kind() {1191                    ty::Uint(ty::UintTy::Usize) => "isize",1192                    ty::Uint(ty::UintTy::U8) => "i8",1193                    ty::Uint(ty::UintTy::U16) => "i16",1194                    ty::Uint(ty::UintTy::U32) => "i32",1195                    ty::Uint(ty::UintTy::U64) => "i64",1196                    ty::Uint(ty::UintTy::U128) => "i128",1197                    _ => "i64",1198                }1199                .to_string(),1200                Applicability::MaybeIncorrect,1201            );1202            return true;1203        }1204        false1205    }12061207    /// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,1208    /// identify those method chain sub-expressions that could or could not have been annotated1209    /// with `?`.1210    fn try_conversion_context(1211        &self,1212        obligation: &PredicateObligation<'tcx>,1213        trait_pred: ty::PolyTraitClause<'tcx>,1214        err: &mut Diag<'_>,1215    ) -> (bool, bool) {1216        let span = obligation.cause.span;1217        /// Look for the (direct) sub-expr of `?`, and return it if it's a `.` method call.1218        struct FindMethodSubexprOfTry {1219            search_span: Span,1220        }1221        impl<'v> Visitor<'v> for FindMethodSubexprOfTry {1222            type Result = ControlFlow<&'v hir::Expr<'v>>;1223            fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) -> Self::Result {1224                if let hir::ExprKind::Match(expr, _arms, hir::MatchSource::TryDesugar(_)) = ex.kind1225                    && ex.span.with_lo(ex.span.hi() - BytePos(1)).lo_hi()1226                        == self.search_span.lo_hi()1227                    && let hir::ExprKind::Call(_, [expr, ..]) = expr.kind1228                {1229                    ControlFlow::Break(expr)1230                } else {1231                    hir::intravisit::walk_expr(self, ex)1232                }1233            }1234        }1235        let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_def_id);1236        let Some(body_id) = self.tcx.hir_node(hir_id).body_id() else { return (false, false) };1237        let ControlFlow::Break(expr) =1238            (FindMethodSubexprOfTry { search_span: span }).visit_body(self.tcx.hir_body(body_id))1239        else {1240            return (false, false);1241        };1242        let Some(typeck) = &self.typeck_results else {1243            return (false, false);1244        };1245        let ObligationCauseCode::QuestionMark = obligation.cause.code().peel_derives() else {1246            return (false, false);1247        };1248        let self_ty = trait_pred.skip_binder().self_ty();1249        let found_ty = trait_pred.skip_binder().trait_ref.args.get(1).and_then(|a| a.as_type());1250        let noted_missing_impl =1251            self.note_missing_impl_for_question_mark(err, self_ty, found_ty, trait_pred);12521253        let mut prev_ty = self.deeply_resolve_ignoring_regions(1254            typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1255        );12561257        // We always look at the `E` type, because that's the only one affected by `?`. If the1258        // incorrect `Result<T, E>` is because of the `T`, we'll get an E0308 on the whole1259        // expression, after the `?` has "unwrapped" the `T`.1260        let get_e_type = |prev_ty: Ty<'tcx>| -> Option<Ty<'tcx>> {1261            let ty::Adt(def, args) = prev_ty.kind() else {1262                return None;1263            };1264            let Some(arg) = args.get(1) else {1265                return None;1266            };1267            if !self.tcx.is_diagnostic_item(sym::Result, def.did()) {1268                return None;1269            }1270            arg.as_type()1271        };12721273        let mut suggested = false;1274        let mut chain = vec![];12751276        // The following logic is similar to `point_at_chain`, but that's focused on associated types1277        let mut expr = expr;1278        while let hir::ExprKind::MethodCall(path_segment, rcvr_expr, args, span) = expr.kind {1279            // Point at every method call in the chain with the `Result` type.1280            // let foo = bar.iter().map(mapper)?;1281            //               ------ -----------1282            expr = rcvr_expr;1283            chain.push((span, prev_ty));12841285            let next_ty = self.deeply_resolve_ignoring_regions(1286                typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1287            );12881289            let is_diagnostic_item = |symbol: Symbol, ty: Ty<'tcx>| {1290                let ty::Adt(def, _) = ty.kind() else {1291                    return false;1292                };1293                self.tcx.is_diagnostic_item(symbol, def.did())1294            };1295            // For each method in the chain, see if this is `Result::map_err` or1296            // `Option::ok_or_else` and if it is, see if the closure passed to it has an incorrect1297            // trailing `;`.1298            if let Some(ty) = get_e_type(prev_ty)1299                && let Some(found_ty) = found_ty1300                // Ideally we would instead use `FnCtxt::lookup_method_for_diagnostic` for 100%1301                // accurate check, but we are in the wrong stage to do that and looking for1302                // `Result::map_err` by checking the Self type and the path segment is enough.1303                // sym::ok_or_else1304                && (1305                    ( // Result::map_err1306                        path_segment.ident.name == sym::map_err1307                            && is_diagnostic_item(sym::Result, next_ty)1308                    ) || ( // Option::ok_or_else1309                        path_segment.ident.name == sym::ok_or_else1310                            && is_diagnostic_item(sym::Option, next_ty)1311                    )1312                )1313                // Found `Result<_, ()>?`1314                && let ty::Tuple(tys) = found_ty.kind()1315                && tys.is_empty()1316                // The current method call returns `Result<_, ()>`1317                && self.can_eq(obligation.param_env, ty, found_ty)1318                // There's a single argument in the method call and it is a closure1319                && let [arg] = args1320                && let hir::ExprKind::Closure(closure) = arg.kind1321                // The closure has a block for its body with no tail expression1322                && let body = self.tcx.hir_body(closure.body)1323                && let hir::ExprKind::Block(block, _) = body.value.kind1324                && let None = block.expr1325                // The last statement is of a type that can be converted to the return error type1326                && let [.., stmt] = block.stmts1327                && let hir::StmtKind::Semi(expr) = stmt.kind1328                && let expr_ty = self.deeply_resolve_ignoring_regions(1329                    typeck.expr_ty_adjusted_opt(expr)1330                        .unwrap_or(Ty::new_misc_error(self.tcx)),1331                )1332                && self1333                    .infcx1334                    .type_implements_trait(1335                        self.tcx.get_diagnostic_item(sym::From).unwrap(),1336                        [self_ty, expr_ty],1337                        obligation.param_env,1338                    )1339                    .must_apply_modulo_regions()1340            {1341                suggested = true;1342                err.span_suggestion_short(1343                    stmt.span.with_lo(expr.span.hi()),1344                    "remove this semicolon",1345                    String::new(),1346                    Applicability::MachineApplicable,1347                );1348            }13491350            prev_ty = next_ty;13511352            if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind1353                && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path1354                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)1355            {1356                let parent = self.tcx.parent_hir_node(binding.hir_id);1357                // We've reached the root of the method call chain...1358                if let hir::Node::LetStmt(local) = parent1359                    && let Some(binding_expr) = local.init1360                {1361                    // ...and it is a binding. Get the binding creation and continue the chain.1362                    expr = binding_expr;1363                }1364                if let hir::Node::Param(_param) = parent {1365                    // ...and it is an fn argument.1366                    break;1367                }1368            }1369        }1370        // `expr` is now the "root" expression of the method call chain, which can be any1371        // expression kind, like a method call or a path. If this expression is `Result<T, E>` as1372        // well, then we also point at it.1373        prev_ty = self.deeply_resolve_ignoring_regions(1374            typeck.expr_ty_adjusted_opt(expr).unwrap_or(Ty::new_misc_error(self.tcx)),1375        );1376        chain.push((expr.span, prev_ty));13771378        let mut prev = None;1379        let mut iter = chain.into_iter().rev().peekable();1380        while let Some((span, err_ty)) = iter.next() {1381            let is_last = iter.peek().is_none();1382            let err_ty = get_e_type(err_ty);1383            let err_ty = match (err_ty, prev) {1384                (Some(err_ty), Some(prev)) if !self.can_eq(obligation.param_env, err_ty, prev) => {1385                    err_ty1386                }1387                (Some(err_ty), None) => err_ty,1388                _ => {1389                    prev = err_ty;1390                    continue;1391                }1392            };13931394            let implements_from = self1395                .infcx1396                .type_implements_trait(1397                    self.tcx.get_diagnostic_item(sym::From).unwrap(),1398                    [self_ty, err_ty],1399                    obligation.param_env,1400                )1401                .must_apply_modulo_regions();14021403            let err_ty_str = self.tcx.short_string(err_ty, err.long_ty_path());1404            let label = if !implements_from && is_last {1405                format!(1406                    "this can't be annotated with `?` because it has type `Result<_, {err_ty_str}>`"1407                )1408            } else {1409                format!("this has type `Result<_, {err_ty_str}>`")1410            };14111412            if !suggested || !implements_from {1413                err.span_label(span, label);1414            }1415            prev = Some(err_ty);1416        }1417        (suggested, noted_missing_impl)1418    }14191420    fn note_missing_impl_for_question_mark(1421        &self,1422        err: &mut Diag<'_>,1423        self_ty: Ty<'_>,1424        found_ty: Option<Ty<'_>>,1425        trait_pred: ty::PolyTraitClause<'tcx>,1426    ) -> bool {1427        match (self_ty.kind(), found_ty) {1428            (ty::Adt(def, _), Some(ty))1429                if let ty::Adt(found, _) = ty.kind()1430                    && def.did().is_local()1431                    && found.did().is_local() =>1432            {1433                err.span_note(1434                    self.tcx.def_span(def.did()),1435                    format!("`{self_ty}` needs to implement `From<{ty}>`"),1436                );1437            }1438            (ty::Adt(def, _), None) if def.did().is_local() => {1439                let trait_path = self.tcx.short_string(1440                    trait_pred.skip_binder().trait_ref.print_only_trait_path(),1441                    err.long_ty_path(),1442                );1443                err.span_note(1444                    self.tcx.def_span(def.did()),1445                    format!("`{self_ty}` needs to implement `{trait_path}`"),1446                );1447            }1448            (ty::Adt(def, _), Some(ty)) if def.did().is_local() => {1449                err.span_note(1450                    self.tcx.def_span(def.did()),1451                    format!("`{self_ty}` needs to implement `From<{ty}>`"),1452                );1453            }1454            (_, Some(ty))1455                if let ty::Adt(def, _) = ty.kind()1456                    && def.did().is_local() =>1457            {1458                err.span_note(1459                    self.tcx.def_span(def.did()),1460                    format!("`{ty}` needs to implement `Into<{self_ty}>`"),1461                );1462            }1463            _ => return false,1464        }1465        true1466    }14671468    fn report_const_param_not_wf(1469        &self,1470        ty: Ty<'tcx>,1471        obligation: &PredicateObligation<'tcx>,1472    ) -> Diag<'a> {1473        let def_id = obligation.cause.body_def_id;1474        let span = self.tcx.ty_span(def_id);14751476        let mut file = None;1477        let ty_str = self.tcx.short_string(ty, &mut file);1478        let mut diag = match ty.kind() {1479            ty::Float(_) => {1480                struct_span_code_err!(1481                    self.dcx(),1482                    span,1483                    E0741,1484                    "`{ty_str}` is forbidden as the type of a const generic parameter",1485                )1486            }1487            ty::FnPtr(..) => {1488                struct_span_code_err!(1489                    self.dcx(),1490                    span,1491                    E0741,1492                    "using function pointers as const generic parameters is forbidden",1493                )1494            }1495            ty::RawPtr(_, _) => {1496                struct_span_code_err!(1497                    self.dcx(),1498                    span,1499                    E0741,1500                    "using raw pointers as const generic parameters is forbidden",1501                )1502            }1503            ty::Adt(def, _) => {1504                // We should probably see if we're *allowed* to derive `ConstParamTy` on the type...1505                let mut diag = struct_span_code_err!(1506                    self.dcx(),1507                    span,1508                    E0741,1509                    "`{ty_str}` must implement `ConstParamTy` to be used as the type of a const \1510                     generic parameter",1511                );1512                // Only suggest derive if this isn't a derived obligation,1513                // and the struct is local.1514                if let Some(span) = self.tcx.hir_span_if_local(def.did())1515                    && obligation.cause.code().parent().is_none()1516                {1517                    if ty.is_structural_eq_shallow(self.tcx) {1518                        diag.span_suggestion_verbose(1519                            span.shrink_to_lo(),1520                            format!("add `#[derive(ConstParamTy)]` to the {}", def.descr()),1521                            "#[derive(ConstParamTy)]\n",1522                            Applicability::MachineApplicable,1523                        );1524                    } else {1525                        // FIXME(adt_const_params): We should check there's not already an1526                        // overlapping `Eq`/`PartialEq` impl.1527                        diag.span_suggestion_verbose(1528                            span.shrink_to_lo(),1529                            format!(1530                                "add `#[derive(ConstParamTy, PartialEq, Eq)]` to the {}",1531                                def.descr()1532                            ),1533                            "#[derive(ConstParamTy, PartialEq, Eq)]\n",1534                            Applicability::MachineApplicable,1535                        );1536                    }1537                }1538                diag1539            }1540            _ => {1541                struct_span_code_err!(1542                    self.dcx(),1543                    span,1544                    E0741,1545                    "`{ty_str}` can't be used as a const parameter type",1546                )1547            }1548        };1549        diag.long_ty_path = file;15501551        let mut code = obligation.cause.code();1552        let mut pred = obligation.predicate.as_trait_clause();1553        while let Some((next_code, next_pred)) = code.parent_with_predicate() {1554            if let Some(pred) = pred {1555                self.enter_forall(pred, |pred| {1556                    let ty = self.tcx.short_string(pred.self_ty(), diag.long_ty_path());1557                    let trait_path = self1558                        .tcx1559                        .short_string(pred.print_modifiers_and_trait_path(), diag.long_ty_path());1560                    diag.note(format!("`{ty}` must implement `{trait_path}`, but it does not"));1561                })1562            }1563            code = next_code;1564            pred = next_pred;1565        }15661567        diag1568    }1569}15701571impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {1572    fn can_match_trait(1573        &self,1574        param_env: ty::ParamEnv<'tcx>,1575        goal: ty::TraitClause<'tcx>,1576        assumption: ty::PolyTraitClause<'tcx>,1577    ) -> bool {1578        // Fast path1579        if goal.polarity != assumption.polarity() {1580            return false;1581        }15821583        let trait_assumption = self.instantiate_binder_with_fresh_vars(1584            DUMMY_SP,1585            infer::BoundRegionConversionTime::HigherRankedType,1586            assumption,1587        );15881589        self.can_eq(param_env, goal.trait_ref, trait_assumption.trait_ref)1590    }15911592    fn can_match_host_effect(1593        &self,1594        param_env: ty::ParamEnv<'tcx>,1595        goal: ty::HostEffectClause<'tcx>,1596        assumption: ty::Binder<'tcx, ty::HostEffectClause<'tcx>>,1597    ) -> bool {1598        let assumption = self.instantiate_binder_with_fresh_vars(1599            DUMMY_SP,1600            infer::BoundRegionConversionTime::HigherRankedType,1601            assumption,1602        );16031604        assumption.constness.satisfies(goal.constness)1605            && self.can_eq(param_env, goal.trait_ref, assumption.trait_ref)1606    }16071608    fn as_host_effect_clause(1609        predicate: ty::Predicate<'tcx>,1610    ) -> Option<ty::Binder<'tcx, ty::HostEffectClause<'tcx>>> {1611        predicate.as_clause().and_then(|clause| match clause.kind().skip_binder() {1612            ty::ClauseKind::HostEffect(host_clause) => Some(clause.kind().rebind(host_clause)),1613            _ => None,1614        })1615    }16161617    fn can_match_projection(1618        &self,1619        param_env: ty::ParamEnv<'tcx>,1620        goal: ty::ProjectionClause<'tcx>,1621        assumption: ty::PolyProjectionClause<'tcx>,1622    ) -> bool {1623        let assumption = self.instantiate_binder_with_fresh_vars(1624            DUMMY_SP,1625            infer::BoundRegionConversionTime::HigherRankedType,1626            assumption,1627        );16281629        self.can_eq(param_env, goal.projection_term, assumption.projection_term)1630            && self.can_eq(param_env, goal.term, assumption.term)1631    }16321633    // returns if `cond` not occurring implies that `error` does not occur - i.e., that1634    // `error` occurring implies that `cond` occurs.1635    #[instrument(level = "debug", skip(self), ret)]1636    pub(super) fn error_implies(1637        &self,1638        cond: Goal<'tcx, ty::Predicate<'tcx>>,1639        error: Goal<'tcx, ty::Predicate<'tcx>>,1640    ) -> bool {1641        if cond == error {1642            return true;1643        }16441645        // FIXME: We could be smarter about this, i.e. if cond's param-env is a1646        // subset of error's param-env. This only matters when binders will carry1647        // predicates though, and obviously only matters for error reporting.1648        if cond.param_env != error.param_env {1649            return false;1650        }1651        let param_env = error.param_env;16521653        if let Some(error) = error.predicate.as_trait_clause() {1654            self.enter_forall(error, |error| {1655                elaborate(self.tcx, std::iter::once(cond.predicate))1656                    .filter_map(|implied| implied.as_trait_clause())1657                    .any(|implied| self.can_match_trait(param_env, error, implied))1658            })1659        } else if let Some(error) = Self::as_host_effect_clause(error.predicate) {1660            self.enter_forall(error, |error| {1661                elaborate(self.tcx, std::iter::once(cond.predicate))1662                    .filter_map(Self::as_host_effect_clause)1663                    .any(|implied| self.can_match_host_effect(param_env, error, implied))1664            })1665        } else if let Some(error) = error.predicate.as_projection_clause() {1666            self.enter_forall(error, |error| {1667                elaborate(self.tcx, std::iter::once(cond.predicate))1668                    .filter_map(|implied| implied.as_projection_clause())1669                    .any(|implied| self.can_match_projection(param_env, error, implied))1670            })1671        } else {1672            false1673        }1674    }16751676    /// Whether `error`, a projection goal, only failed because the trait goal it rests on1677    /// did: `<T as Trait>::Assoc == U` cannot hold when `T: Trait` doesn't, so an error on1678    /// the latter says everything the former would.1679    pub(super) fn trait_error_implies_projection_error(1680        &self,1681        cond: Goal<'tcx, ty::Predicate<'tcx>>,1682        error: Goal<'tcx, ty::Predicate<'tcx>>,1683    ) -> bool {1684        if cond.param_env != error.param_env {1685            return false;1686        }1687        let Some(error) = error.predicate.as_projection_clause() else {1688            return false;1689        };16901691        self.enter_forall(error, |error| {1692            if !error.projection_term.kind.is_trait_projection() {1693                return false;1694            }1695            let trait_pred = ty::TraitClause {1696                trait_ref: error.projection_term.trait_ref(self.tcx),1697                polarity: ty::ClausePolarity::Positive,1698            };1699            // Elaborating is what pairs a failing `C: FnMut(..)` with the1700            // `<C as FnOnce<..>>::Output` projection resting on it. A supertrait can hold1701            // while `cond` fails though, so the projection is only covered if its own trait1702            // goal is unproven too, otherwise it failed for its own reasons.1703            elaborate(self.tcx, std::iter::once(cond.predicate))1704                .filter_map(|implied| implied.as_trait_clause())1705                .any(|implied| self.can_match_trait(cond.param_env, trait_pred, implied))1706                && !self.predicate_must_hold_modulo_regions(&Obligation::new(1707                    self.tcx,1708                    ObligationCause::dummy(),1709                    cond.param_env,1710                    trait_pred,1711                ))1712        })1713    }17141715    #[instrument(level = "debug", skip_all)]1716    pub(super) fn report_projection_error(1717        &self,1718        obligation: &PredicateObligation<'tcx>,1719        error: &MismatchedProjectionTypes<'tcx>,1720    ) -> ErrorGuaranteed {1721        let predicate = self.deeply_resolve_ignoring_regions(obligation.predicate);17221723        if let Err(e) = predicate.error_reported() {1724            return e;1725        }17261727        self.probe(|_| {1728            // try to find the mismatched types to report the error with.1729            //1730            // this can fail if the problem was higher-ranked, in which1731            // cause I have no idea for a good error message.1732            let bound_predicate = predicate.kind();1733            let (values, err) = match bound_predicate.skip_binder() {1734                ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {1735                    let ocx = ObligationCtxt::new(self);17361737                    let data = self.instantiate_binder_with_fresh_vars(1738                        obligation.cause.span,1739                        infer::BoundRegionConversionTime::HigherRankedType,1740                        bound_predicate.rebind(data),1741                    );1742                    let unnormalized_term = data.projection_term.to_term(self.tcx, ty::IsRigid::No);1743                    let normalized_term = ocx.normalize(1744                        &obligation.cause,1745                        obligation.param_env,1746                        Unnormalized::new_wip(unnormalized_term),1747                    );17481749                    // constrain inference variables a bit more to nested obligations from normalize so1750                    // we can have more helpful errors.1751                    //1752                    // we intentionally drop errors from normalization here,1753                    // since the normalization is just done to improve the error message.1754                    let _ = ocx.try_evaluate_obligations();17551756                    if let Err(new_err) =1757                        ocx.eq(&obligation.cause, obligation.param_env, data.term, normalized_term)1758                    {1759                        (1760                            Some((1761                                data.projection_term,1762                                self.deeply_resolve_ignoring_regions(normalized_term),1763                                data.term,1764                            )),1765                            new_err,1766                        )1767                    } else {1768                        (None, error.err)1769                    }1770                }1771                _ => (None, error.err),1772            };17731774            let mut file = None;1775            let (msg, mut span, mut closure_span) = values1776                .and_then(|(predicate, normalized_term, expected_term)| {1777                    self.maybe_detailed_projection_msg(1778                        obligation.cause.span,1779                        predicate,1780                        normalized_term,1781                        expected_term,1782                        &mut file,1783                    )1784                })1785                .unwrap_or_else(|| {1786                    (1787                        with_forced_trimmed_paths!(format!(1788                            "type mismatch resolving `{}`",1789                            self.tcx.short_string(1790                                self.deeply_resolve_ignoring_regions(predicate),1791                                &mut file1792                            ),1793                        )),1794                        obligation.cause.span,1795                        None,1796                    )1797                });17981799            // When the obligation comes from a closure arg and the projection isn't FnOnceOutput1800            // (which maybe_detailed_projection_msg handles via self_ty), point at the closure's1801            // return expression and label the closure declaration.1802            if closure_span.is_none()1803                && let ObligationCauseCode::FunctionArg { arg_hir_id, .. } = obligation.cause.code()1804                && let Node::Expr(arg_expr) = self.tcx.hir_node(*arg_hir_id)1805                && let hir::ExprKind::Closure(closure) = arg_expr.kind1806                && closure.kind == hir::ClosureKind::Closure1807            {1808                let body = self.tcx.hir_body(closure.body);1809                let ret_span = match body.value.kind {1810                    hir::ExprKind::Block(hir::Block { expr: Some(expr), .. }, _) => expr.span,1811                    hir::ExprKind::Block(hir::Block { expr: None, stmts: [.., last], .. }, _) => {1812                        last.span1813                    }1814                    _ => body.value.span,1815                };1816                if !closure.fn_decl_span.overlaps(ret_span) {1817                    closure_span = Some(closure.fn_decl_span);1818                    span = ret_span;1819                }1820            }18211822            let mut diag = struct_span_code_err!(self.dcx(), span, E0271, "{msg}");1823            *diag.long_ty_path() = file;1824            let mut mention_bounds = true;1825            if let Some(span) = closure_span {1826                if let Some((_, _, expected_ty)) = values1827                    && let Some(expected_ty) = expected_ty.as_type()1828                    && let ty::Closure(def_id, _) = expected_ty.kind()1829                    && self.tcx.def_span(*def_id).overlaps(span)1830                    && let ObligationCauseCode::FunctionArg { parent_code, arg_hir_id, .. } =1831                        obligation.cause.code()1832                    && let ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _)1833                    | ObligationCauseCode::WhereClause(def_id, span) = &**parent_code1834                {1835                    // We have a trait bound for a closure to return itself, like1836                    // `T: FnOnce() -> T`. This is nonsensical, but as far as the type system is1837                    // concerned, valid. This is quite an edge case, but lets produce a reasonable1838                    // diagnostic even in the face of an unreasonable user :)1839                    let mut multispan: MultiSpan = (*span).into();1840                    multispan.push_span_label(*span, "this requires the closure to return itself");1841                    if let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) {1842                        multispan1843                            .push_span_label(arg.span, "this closure would have to return itself");1844                    }1845                    let in_the_item = match self.tcx.opt_item_name(*def_id) {1846                        Some(name) => format!("in `{name}`"),1847                        None => String::new(),1848                    };1849                    diag.span_note(1850                        multispan,1851                        format!(1852                            "a bound {in_the_item} requires that a closure return itself, which is \1853                             not possible",1854                        ),1855                    );1856                    mention_bounds = false;1857                } else {1858                    // Mark the closure decl so that it is seen even if we are pointing at the1859                    // return type or expression.1860                    //1861                    // error[E0271]: expected `{closure@foo.rs:41:16}` to be a closure that returns1862                    //               `Unit3`, but it returns `Unit4`1863                    //   --> $DIR/foo.rs:43:171864                    //    |1865                    // LL |     let v = Unit2.m(1866                    //    |                   - required by a bound introduced by this call1867                    // ...1868                    // LL |             f: |x| {1869                    //    |                --- /* this span */1870                    // LL |                 drop(x);1871                    // LL |                 Unit41872                    //    |                 ^^^^^ expected `Unit3`, found `Unit4`1873                    //    |1874                    diag.span_label(span, "this closure");1875                    if !span.overlaps(obligation.cause.span) {1876                        // Point at the binding corresponding to the closure where it is used.1877                        diag.span_label(obligation.cause.span, "closure used here");1878                    }1879                }1880            }18811882            let secondary_span = self.probe(|_| {1883                let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) =1884                    predicate.kind().skip_binder()1885                else {1886                    return None;1887                };1888                if !proj.projection_term.kind.is_trait_projection() {1889                    return None;1890                }18911892                let trait_ref = self.enter_forall_and_leak_universe(1893                    predicate.kind().rebind(proj.projection_term.trait_ref(self.tcx)),1894                );1895                let Ok(Some(ImplSource::UserDefined(impl_data))) =1896                    SelectionContext::new(self).select(&obligation.with(self.tcx, trait_ref))1897                else {1898                    return None;1899                };19001901                let Ok(node) =1902                    specialization_graph::assoc_def(self.tcx, impl_data.impl_def_id, proj.def_id())1903                else {1904                    return None;1905                };19061907                if !node.is_final() {1908                    return None;1909                }19101911                match self.tcx.hir_get_if_local(node.item.def_id) {1912                    Some(1913                        hir::Node::TraitItem(hir::TraitItem {1914                            kind: hir::TraitItemKind::Type(_, Some(ty)),1915                            ..1916                        })1917                        | hir::Node::ImplItem(hir::ImplItem {1918                            kind: hir::ImplItemKind::Type(ty),1919                            ..1920                        }),1921                    ) => Some((1922                        ty.span,1923                        with_forced_trimmed_paths!(Cow::from(format!(1924                            "type mismatch resolving `{}`",1925                            self.tcx.short_string(1926                                self.deeply_resolve_ignoring_regions(predicate),1927                                diag.long_ty_path()1928                            ),1929                        ))),1930                        true,1931                    )),1932                    _ => None,1933                }1934            });19351936            self.note_type_err(1937                &mut diag,1938                &obligation.cause,1939                secondary_span,1940                values.map(|(_, normalized_ty, expected_ty)| {1941                    obligation.param_env.and(infer::ValuePairs::Terms(ExpectedFound::new(1942                        expected_ty,1943                        normalized_ty,1944                    )))1945                }),1946                err,1947                false,1948                Some(span),1949            );1950            if mention_bounds {1951                self.note_obligation_cause(&mut diag, obligation);1952            }1953            diag.emit_err()1954        })1955    }19561957    fn maybe_detailed_projection_msg(1958        &self,1959        mut span: Span,1960        projection_term: ty::AliasTerm<'tcx>,1961        normalized_ty: ty::Term<'tcx>,1962        expected_ty: ty::Term<'tcx>,1963        long_ty_path: &mut Option<PathBuf>,1964    ) -> Option<(String, Span, Option<Span>)> {1965        if !projection_term.kind.is_trait_projection() {1966            return None;1967        }19681969        let projection_def_id = projection_term.expect_projection_def_id();1970        let trait_def_id = projection_term.trait_def_id(self.tcx);1971        let self_ty = projection_term.self_ty();19721973        with_forced_trimmed_paths! {1974            if self.tcx.is_lang_item(projection_def_id, LangItem::FnOnceOutput) {1975                let (span, closure_span) = if let ty::Closure(def_id, _) = *self_ty.kind() {1976                    let def_span = self.tcx.def_span(def_id);1977                    if let Some(local_def_id) = def_id.as_local()1978                        && let node = self.tcx.hir_node_by_def_id(local_def_id)1979                        && let Some(fn_decl) = node.fn_decl()1980                        && let Some(id) = node.body_id()1981                    {1982                        span = match fn_decl.output {1983                            hir::FnRetTy::Return(ty) => ty.span,1984                            hir::FnRetTy::DefaultReturn(_) => {1985                                let body = self.tcx.hir_body(id);1986                                match body.value.kind {1987                                    hir::ExprKind::Block(1988                                        hir::Block { expr: Some(expr), .. },1989                                        _,1990                                    ) => expr.span,1991                                    hir::ExprKind::Block(1992                                        hir::Block {1993                                            expr: None, stmts: [.., last], ..1994                                        },1995                                        _,1996                                    ) => last.span,1997                                    _ => body.value.span,1998                                }1999                            }2000                        };

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.

Generated by searchcode.com · powered by code_get_file + code_get_findings