Skip to content

Commit 2507e83

Browse files
Stop using the whole match expr span for an arm's obligation span
1 parent 5f5c243 commit 2507e83

File tree

5 files changed

+18
-21
lines changed

5 files changed

+18
-21
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9494
(None, arm.body.span)
9595
};
9696

97-
let (span, code) = match prior_arm {
97+
let code = match prior_arm {
9898
// The reason for the first arm to fail is not that the match arms diverge,
9999
// but rather that there's a prior obligation that doesn't hold.
100-
None => {
101-
(arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src))
102-
}
103-
Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => (
104-
expr.span,
100+
None => ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src),
101+
Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => {
105102
ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause {
106103
arm_block_id,
107104
arm_span,
@@ -110,13 +107,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
110107
prior_arm_ty,
111108
prior_arm_span,
112109
scrut_span: scrut.span,
110+
expr_span: expr.span,
113111
source: match_src,
114112
prior_non_diverging_arms: prior_non_diverging_arms.clone(),
115113
tail_defines_return_position_impl_trait,
116-
})),
117-
),
114+
}))
115+
}
118116
};
119-
let cause = self.cause(span, code);
117+
let cause = self.cause(arm_span, code);
120118

121119
// This is the moral equivalent of `coercion.coerce(self, cause, arm.body, arm_ty)`.
122120
// We use it this way to be able to expand on the potential error and detect when a

compiler/rustc_middle/src/traits/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,8 @@ pub struct MatchExpressionArmCause<'tcx> {
519519
pub prior_arm_span: Span,
520520
pub scrut_span: Span,
521521
pub source: hir::MatchSource,
522+
// Span of the *whole* match expr
523+
pub expr_span: Span,
522524
pub prior_non_diverging_arms: Vec<Span>,
523525
// Is the expectation of this match expression an RPIT?
524526
pub tail_defines_return_position_impl_trait: Option<LocalDefId>,

compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
412412
source,
413413
ref prior_non_diverging_arms,
414414
scrut_span,
415+
expr_span,
415416
..
416417
}) => match source {
417418
hir::MatchSource::TryDesugar(scrut_hir_id) => {
@@ -460,12 +461,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
460461
format!("this and all prior arms are found to be of type `{t}`"),
461462
);
462463
}
463-
let outer = if any_multiline_arm || !source_map.is_multiline(cause.span) {
464+
let outer = if any_multiline_arm || !source_map.is_multiline(expr_span) {
464465
// Cover just `match` and the scrutinee expression, not
465466
// the entire match body, to reduce diagram noise.
466-
cause.span.shrink_to_lo().to(scrut_span)
467+
expr_span.shrink_to_lo().to(scrut_span)
467468
} else {
468-
cause.span
469+
expr_span
469470
};
470471
let msg = "`match` arms have incompatible types";
471472
err.span_label(outer, msg);

tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ fn main() {
2222
Some(()) => &S,
2323
None => &R, //~ ERROR E0308
2424
}
25-
let t: &dyn Trait = match opt() { //~ ERROR E0038
25+
let t: &dyn Trait = match opt() {
2626
Some(()) => &S, //~ ERROR E0038
27-
None => &R,
27+
None => &R, //~ ERROR E0038
2828
};
2929
}

tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr

+3-7
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,10 @@ LL | trait Trait: Sized {}
3131
= note: required for the cast from `&S` to `&dyn Trait`
3232

3333
error[E0038]: the trait `Trait` cannot be made into an object
34-
--> $DIR/wf-dyn-incompat-trait-obj-match.rs:25:25
34+
--> $DIR/wf-dyn-incompat-trait-obj-match.rs:27:17
3535
|
36-
LL | let t: &dyn Trait = match opt() {
37-
| _________________________^
38-
LL | | Some(()) => &S,
39-
LL | | None => &R,
40-
LL | | };
41-
| |_____^ `Trait` cannot be made into an object
36+
LL | None => &R,
37+
| ^^ `Trait` cannot be made into an object
4238
|
4339
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
4440
--> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14

0 commit comments

Comments
 (0)