Consolidate obligation cause codes for where clauses

This commit is contained in:
Michael Goulet 2024-05-10 11:04:53 -04:00
parent ef15976387
commit e444017b49
25 changed files with 137 additions and 139 deletions

View file

@ -2059,10 +2059,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// We currently do not store the `DefId` in the `ConstraintCategory` // We currently do not store the `DefId` in the `ConstraintCategory`
// for performances reasons. The error reporting code used by NLL only // for performances reasons. The error reporting code used by NLL only
// uses the span, so this doesn't cause any problems at the moment. // uses the span, so this doesn't cause any problems at the moment.
Some(ObligationCauseCode::SpannedWhereClause( Some(ObligationCauseCode::WhereClause(CRATE_DEF_ID.to_def_id(), predicate_span))
CRATE_DEF_ID.to_def_id(),
predicate_span,
))
} else { } else {
None None
} }

View file

@ -11,7 +11,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt};
use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt};
use rustc_mir_dataflow::Analysis; 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::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};
@ -738,7 +738,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let cause = ObligationCause::new( let cause = ObligationCause::new(
terminator.source_info.span, terminator.source_info.span,
self.body.source.def_id().expect_local(), self.body.source.def_id().expect_local(),
ObligationCauseCode::WhereClause(callee), ObligationCauseCode::WhereClause(callee, DUMMY_SP),
); );
let normalized_predicates = ocx.normalize(&cause, param_env, predicates); let normalized_predicates = ocx.normalize(&cause, param_env, predicates);
ocx.register_obligations(traits::predicates_for_generics( ocx.register_obligations(traits::predicates_for_generics(

View file

@ -819,7 +819,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
ObligationCause::new( ObligationCause::new(
self.span, self.span,
self.body_id, self.body_id,
ObligationCauseCode::SpannedWhereClause(proj.def_id, pred_span), ObligationCauseCode::WhereClause(proj.def_id, pred_span),
), ),
self.param_env, self.param_env,
pred, pred,
@ -2011,11 +2011,7 @@ pub(super) fn check_type_bounds<'tcx>(
}, },
); );
let mk_cause = |span: Span| { let mk_cause = |span: Span| {
let code = if span.is_dummy() { let code = ObligationCauseCode::WhereClause(trait_ty.def_id, span);
ObligationCauseCode::WhereClause(trait_ty.def_id)
} else {
ObligationCauseCode::SpannedWhereClause(trait_ty.def_id, span)
};
ObligationCause::new(impl_ty_span, impl_ty_def_id, code) ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
}; };
@ -2251,8 +2247,7 @@ fn try_report_async_mismatch<'tcx>(
}; };
for error in errors { for error in errors {
if let ObligationCauseCode::SpannedWhereClause(def_id, _) = if let ObligationCauseCode::WhereClause(def_id, _) = *error.root_obligation.cause.code()
*error.root_obligation.cause.code()
&& def_id == async_future_def_id && def_id == async_future_def_id
&& let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred() && let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred()
&& let Some(proj) = proj.no_bound_vars() && let Some(proj) = proj.no_bound_vars()

View file

@ -1550,7 +1550,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
let cause = traits::ObligationCause::new( let cause = traits::ObligationCause::new(
sp, sp,
wfcx.body_def_id, 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) traits::Obligation::new(tcx, cause, wfcx.param_env, pred)
}); });

View file

@ -212,7 +212,7 @@ fn get_impl_args(
traits::ObligationCause::new( traits::ObligationCause::new(
impl1_span, impl1_span,
impl1_def_id, impl1_def_id,
traits::ObligationCauseCode::SpannedWhereClause(impl2_node.def_id(), span), traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span),
) )
}, },
); );

View file

@ -1409,11 +1409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir_id: HirId, hir_id: HirId,
) { ) {
self.add_required_obligations_with_code(span, def_id, args, |idx, span| { self.add_required_obligations_with_code(span, def_id, args, |idx, span| {
if span.is_dummy() { ObligationCauseCode::WhereClauseInExpr(def_id, span, hir_id, idx)
ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx)
} else {
ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, hir_id, idx)
}
}) })
} }

View file

