Skip to content

Consolidate obligation cause codes for where clauses #124988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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(
Expand Down
11 changes: 3 additions & 8 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> 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,
Expand Down Expand Up @@ -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)
};

Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
)
},
);
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
16 changes: 6 additions & 10 deletions compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_infer/src/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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..."
)
}
}
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_infer/src/infer/outlives/obligations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
)
Expand Down
25 changes: 9 additions & 16 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>),
Expand Down
Loading
Loading