From e444017b4942bf0137b8679d8e8811a8cc604cb4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 May 2024 11:04:53 -0400 Subject: [PATCH] Consolidate obligation cause codes for where clauses --- .../rustc_borrowck/src/region_infer/mod.rs | 5 +-- .../src/transform/check_consts/check.rs | 4 +- .../src/check/compare_impl_item.rs | 11 ++---- .../rustc_hir_analysis/src/check/wfcheck.rs | 2 +- .../src/impl_wf_check/min_specialization.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 6 +-- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 5 +-- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 5 +-- .../rustc_hir_typeck/src/method/confirm.rs | 16 +++----- compiler/rustc_hir_typeck/src/method/probe.rs | 20 +++------- .../rustc_hir_typeck/src/method/suggest.rs | 6 +-- .../src/infer/error_reporting/mod.rs | 5 ++- .../mismatched_static_lifetime.rs | 7 +++- .../nice_region_error/placeholder_error.rs | 7 ++-- .../nice_region_error/static_impl_trait.rs | 2 +- .../src/infer/error_reporting/note.rs | 11 +++--- .../src/infer/outlives/obligations.rs | 8 +++- compiler/rustc_middle/src/traits/mod.rs | 25 +++++------- .../src/traits/error_reporting/suggestions.rs | 38 ++++++++++--------- .../error_reporting/type_err_ctxt_ext.rs | 26 ++++++------- .../src/traits/project.rs | 14 +------ .../rustc_trait_selection/src/traits/wf.rs | 6 +-- .../trait-bounds/issue-59311.stderr | 26 ++++++++++--- .../trait-bounds/trivial-does-not-hold.rs | 11 ++++++ .../trait-bounds/trivial-does-not-hold.stderr | 10 +++++ 25 files changed, 138 insertions(+), 140 deletions(-) create mode 100644 tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs create mode 100644 tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e58723c2ec954..167ca7ba04570 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2059,10 +2059,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We currently do not store the `DefId` in the `ConstraintCategory` // for performances reasons. The error reporting code used by NLL only // uses the span, so this doesn't cause any problems at the moment. - Some(ObligationCauseCode::SpannedWhereClause( - CRATE_DEF_ID.to_def_id(), - predicate_span, - )) + Some(ObligationCauseCode::WhereClause(CRATE_DEF_ID.to_def_id(), predicate_span)) } else { None } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index d43dc467c0f0f..46cc9f69373f5 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -11,7 +11,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; @@ -738,7 +738,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let cause = ObligationCause::new( terminator.source_info.span, self.body.source.def_id().expect_local(), - ObligationCauseCode::WhereClause(callee), + ObligationCauseCode::WhereClause(callee, DUMMY_SP), ); let normalized_predicates = ocx.normalize(&cause, param_env, predicates); ocx.register_obligations(traits::predicates_for_generics( diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index b2b82670d8b03..db223f9d80f39 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -819,7 +819,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { ObligationCause::new( self.span, self.body_id, - ObligationCauseCode::SpannedWhereClause(proj.def_id, pred_span), + ObligationCauseCode::WhereClause(proj.def_id, pred_span), ), self.param_env, pred, @@ -2011,11 +2011,7 @@ pub(super) fn check_type_bounds<'tcx>( }, ); let mk_cause = |span: Span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(trait_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(trait_ty.def_id, span) - }; + let code = ObligationCauseCode::WhereClause(trait_ty.def_id, span); ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; @@ -2251,8 +2247,7 @@ fn try_report_async_mismatch<'tcx>( }; for error in errors { - if let ObligationCauseCode::SpannedWhereClause(def_id, _) = - *error.root_obligation.cause.code() + if let ObligationCauseCode::WhereClause(def_id, _) = *error.root_obligation.cause.code() && def_id == async_future_def_id && let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred() && let Some(proj) = proj.no_bound_vars() diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0578317f91459..e50af9605fd0d 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1550,7 +1550,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let cause = traits::ObligationCause::new( sp, wfcx.body_def_id, - ObligationCauseCode::WhereClause(def_id.to_def_id()), + ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP), ); traits::Obligation::new(tcx, cause, wfcx.param_env, pred) }); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index de697b04ebf77..6dd59a62a7a46 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -212,7 +212,7 @@ fn get_impl_args( traits::ObligationCause::new( impl1_span, impl1_def_id, - traits::ObligationCauseCode::SpannedWhereClause(impl2_node.def_id(), span), + traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span), ) }, ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 881f726e1da80..b32cab6d3f71f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1409,11 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: HirId, ) { self.add_required_obligations_with_code(span, def_id, args, |idx, span| { - if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, hir_id, idx) - } + ObligationCauseCode::WhereClauseInExpr(def_id, span, hir_id, idx) }) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 26996397659ec..c3525f175da8e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -14,8 +14,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, error: &mut traits::FulfillmentError<'tcx>, ) -> bool { - let (ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - | ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, hir_id, idx)) = + let ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) = *error.obligation.cause.code().peel_derives() else { return false; @@ -512,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> { match obligation_cause_code { - traits::ObligationCauseCode::SpannedWhereClauseInExpr(_, _, _, _) => { + traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _) => { // This is the "root"; we assume that the `expr` is already pointing here. // Therefore, we return `Ok` so that this `expr` can be refined further. Ok(expr) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 4bf82355b622a..5fa715dc7618b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2013,8 +2013,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (span, code) in errors_causecode { self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { if let Some(fn_sig) = self.body_fn_sig() - && let ObligationCauseCode::SpannedWhereClauseInExpr(_, _, binding_hir_id, ..) = - code + && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code && !fn_sig.output().is_unit() { let mut block_num = 0; @@ -2103,7 +2102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // This is because due to normalization, we often register duplicate // obligations with misc obligations that are basically impossible to - // line back up with a useful SpannedWhereClauseInExpr. + // line back up with a useful WhereClauseInExpr. for error in not_adjusted { for (span, predicate, cause) in &remap_cause { if *predicate == error.obligation.predicate diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 56c296fc1c00e..007ec7ff378ab 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -564,16 +564,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // `self.add_required_obligations(self.span, def_id, &all_args);` for obligation in traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, self.call_expr.hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - def_id, - span, - self.call_expr.hir_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + def_id, + span, + self.call_expr.hir_id, + idx, + ); traits::ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 434bd9574986e..e9446b862fa0d 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1401,20 +1401,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. ocx.register_obligations(traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr( - impl_def_id, - self.scope_expr_id, - idx, - ) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - impl_def_id, - span, - self.scope_expr_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + impl_def_id, + span, + self.scope_expr_id, + idx, + ); ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index d1891a032e102..0483bd0357675 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -832,9 +832,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (data.impl_or_alias_def_id, data.span) } Some( - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, _, _) - | ObligationCauseCode::SpannedWhereClause(def_id, span), - ) => (*def_id, *span), + ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _) + | ObligationCauseCode::WhereClause(def_id, span), + ) if !span.is_dummy() => (*def_id, *span), _ => continue, }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 46310941113d4..3488517a4ef9b 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -883,9 +883,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("...or use `match` instead of `let...else`"); } _ => { - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = cause.code().peel_derives() + && !span.is_dummy() && let TypeError::RegionsPlaceholderMismatch = terr { err.span_note(*span, "the lifetime requirement is introduced here"); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index b6c38739e9af5..fdfce7f8f73c7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -38,11 +38,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let (ObligationCauseCode::SpannedWhereClause(_, binding_span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, binding_span, ..)) = *parent.code() + let (ObligationCauseCode::WhereClause(_, binding_span) + | ObligationCauseCode::WhereClauseInExpr(_, binding_span, ..)) = *parent.code() else { return None; }; + if binding_span.is_dummy() { + return None; + } // FIXME: we should point at the lifetime let multi_span: MultiSpan = vec![binding_span].into(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index dbd165c093aaf..31d45133eb0bc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -10,7 +10,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; use rustc_errors::{Diag, IntoDiagArg}; use rustc_hir::def::Namespace; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; use rustc_middle::ty::GenericArgsRef; @@ -240,8 +240,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let span = cause.span(); let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = - if let ObligationCauseCode::WhereClause(def_id) - | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *cause.code() + if let ObligationCauseCode::WhereClause(def_id, span) + | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code() + && def_id != CRATE_DEF_ID.to_def_id() { ( true, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index e5950a7c9350e..8a1e3a7ac71b7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _ => cause.code(), } && let ( - &ObligationCauseCode::WhereClause(item_def_id) + &ObligationCauseCode::WhereClause(item_def_id, _) | &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..), None, ) = (code, override_error_code) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index ecbe65fe9261e..00dd20a2cc270 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -357,21 +357,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Subtype(box ref trace) if matches!( &trace.cause.code().peel_derives(), - ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) ) => { // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = &trace.cause.code().peel_derives() + && !span.is_dummy() { let span = *span; self.report_concrete_failure(placeholder_origin, sub, sup) .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( - "control flow ensures we have a `BindingObligation` or `SpannedWhereClauseInExpr` here..." + "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." ) } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 94f8a2664f9cd..e0d23d7629f99 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -103,8 +103,12 @@ impl<'tcx> InferCtxt<'tcx> { cause.span, sup_type, match cause.code().peel_derives() { - ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) => Some(*span), + ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) + if !span.is_dummy() => + { + Some(*span) + } _ => None, }, ) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 6c33a29ea8122..fb796bf87a1dd 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -247,22 +247,15 @@ pub enum ObligationCauseCode<'tcx> { /// A tuple is WF only if its middle elements are `Sized`. TupleElem, - /// Must satisfy all of the where-clause predicates of the - /// given item. - WhereClause(DefId), - - /// Like `WhereClause`, but carries the span of the - /// predicate when it can be identified. - SpannedWhereClause(DefId, Span), - - /// Like `WhereClause`, but carries the `HirId` of the - /// expression that caused the obligation, and the `usize` - /// indicates exactly which predicate it is in the list of - /// instantiated predicates. - WhereClauseInExpr(DefId, HirId, usize), - - /// Combines `SpannedWhereClause` and `WhereClauseInExpr`. - SpannedWhereClauseInExpr(DefId, Span, HirId, usize), + /// Represents a clause that comes from a specific item. + /// The span corresponds to the clause. + WhereClause(DefId, Span), + + /// Like `WhereClause`, but also identifies the expression + /// which requires the `where` clause to be proven, and also + /// identifies the index of the predicate in the `predicates_of` + /// list of the item. + WhereClauseInExpr(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 597effcbbf0e7..51a4e910d621e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1205,8 +1205,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = match obligation.cause.code() { ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code, - c @ ObligationCauseCode::WhereClause(_) - | c @ ObligationCauseCode::WhereClauseInExpr(..) => c, + // FIXME(compiler-errors): This is kind of a mess, but required for obligations + // that come from a path expr to affect the *call* expr. + c @ ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, _) + if self.tcx.hir().span(*hir_id).lo() == span.lo() => + { + c + } c if matches!( span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(DesugaringKind::ForLoop) @@ -1262,8 +1267,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() + if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -1403,10 +1407,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ObligationCauseCode::ImplDerived(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) - } else if let ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) = code + } else if let ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) = code { try_borrowing(poly_trait_pred, &never_suggest_borrow) } else { @@ -2102,10 +2104,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCauseCode<'tcx>, err: &mut Diag<'tcx>, ) { - // First, look for an `SpannedWhereClauseInExpr`, which means we can get + // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check // that the predicate that we failed to satisfy is a `Fn`-like trait. - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = cause + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) && let Some(pred) = predicates.predicates.get(*idx) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() @@ -2746,12 +2748,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::TupleElem => { err.note("only the last element of a tuple may have a dynamically sized type"); } - ObligationCauseCode::WhereClause(_) | ObligationCauseCode::WhereClauseInExpr(..) => { - // We hold the `DefId` of the item introducing the obligation, but displaying it - // doesn't add user usable information. It always point at an associated item. - } - ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..) => { + ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..) + if !span.is_dummy() => + { let item_name = tcx.def_path_str(item_def_id); let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id)); let mut multispan = MultiSpan::from(span); @@ -2882,6 +2882,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help(help); } } + ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) => { + // We hold the `DefId` of the item introducing the obligation, but displaying it + // doesn't add user usable information. It always point at an associated item. + } ObligationCauseCode::Coercion { source, target } => { let source = tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file); @@ -3802,7 +3806,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // to an associated type (as seen from `trait_pred`) in the predicate. Like in // trait_pred `S: Sum<::Item>` and predicate `i32: Sum<&()>` let mut type_diffs = vec![]; - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = parent_code + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cdde12af8ea18..92fe50883d0fd 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1535,9 +1535,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { *err, ); let code = error.obligation.cause.code().peel_derives().peel_match_impls(); - if let ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + if let ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) = code { self.note_obligation_cause_code( @@ -1612,11 +1610,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let is_normalized_term_expected = !matches!( obligation.cause.code().peel_derives(), - ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) - | ObligationCauseCode::Coercion { .. } + |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr( + .. + ) | ObligationCauseCode::Coercion { .. } ); let (expected, actual) = if is_normalized_term_expected { @@ -2447,7 +2443,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - if let ObligationCauseCode::WhereClause(def_id) + if let ObligationCauseCode::WhereClause(def_id, _) | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code() { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); @@ -2883,12 +2879,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { else { return; }; - let (ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..)) = + let (ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) = *obligation.cause.code().peel_derives() else { return; }; + if span.is_dummy() { + return; + } debug!(?pred, ?item_def_id, ?span); let (Some(node), true) = ( @@ -3181,10 +3180,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::RustCall => { err.primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); } - ObligationCauseCode::SpannedWhereClause(def_id, _) - | ObligationCauseCode::WhereClause(def_id) - if self.tcx.is_fn_trait(*def_id) => - { + ObligationCauseCode::WhereClause(def_id, _) if self.tcx.is_fn_trait(*def_id) => { err.code(E0059); err.primary_message(format!( "type parameter to bare `{}` trait must be a tuple", diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 1e78484f30541..f092f42dacf9a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -573,11 +573,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. // Consider creating separate cause codes for this specific situation. - if span.is_dummy() { - ObligationCauseCode::WhereClause(alias_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(alias_ty.def_id, span) - }, + ObligationCauseCode::WhereClause(alias_ty.def_id, span), ); obligations.push(Obligation::with_depth( @@ -2130,17 +2126,11 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( | ObligationCauseCode::AscribeUserTypeProvePredicate(..) ) { obligation.cause.clone() - } else if span.is_dummy() { - ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObligationCauseCode::WhereClause(obligation.predicate.def_id), - ) } else { ObligationCause::new( obligation.cause.span, obligation.cause.body_id, - ObligationCauseCode::SpannedWhereClause(obligation.predicate.def_id, span), + ObligationCauseCode::WhereClause(obligation.predicate.def_id, span), ) }; nested.push(Obligation::with_depth( diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 2c2b84d4a8753..562a82cc73d65 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -568,11 +568,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { iter::zip(predicates, origins.into_iter().rev()) .map(|((pred, span), origin_def_id)| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(origin_def_id) - } else { - ObligationCauseCode::SpannedWhereClause(origin_def_id, span) - }; + let code = ObligationCauseCode::WhereClause(origin_def_id, span); let cause = self.cause(code); traits::Obligation::with_depth( self.tcx(), diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr index f8bed86ccf599..a26c617dc931d 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -1,19 +1,33 @@ error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs new file mode 100644 index 0000000000000..fa76686cc8b61 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs @@ -0,0 +1,11 @@ +// Minimized test from #59311. + +pub fn crash() +where + for<'a> &'a (): 'static, +{ + || {}; + //~^ ERROR higher-ranked lifetime error +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr new file mode 100644 index 0000000000000..9e0d7e4b7be09 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/trivial-does-not-hold.rs:7:5 + | +LL | || {}; + | ^^^^^ + | + = note: could not prove `for<'a> &'a (): 'b` + +error: aborting due to 1 previous error +