Skip to content

Commit 888f8b8

Browse files
committed
Add more HIR tracking information to ObligationCauseCode
This data will help with extending E0038 object safety errors.
1 parent b71fd5b commit 888f8b8

File tree

4 files changed

+15
-14
lines changed

4 files changed

+15
-14
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
487487
fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceResult<'tcx> {
488488
source = self.shallow_resolve(source);
489489
target = self.shallow_resolve(target);
490-
debug!(?source, ?target);
490+
debug!(?source, ?target, ?self.cause);
491491

492492
// We don't apply any coercions incase either the source or target
493493
// aren't sufficiently well known but tend to instead just equate
@@ -565,11 +565,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
565565
let mut selcx = traits::SelectionContext::new(self);
566566

567567
// Create an obligation for `Source: CoerceUnsized<Target>`.
568-
let cause = ObligationCause::new(
569-
self.cause.span,
570-
self.body_id,
571-
ObligationCauseCode::Coercion { source, target },
572-
);
568+
let mut cause =
569+
ObligationCause::new(self.cause.span, self.body_id, self.cause.code().clone());
570+
cause.map_code(|parent_code| ObligationCauseCode::Coercion { source, target, parent_code });
573571

574572
// Use a FIFO queue for this custom fulfillment procedure.
575573
//
@@ -993,8 +991,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
993991
}
994992
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
995993

996-
let cause =
997-
cause.unwrap_or_else(|| self.cause(expr.span, ObligationCauseCode::ExprAssignable));
994+
let cause = cause.unwrap_or_else(|| {
995+
self.cause(expr.span, ObligationCauseCode::ExprAssignable(Some(expr.hir_id)))
996+
});
998997
let coerce = Coerce::new(self, cause, allow_two_phase);
999998
let ok = self.commit_if_ok(|_| coerce.coerce(source, target))?;
1000999

@@ -1016,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10161015
let source = self.resolve_vars_with_obligations(expr_ty);
10171016
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
10181017

1019-
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable);
1018+
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable(None));
10201019
// We don't ever need two-phase here since we throw out the result of the coercion
10211020
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
10221021
self.probe(|_| {
@@ -1033,7 +1032,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10331032
/// how many dereference steps needed to achieve `expr_ty <: target`. If
10341033
/// it's not possible, return `None`.
10351034
pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<usize> {
1036-
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable);
1035+
let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable(None));
10371036
// We don't ever need two-phase here since we throw out the result of the coercion
10381037
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
10391038
coerce

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ pub enum ObligationCauseCode<'tcx> {
268268
Coercion {
269269
source: Ty<'tcx>,
270270
target: Ty<'tcx>,
271+
/// The obligation introduced by this argument.
272+
parent_code: InternedObligationCauseCode<'tcx>,
271273
},
272274

273275
/// Various cases where expressions must be `Sized` / `Copy` / etc.
@@ -355,7 +357,7 @@ pub enum ObligationCauseCode<'tcx> {
355357
},
356358

357359
/// Checking that this expression can be assigned to its target.
358-
ExprAssignable,
360+
ExprAssignable(Option<HirId>),
359361

360362
/// Computing common supertype in the arms of a match expression
361363
MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,7 +2711,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27112711
let tcx = self.tcx;
27122712
let predicate = predicate.upcast(tcx);
27132713
match *cause_code {
2714-
ObligationCauseCode::ExprAssignable
2714+
ObligationCauseCode::ExprAssignable(_)
27152715
| ObligationCauseCode::MatchExpressionArm { .. }
27162716
| ObligationCauseCode::Pattern { .. }
27172717
| ObligationCauseCode::IfExpression { .. }
@@ -2890,7 +2890,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
28902890
// We hold the `DefId` of the item introducing the obligation, but displaying it
28912891
// doesn't add user usable information. It always point at an associated item.
28922892
}
2893-
ObligationCauseCode::Coercion { source, target } => {
2893+
ObligationCauseCode::Coercion { source, target, .. } => {
28942894
let source =
28952895
tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file);
28962896
let target =

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
656656
}
657657
}
658658

659-
if let ObligationCauseCode::Coercion { source, target } =
659+
if let ObligationCauseCode::Coercion { source, target, .. } =
660660
*obligation.cause.code().peel_derives()
661661
{
662662
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {

0 commit comments

Comments
 (0)