about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-10-27 22:35:17 +0000
committerMichael Goulet <michael@errs.io>2024-10-27 22:48:03 +0000
commit2507e83d7bb0dd9e7217b10b13afc61763dc1eca (patch)
tree3dd9dc0fbdb4e6454fd2c404c521a497153ca933
parent5f5c243ca020e45cb6ee48a1f635a929eb611fd2 (diff)
downloadrust-2507e83d7bb0dd9e7217b10b13afc61763dc1eca.tar.gz
rust-2507e83d7bb0dd9e7217b10b13afc61763dc1eca.zip
Stop using the whole match expr span for an arm's obligation span
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs16
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs7
-rw-r--r--tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs4
-rw-r--r--tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr10
5 files changed, 18 insertions, 21 deletions
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index e68caa3e2e3..3372cae7a51 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -94,14 +94,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (None, arm.body.span)
             };
 
-            let (span, code) = match prior_arm {
+            let code = match prior_arm {
                 // The reason for the first arm to fail is not that the match arms diverge,
                 // but rather that there's a prior obligation that doesn't hold.
-                None => {
-                    (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src))
-                }
-                Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => (
-                    expr.span,
+                None => ObligationCauseCode::BlockTailExpression(arm.body.hir_id, match_src),
+                Some((prior_arm_block_id, prior_arm_ty, prior_arm_span)) => {
                     ObligationCauseCode::MatchExpressionArm(Box::new(MatchExpressionArmCause {
                         arm_block_id,
                         arm_span,
@@ -110,13 +107,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         prior_arm_ty,
                         prior_arm_span,
                         scrut_span: scrut.span,
+                        expr_span: expr.span,
                         source: match_src,
                         prior_non_diverging_arms: prior_non_diverging_arms.clone(),
                         tail_defines_return_position_impl_trait,
-                    })),
-                ),
+                    }))
+                }
             };
-            let cause = self.cause(span, code);
+            let cause = self.cause(arm_span, code);
 
             // This is the moral equivalent of `coercion.coerce(self, cause, arm.body, arm_ty)`.
             // We use it this way to be able to expand on the potential error and detect when a
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 8ee8b4c4823..7237a7014e8 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -519,6 +519,8 @@ pub struct MatchExpressionArmCause<'tcx> {
     pub prior_arm_span: Span,
     pub scrut_span: Span,
     pub source: hir::MatchSource,
+    // Span of the *whole* match expr
+    pub expr_span: Span,
     pub prior_non_diverging_arms: Vec<Span>,
     // Is the expectation of this match expression an RPIT?
     pub tail_defines_return_position_impl_trait: Option<LocalDefId>,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index b9a569d25e3..0cbb43b8763 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -412,6 +412,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 source,
                 ref prior_non_diverging_arms,
                 scrut_span,
+                expr_span,
                 ..
             }) => match source {
                 hir::MatchSource::TryDesugar(scrut_hir_id) => {
@@ -460,12 +461,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             format!("this and all prior arms are found to be of type `{t}`"),
                         );
                     }
-                    let outer = if any_multiline_arm || !source_map.is_multiline(cause.span) {
+                    let outer = if any_multiline_arm || !source_map.is_multiline(expr_span) {
                         // Cover just `match` and the scrutinee expression, not
                         // the entire match body, to reduce diagram noise.
-                        cause.span.shrink_to_lo().to(scrut_span)
+                        expr_span.shrink_to_lo().to(scrut_span)
                     } else {
-                        cause.span
+                        expr_span
                     };
                     let msg = "`match` arms have incompatible types";
                     err.span_label(outer, msg);
diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs
index 07e90538b85..6eba6b7abec 100644
--- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs
+++ b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.rs
@@ -22,8 +22,8 @@ fn main() {
         Some(()) => &S,
         None => &R,  //~ ERROR E0308
     }
-    let t: &dyn Trait = match opt() { //~ ERROR E0038
+    let t: &dyn Trait = match opt() {
         Some(()) => &S, //~ ERROR E0038
-        None => &R,
+        None => &R, //~ ERROR E0038
     };
 }
diff --git a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
index d7366e12256..6cd4ebf8412 100644
--- a/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
+++ b/tests/ui/wf/wf-dyn-incompat-trait-obj-match.stderr
@@ -31,14 +31,10 @@ LL | trait Trait: Sized {}
    = note: required for the cast from `&S` to `&dyn Trait`
 
 error[E0038]: the trait `Trait` cannot be made into an object
-  --> $DIR/wf-dyn-incompat-trait-obj-match.rs:25:25
+  --> $DIR/wf-dyn-incompat-trait-obj-match.rs:27:17
    |
-LL |       let t: &dyn Trait = match opt() {
-   |  _________________________^
-LL | |         Some(()) => &S,
-LL | |         None => &R,
-LL | |     };
-   | |_____^ `Trait` cannot be made into an object
+LL |         None => &R,
+   |                 ^^ `Trait` cannot be made into an object
    |
 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>
   --> $DIR/wf-dyn-incompat-trait-obj-match.rs:6:14