about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2024-12-19 01:16:53 -0800
committerdianne <diannes.gm@gmail.com>2025-01-06 16:12:11 -0800
commit50222dba2edd2bcf265a8ca4753de0df59bf587d (patch)
tree80fbafb856e71cb4bf733562ade3931efebb3e62 /compiler
parent31e4d8175a3ef5d10f2319e98a20ca6c81614487 (diff)
downloadrust-50222dba2edd2bcf265a8ca4753de0df59bf587d.tar.gz
rust-50222dba2edd2bcf265a8ca4753de0df59bf587d.zip
`best_blame_constraint`: avoid blaming assignments without user-provided types
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs6
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs1
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs16
-rw-r--r--compiler/rustc_middle/src/mir/query.rs7
5 files changed, 25 insertions, 7 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 2d993a3fd16..8a43e4b54b1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2911,7 +2911,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             (
                 name,
                 BorrowExplanation::MustBeValidFor {
-                    category: ConstraintCategory::Assignment,
+                    category: ConstraintCategory::Assignment { .. },
                     from_closure: false,
                     region_name:
                         RegionName {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 481b8d41f10..78809908180 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -41,7 +41,7 @@ impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
     fn description(&self) -> &'static str {
         // Must end with a space. Allows for empty names to be provided.
         match self {
-            ConstraintCategory::Assignment => "assignment ",
+            ConstraintCategory::Assignment { .. } => "assignment ",
             ConstraintCategory::Return(_) => "returning this value ",
             ConstraintCategory::Yield => "yielding this value ",
             ConstraintCategory::UseAsConst => "using this value as a constant ",
@@ -481,7 +481,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             (ConstraintCategory::Return(kind), true, false) if self.is_closure_fn_mut(fr) => {
                 self.report_fnmut_error(&errci, kind)
             }
-            (ConstraintCategory::Assignment, true, false)
+            (ConstraintCategory::Assignment { .. }, true, false)
             | (ConstraintCategory::CallArgument(_), true, false) => {
                 let mut db = self.report_escaping_data_error(&errci);
 
@@ -672,7 +672,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
         // Revert to the normal error in these cases.
         // Assignments aren't "escapes" in function items.
         if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none())
-            || (*category == ConstraintCategory::Assignment
+            || (matches!(category, ConstraintCategory::Assignment { .. })
                 && self.regioncx.universal_regions().defining_ty.is_fn_def())
             || self.regioncx.universal_regions().defining_ty.is_const()
         {
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 4ceb2fcd8d7..7e8fad8698a 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2034,6 +2034,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     | ConstraintCategory::BoringNoLocation
                     | ConstraintCategory::Internal
                     | ConstraintCategory::Predicate(_)
+                    | ConstraintCategory::Assignment { has_interesting_ty: false }
             ) && constraint.span.desugaring_kind().is_none_or(|kind| {
                 // Try to avoid blaming constraints from desugarings, since they may not clearly
                 // clearly match what users have written. As an exception, allow blaming returns
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 10fb8a399a2..a436edd85d9 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -892,7 +892,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     Some(l) if !body.local_decls[l].is_user_variable() => {
                         ConstraintCategory::Boring
                     }
-                    _ => ConstraintCategory::Assignment,
+                    Some(l) => ConstraintCategory::Assignment {
+                        has_interesting_ty: body.local_decls[l].user_ty.is_some()
+                            || matches!(
+                                body.local_decls[l].local_info(),
+                                LocalInfo::User(BindingForm::Var(VarBindingForm {
+                                    opt_ty_info: Some(_),
+                                    ..
+                                }))
+                            ),
+                    },
+                    // Assignments to projections should be considered interesting.
+                    _ => ConstraintCategory::Assignment { has_interesting_ty: true },
                 };
                 debug!(
                     "assignment category: {:?} {:?}",
@@ -1226,7 +1237,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     Some(l) if !body.local_decls[l].is_user_variable() => {
                         ConstraintCategory::Boring
                     }
-                    _ => ConstraintCategory::Assignment,
+                    // The return type of a call is interesting for diagnostics.
+                    _ => ConstraintCategory::Assignment { has_interesting_ty: true },
                 };
 
                 let locations = term_location.to_locations();
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 429be9bc725..c2bb95a91c4 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -250,7 +250,12 @@ pub enum ConstraintCategory<'tcx> {
     CallArgument(#[derive_where(skip)] Option<Ty<'tcx>>),
     CopyBound,
     SizedBound,
-    Assignment,
+    Assignment {
+        /// Whether this assignment is likely to be interesting to refer to in diagnostics.
+        /// Currently, this is true when it's assigning to a projection, when it's assigning from
+        /// the return value of a call, and when it has a user-provided type annotation.
+        has_interesting_ty: bool,
+    },
     /// A constraint that came from a usage of a variable (e.g. in an ADT expression
     /// like `Foo { field: my_val }`)
     Usage,