@ -14,8 +14,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
error: &mut traits::FulfillmentError<'tcx>, error: &mut traits::FulfillmentError<'tcx>,
) -> bool { ) -> bool {
let (ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) let ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) =
| ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, hir_id, idx)) =
*error.obligation.cause.code().peel_derives() *error.obligation.cause.code().peel_derives()
else { else {
return false; return false;
@ -512,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> { ) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> {
match obligation_cause_code { match obligation_cause_code {
traits::ObligationCauseCode::SpannedWhereClauseInExpr(_, _, _, _) => { traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _) => {
// This is the "root"; we assume that the `expr` is already pointing here. // 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. // Therefore, we return `Ok` so that this `expr` can be refined further.
Ok(expr) Ok(expr)

View file

@ -2013,8 +2013,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for (span, code) in errors_causecode { for (span, code) in errors_causecode {
self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
if let Some(fn_sig) = self.body_fn_sig() if let Some(fn_sig) = self.body_fn_sig()
&& let ObligationCauseCode::SpannedWhereClauseInExpr(_, _, binding_hir_id, ..) = && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code
code
&& !fn_sig.output().is_unit() && !fn_sig.output().is_unit()
{ {
let mut block_num = 0; 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 // This is because due to normalization, we often register duplicate
// obligations with misc obligations that are basically impossible to // 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 error in not_adjusted {
for (span, predicate, cause) in &remap_cause { for (span, predicate, cause) in &remap_cause {
if *predicate == error.obligation.predicate if *predicate == error.obligation.predicate

View file

@ -564,16 +564,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// `self.add_required_obligations(self.span, def_id, &all_args);` // `self.add_required_obligations(self.span, def_id, &all_args);`
for obligation in traits::predicates_for_generics( for obligation in traits::predicates_for_generics(
|idx, span| { |idx, span| {
let code = if span.is_dummy() { let code = ObligationCauseCode::WhereClauseInExpr(
ObligationCauseCode::WhereClauseInExpr(def_id, self.call_expr.hir_id, idx)
} else {
ObligationCauseCode::SpannedWhereClauseInExpr(
def_id, def_id,
span, span,
self.call_expr.hir_id, self.call_expr.hir_id,
idx, idx,
) );
};
traits::ObligationCause::new(self.span, self.body_id, code) traits::ObligationCause::new(self.span, self.body_id, code)
}, },
self.param_env, self.param_env,

View file

@ -1401,20 +1401,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// Convert the bounds into obligations. // Convert the bounds into obligations.
ocx.register_obligations(traits::predicates_for_generics( ocx.register_obligations(traits::predicates_for_generics(
|idx, span| { |idx, span| {
let code = if span.is_dummy() { let code = ObligationCauseCode::WhereClauseInExpr(
ObligationCauseCode::WhereClauseInExpr(
impl_def_id,
self.scope_expr_id,
idx,
)
} else {
ObligationCauseCode::SpannedWhereClauseInExpr(
impl_def_id, impl_def_id,
span, span,
self.scope_expr_id, self.scope_expr_id,
idx, idx,
) );
};
ObligationCause::new(self.span, self.body_id, code) ObligationCause::new(self.span, self.body_id, code)
}, },
self.param_env, self.param_env,

View file

@ -832,9 +832,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(data.impl_or_alias_def_id, data.span) (data.impl_or_alias_def_id, data.span)
} }
Some( Some(
ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, _, _) ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _)
| ObligationCauseCode::SpannedWhereClause(def_id, span), | ObligationCauseCode::WhereClause(def_id, span),
) => (*def_id, *span), ) if !span.is_dummy() => (*def_id, *span),
_ => continue, _ => continue,
}; };

View file

@ -883,9 +883,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.help("...or use `match` instead of `let...else`"); err.help("...or use `match` instead of `let...else`");
} }
_ => { _ => {
if let ObligationCauseCode::SpannedWhereClause(_, span) if let ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
cause.code().peel_derives() cause.code().peel_derives()
&& !span.is_dummy()
&& let TypeError::RegionsPlaceholderMismatch = terr && let TypeError::RegionsPlaceholderMismatch = terr
{ {
err.span_note(*span, "the lifetime requirement is introduced here"); err.span_note(*span, "the lifetime requirement is introduced here");

View file

@ -38,11 +38,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else {
return None; return None;
}; };
let (ObligationCauseCode::SpannedWhereClause(_, binding_span) let (ObligationCauseCode::WhereClause(_, binding_span)
| ObligationCauseCode::SpannedWhereClauseInExpr(_, binding_span, ..)) = *parent.code() | ObligationCauseCode::WhereClauseInExpr(_, binding_span, ..)) = *parent.code()
else { else {
return None; return None;
}; };
if binding_span.is_dummy() {
return None;
}
// FIXME: we should point at the lifetime // FIXME: we should point at the lifetime
let multi_span: MultiSpan = vec![binding_span].into(); let multi_span: MultiSpan = vec![binding_span].into();

View file

@ -10,7 +10,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode};
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_errors::{Diag, IntoDiagArg}; use rustc_errors::{Diag, IntoDiagArg};
use rustc_hir::def::Namespace; 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::error::ExpectedFound;
use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode};
use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::GenericArgsRef;
@ -240,8 +240,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
let span = cause.span(); let span = cause.span();
let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) =
if let ObligationCauseCode::WhereClause(def_id) if let ObligationCauseCode::WhereClause(def_id, span)
| ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *cause.code() | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code()
&& def_id != CRATE_DEF_ID.to_def_id()
{ {
( (
true, true,

View file

@ -214,7 +214,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
_ => cause.code(), _ => cause.code(),
} }
&& let ( && let (
&ObligationCauseCode::WhereClause(item_def_id) &ObligationCauseCode::WhereClause(item_def_id, _)
| &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..), | &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..),
None, None,
) = (code, override_error_code) ) = (code, override_error_code)

View file

@ -357,21 +357,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
infer::Subtype(box ref trace) infer::Subtype(box ref trace)
if matches!( if matches!(
&trace.cause.code().peel_derives(), &trace.cause.code().peel_derives(),
ObligationCauseCode::SpannedWhereClause(..) ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::SpannedWhereClauseInExpr(..) | ObligationCauseCode::WhereClauseInExpr(..)
) => ) =>
{ {
// Hack to get around the borrow checker because trace.cause has an `Rc`. // Hack to get around the borrow checker because trace.cause has an `Rc`.
if let ObligationCauseCode::SpannedWhereClause(_, span) if let ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = | ObligationCauseCode::WhereClauseInExpr(_, span, ..) =
&trace.cause.code().peel_derives() &trace.cause.code().peel_derives()
&& !span.is_dummy()
{ {
let span = *span; let span = *span;
self.report_concrete_failure(placeholder_origin, sub, sup) self.report_concrete_failure(placeholder_origin, sub, sup)
.with_span_note(span, "the lifetime requirement is introduced here") .with_span_note(span, "the lifetime requirement is introduced here")
} else { } else {
unreachable!( unreachable!(
"control flow ensures we have a `BindingObligation` or `SpannedWhereClauseInExpr` here..." "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..."
) )
} }
} }

View file

@ -103,8 +103,12 @@ impl<'tcx> InferCtxt<'tcx> {
cause.span, cause.span,
sup_type, sup_type,
match cause.code().peel_derives() { match cause.code().peel_derives() {
ObligationCauseCode::SpannedWhereClause(_, span) ObligationCauseCode::WhereClause(_, span)
| ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) => Some(*span), | ObligationCauseCode::WhereClauseInExpr(_, span, ..)
if !span.is_dummy() =>
{
Some(*span)
}
_ => None, _ => None,
}, },
) )

View file

@ -247,22 +247,15 @@ pub enum ObligationCauseCode<'tcx> {
/// A tuple is WF only if its middle elements are `Sized`. /// A tuple is WF only if its middle elements are `Sized`.
TupleElem, TupleElem,
/// Must satisfy all of the where-clause predicates of the /// Represents a clause that comes from a specific item.
/// given item. /// The span corresponds to the clause.
WhereClause(DefId), WhereClause(DefId, Span),
/// Like `WhereClause`, but carries the span of the /// Like `WhereClause`, but also identifies the expression
/// predicate when it can be identified. /// which requires the `where` clause to be proven, and also
SpannedWhereClause(DefId, Span), /// identifies the index of the predicate in the `predicates_of`
/// list of the item.
/// Like `WhereClause`, but carries the `HirId` of the WhereClauseInExpr(DefId, Span, HirId, usize),
/// 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),
/// A type like `&'a T` is WF only if `T: 'a`. /// A type like `&'a T` is WF only if `T: 'a`.
ReferenceOutlivesReferent(Ty<'tcx>), ReferenceOutlivesReferent(Ty<'tcx>),

View file

@ -1205,8 +1205,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let code = match obligation.cause.code() { let code = match obligation.cause.code() {
ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code, ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code,
c @ ObligationCauseCode::WhereClause(_) // FIXME(compiler-errors): This is kind of a mess, but required for obligations
| c @ ObligationCauseCode::WhereClauseInExpr(..) => c, // 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!( c if matches!(
span.ctxt().outer_expn_data().kind, span.ctxt().outer_expn_data().kind,
ExpnKind::Desugaring(DesugaringKind::ForLoop) 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 mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref);
let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
if let ObligationCauseCode::WhereClause(_) if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code()
| ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code()
&& let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() && 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 { if let ObligationCauseCode::ImplDerived(cause) = &*code {
try_borrowing(cause.derived.parent_trait_pred, &[]) try_borrowing(cause.derived.parent_trait_pred, &[])
} else if let ObligationCauseCode::SpannedWhereClause(_, _) } else if let ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::WhereClause(_) | ObligationCauseCode::WhereClauseInExpr(..) = code
| ObligationCauseCode::WhereClauseInExpr(..)
| ObligationCauseCode::SpannedWhereClauseInExpr(..) = code
{ {
try_borrowing(poly_trait_pred, &never_suggest_borrow) try_borrowing(poly_trait_pred, &never_suggest_borrow)
} else { } else {
@ -2102,10 +2104,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
err: &mut Diag<'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 // the uninstantiated predicate list of the called function. And check
// that the predicate that we failed to satisfy is a `Fn`-like trait. // 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 predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
&& let Some(pred) = predicates.predicates.get(*idx) && let Some(pred) = predicates.predicates.get(*idx)
&& let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder()
@ -2746,12 +2748,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ObligationCauseCode::TupleElem => { ObligationCauseCode::TupleElem => {
err.note("only the last element of a tuple may have a dynamically sized type"); err.note("only the last element of a tuple may have a dynamically sized type");
} }
ObligationCauseCode::WhereClause(_) | ObligationCauseCode::WhereClauseInExpr(..) => { ObligationCauseCode::WhereClause(item_def_id, span)
// We hold the `DefId` of the item introducing the obligation, but displaying it | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
// doesn't add user usable information. It always point at an associated item. if !span.is_dummy() =>
} {
ObligationCauseCode::SpannedWhereClause(item_def_id, span)
| ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..) => {
let item_name = tcx.def_path_str(item_def_id); 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 short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id));
let mut multispan = MultiSpan::from(span); let mut multispan = MultiSpan::from(span);
@ -2882,6 +2882,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.help(help); 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 } => { ObligationCauseCode::Coercion { source, target } => {
let source = let source =
tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file); 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 // to an associated type (as seen from `trait_pred`) in the predicate. Like in
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>` // trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
let mut type_diffs = vec![]; 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 Some(node_args) = typeck_results.node_args_opt(call_hir_id)
&& let where_clauses = && let where_clauses =
self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args)

View file

@ -1535,9 +1535,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
*err, *err,
); );
let code = error.obligation.cause.code().peel_derives().peel_match_impls(); let code = error.obligation.cause.code().peel_derives().peel_match_impls();
if let ObligationCauseCode::SpannedWhereClause(..) if let ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::WhereClause(..)
| ObligationCauseCode::SpannedWhereClauseInExpr(..)
| ObligationCauseCode::WhereClauseInExpr(..) = code | ObligationCauseCode::WhereClauseInExpr(..) = code
{ {
self.note_obligation_cause_code( self.note_obligation_cause_code(
@ -1612,11 +1610,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let is_normalized_term_expected = !matches!( let is_normalized_term_expected = !matches!(
obligation.cause.code().peel_derives(), obligation.cause.code().peel_derives(),
ObligationCauseCode::WhereClause(_) |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr(
| ObligationCauseCode::SpannedWhereClause(_, _) ..
| ObligationCauseCode::WhereClauseInExpr(..) ) | ObligationCauseCode::Coercion { .. }
| ObligationCauseCode::SpannedWhereClauseInExpr(..)
| ObligationCauseCode::Coercion { .. }
); );
let (expected, actual) = if is_normalized_term_expected { 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() | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code()
{ {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
@ -2883,12 +2879,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
else { else {
return; return;
}; };
let (ObligationCauseCode::SpannedWhereClause(item_def_id, span) let (ObligationCauseCode::WhereClause(item_def_id, span)
| ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..)) = | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) =
*obligation.cause.code().peel_derives() *obligation.cause.code().peel_derives()
else { else {
return; return;
}; };
if span.is_dummy() {
return;
}
debug!(?pred, ?item_def_id, ?span); debug!(?pred, ?item_def_id, ?span);
let (Some(node), true) = ( let (Some(node), true) = (
@ -3181,10 +3180,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ObligationCauseCode::RustCall => { ObligationCauseCode::RustCall => {
err.primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); 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.code(E0059);
err.primary_message(format!( err.primary_message(format!(
"type parameter to bare `{}` trait must be a tuple", "type parameter to bare `{}` trait must be a tuple",

View file

@ -573,11 +573,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
// cause code, inherent projections will be printed with identity instantiation in // cause code, inherent projections will be printed with identity instantiation in
// diagnostics which is not ideal. // diagnostics which is not ideal.
// Consider creating separate cause codes for this specific situation. // Consider creating separate cause codes for this specific situation.
if span.is_dummy() { ObligationCauseCode::WhereClause(alias_ty.def_id, span),
ObligationCauseCode::WhereClause(alias_ty.def_id)
} else {
ObligationCauseCode::SpannedWhereClause(alias_ty.def_id, span)
},
); );
obligations.push(Obligation::with_depth( obligations.push(Obligation::with_depth(
@ -2130,17 +2126,11 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
| ObligationCauseCode::AscribeUserTypeProvePredicate(..) | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
) { ) {
obligation.cause.clone() obligation.cause.clone()
} else if span.is_dummy() {
ObligationCause::new(
obligation.cause.span,
obligation.cause.body_id,
ObligationCauseCode::WhereClause(obligation.predicate.def_id),
)
} else { } else {
ObligationCause::new( ObligationCause::new(
obligation.cause.span, obligation.cause.span,
obligation.cause.body_id, obligation.cause.body_id,
ObligationCauseCode::SpannedWhereClause(obligation.predicate.def_id, span), ObligationCauseCode::WhereClause(obligation.predicate.def_id, span),
) )
}; };
nested.push(Obligation::with_depth( nested.push(Obligation::with_depth(

View file

@ -568,11 +568,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
iter::zip(predicates, origins.into_iter().rev()) iter::zip(predicates, origins.into_iter().rev())
.map(|((pred, span), origin_def_id)| { .map(|((pred, span), origin_def_id)| {
let code = if span.is_dummy() { let code = ObligationCauseCode::WhereClause(origin_def_id, span);
ObligationCauseCode::WhereClause(origin_def_id)
} else {
ObligationCauseCode::SpannedWhereClause(origin_def_id, span)
};
let cause = self.cause(code); let cause = self.cause(code);
traits::Obligation::with_depth( traits::Obligation::with_depth(
self.tcx(), self.tcx(),

View file

@ -1,19 +1,33 @@
error: implementation of `Trait` is not general enough error: implementation of `Trait` is not general enough
--> $DIR/issue-59311.rs:17:5 --> $DIR/issue-59311.rs:17:5
| |
LL | / pub fn crash<V>(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(|| {}); LL | v.t(|| {});
| ^^^^^^^^^^ implementation of `Trait` is not general enough | ^^^^^^^^^^
| |
= 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: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0`
error: implementation of `Trait` is not general enough error: implementation of `Trait` is not general enough
--> $DIR/issue-59311.rs:17:5 --> $DIR/issue-59311.rs:17:5
| |
LL | / pub fn crash<V>(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(|| {}); LL | v.t(|| {});
| ^^^^^^^^^^ implementation of `Trait` is not general enough | ^^^^^^^^^^
| |
= 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: ...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` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

View file

@ -0,0 +1,11 @@
// Minimized test from #59311.
pub fn crash()
where
for<'a> &'a (): 'static,
{
|| {};
//~^ ERROR higher-ranked lifetime error
}
fn main() {}

View file

@ -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