From fe8b12f8cfd27984a6102c441b49023d5bce0b02 Mon Sep 17 00:00:00 2001 From: dianne Date: Sat, 21 Dec 2024 13:23:57 -0800 Subject: [PATCH] only avoid blaming assignments from argument patterns --- .../src/diagnostics/conflict_errors.rs | 2 +- .../src/diagnostics/region_errors.rs | 6 ++-- .../rustc_borrowck/src/region_infer/mod.rs | 17 +++++------ compiler/rustc_borrowck/src/type_check/mod.rs | 28 ++++++++++--------- compiler/rustc_middle/src/mir/query.rs | 7 +---- ...egion_subtyping_basic.main.nll.0.32bit.mir | 4 +-- ...egion_subtyping_basic.main.nll.0.64bit.mir | 4 +-- tests/mir-opt/storage_ranges.main.nll.0.mir | 2 +- tests/ui/fn/fn_def_coercion.rs | 4 +-- tests/ui/fn/fn_def_coercion.stderr | 9 ++++-- .../adt-tuple-struct-calls.stderr | 18 ++++-------- .../nll/user-annotations/method-ufcs-1.stderr | 7 ++--- .../nll/user-annotations/method-ufcs-2.stderr | 7 ++--- .../promoted-annotation.stderr | 6 ++-- 14 files changed, 54 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 8a43e4b54b195..2d993a3fd16f7 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 051778dcace80..f0baa20648cd2 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); @@ -673,7 +673,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()) - || (matches!(category, ConstraintCategory::Assignment { .. }) + || (*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 73e25cbae27ed..d6375c5dc2701 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2080,25 +2080,22 @@ impl<'tcx> RegionInferenceContext<'tcx> { | ConstraintCategory::CallArgument(_) | ConstraintCategory::CopyBound | ConstraintCategory::SizedBound - | ConstraintCategory::Assignment { has_interesting_ty: true } + | ConstraintCategory::Assignment | ConstraintCategory::Usage | ConstraintCategory::ClosureUpvar(_) => 2, - // Give assignments a lower priority when flagged as less likely to be interesting. - // In particular, de-prioritize MIR assignments lowered from argument patterns. - ConstraintCategory::Assignment { has_interesting_ty: false } => 3, // Generic arguments are unlikely to be what relates regions together - ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg) => 4, + ConstraintCategory::TypeAnnotation(AnnotationSource::GenericArg) => 3, // We handle predicates and opaque types specially; don't prioritize them here. - ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 5, + ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4, // `Boring` constraints can correspond to user-written code and have useful spans, // but don't provide any other useful information for diagnostics. - ConstraintCategory::Boring => 6, + ConstraintCategory::Boring => 5, // `BoringNoLocation` constraints can point to user-written code, but are less // specific, and are not used for relations that would make sense to blame. - ConstraintCategory::BoringNoLocation => 7, + ConstraintCategory::BoringNoLocation => 6, // Do not blame internal constraints. - ConstraintCategory::Internal => 8, - ConstraintCategory::IllegalUniverse => 9, + ConstraintCategory::Internal => 7, + ConstraintCategory::IllegalUniverse => 8, } }; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 495ec956f35a8..1eb471968b285 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -892,18 +892,20 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Some(l) if !body.local_decls[l].is_user_variable() => { ConstraintCategory::Boring } - 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 }, + Some(_) + if let Some(body_id) = tcx + .hir_node_by_def_id(body.source.def_id().expect_local()) + .body_id() + && let params = tcx.hir().body(body_id).params + && params + .iter() + .any(|param| param.span.contains(stmt.source_info.span)) => + { + // Assignments generated from lowering argument patterns shouldn't be called + // "assignments" in diagnostics and aren't interesting to blame for errors. + ConstraintCategory::Boring + } + _ => ConstraintCategory::Assignment, }; debug!( "assignment category: {:?} {:?}", @@ -1238,7 +1240,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ConstraintCategory::Boring } // The return type of a call is interesting for diagnostics. - _ => ConstraintCategory::Assignment { has_interesting_ty: true }, + _ => ConstraintCategory::Assignment, }; 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 f2fbc63ee4112..db5da941f1e7b 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -242,12 +242,7 @@ pub enum ConstraintCategory<'tcx> { CallArgument(Option>), CopyBound, SizedBound, - 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, - }, + Assignment, /// A constraint that came from a usage of a variable (e.g. in an ADT expression /// like `Foo { field: my_val }`) Usage, diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 7f4a2bbbb5c34..35e44b2314a50 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -17,8 +17,8 @@ | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=3]} | '?4 live at {bb1[4..=7], bb2[0..=2]} -| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0) -| '?3: '?4 due to Assignment { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) +| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0) +| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) | | Borrows | bw0: issued at bb1[0] in '?2 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 1d80df76b3f77..6d415f42d06f3 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -17,8 +17,8 @@ | '?2 live at {bb1[0]} | '?3 live at {bb1[1..=3]} | '?4 live at {bb1[4..=7], bb2[0..=2]} -| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0) -| '?3: '?4 due to Assignment { has_interesting_ty: false } at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) +| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:19:13: 19:18 (#0) +| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:20:13: 20:14 (#0) | | Borrows | bw0: issued at bb1[0] in '?2 diff --git a/tests/mir-opt/storage_ranges.main.nll.0.mir b/tests/mir-opt/storage_ranges.main.nll.0.mir index 291e3bbc87354..ae8cd0c894dac 100644 --- a/tests/mir-opt/storage_ranges.main.nll.0.mir +++ b/tests/mir-opt/storage_ranges.main.nll.0.mir @@ -15,7 +15,7 @@ | '?1 live at {bb0[0..=22]} | '?2 live at {bb0[10]} | '?3 live at {bb0[11]} -| '?2: '?3 due to Assignment { has_interesting_ty: false } at Single(bb0[10]) ($DIR/storage_ranges.rs:7:17: 7:25 (#0) +| '?2: '?3 due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:7:17: 7:25 (#0) | | Borrows | bw0: issued at bb0[10] in '?2 diff --git a/tests/ui/fn/fn_def_coercion.rs b/tests/ui/fn/fn_def_coercion.rs index eea9e480827fb..31c8fa41de17c 100644 --- a/tests/ui/fn/fn_def_coercion.rs +++ b/tests/ui/fn/fn_def_coercion.rs @@ -47,11 +47,11 @@ fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { let x = match true { true => foo::<&'c ()>, //~ ERROR lifetime may not live long enough - false => foo::<&'a ()>, + false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough }; x(a); - x(b); //~ ERROR lifetime may not live long enough + x(b); x(c); } diff --git a/tests/ui/fn/fn_def_coercion.stderr b/tests/ui/fn/fn_def_coercion.stderr index a4dc72310815b..c2776887b79d4 100644 --- a/tests/ui/fn/fn_def_coercion.stderr +++ b/tests/ui/fn/fn_def_coercion.stderr @@ -133,17 +133,20 @@ LL | true => foo::<&'c ()>, = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/fn_def_coercion.rs:54:5 + --> $DIR/fn_def_coercion.rs:50:18 | LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) { | -- -- lifetime `'b` defined here | | | lifetime `'a` defined here ... -LL | x(b); - | ^^^^ argument requires that `'b` must outlive `'a` +LL | false => foo::<&'a ()>, + | ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of a function pointer to `foo` + = note: the function `foo` is invariant over the parameter `T` + = help: see for more information about variance help: the following changes may resolve your lifetime errors | diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr index 2084697e7e26d..1478ad1431ba4 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr @@ -4,11 +4,9 @@ error[E0597]: `c` does not live long enough LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'static u32>; + | -------------------------- assignment requires that `c` is borrowed for `'static` LL | f(&c); - | --^^- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'static` + | ^^ borrowed value does not live long enough LL | } | - `c` dropped here while still borrowed @@ -20,11 +18,9 @@ LL | fn annot_reference_named_lifetime<'a>(_d: &'a u32) { LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'a u32>; + | --------------------- assignment requires that `c` is borrowed for `'a` LL | f(&c); - | --^^- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'a` + | ^^ borrowed value does not live long enough LL | } | - `c` dropped here while still borrowed @@ -37,11 +33,9 @@ LL | let _closure = || { LL | let c = 66; | - binding `c` declared here LL | let f = SomeStruct::<&'a u32>; + | --------------------- assignment requires that `c` is borrowed for `'a` LL | f(&c); - | --^^- - | | | - | | borrowed value does not live long enough - | argument requires that `c` is borrowed for `'a` + | ^^ borrowed value does not live long enough LL | }; | - `c` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/method-ufcs-1.stderr b/tests/ui/nll/user-annotations/method-ufcs-1.stderr index c42ea0172cf75..087e270c70f7d 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-1.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-1.stderr @@ -4,11 +4,10 @@ error[E0597]: `a` does not live long enough LL | let a = 22; | - binding `a` declared here ... +LL | let x = <&'static u32 as Bazoom<_>>::method; + | ----------------------------------- assignment requires that `a` is borrowed for `'static` LL | x(&a, b, c); - | --^^------- - | | | - | | borrowed value does not live long enough - | argument requires that `a` is borrowed for `'static` + | ^^ borrowed value does not live long enough LL | } | - `a` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/method-ufcs-2.stderr b/tests/ui/nll/user-annotations/method-ufcs-2.stderr index 287337c7d52d3..c89bed3b1b18f 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-2.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-2.stderr @@ -4,11 +4,10 @@ error[E0597]: `a` does not live long enough LL | let a = 22; | - binding `a` declared here ... +LL | let x = <&'static u32 as Bazoom<_>>::method; + | ----------------------------------- assignment requires that `a` is borrowed for `'static` LL | x(&a, b, c); - | --^^------- - | | | - | | borrowed value does not live long enough - | argument requires that `a` is borrowed for `'static` + | ^^ borrowed value does not live long enough LL | } | - `a` dropped here while still borrowed diff --git a/tests/ui/nll/user-annotations/promoted-annotation.stderr b/tests/ui/nll/user-annotations/promoted-annotation.stderr index 39993475796f5..ca99e53187091 100644 --- a/tests/ui/nll/user-annotations/promoted-annotation.stderr +++ b/tests/ui/nll/user-annotations/promoted-annotation.stderr @@ -6,11 +6,9 @@ LL | fn foo<'a>() { LL | let x = 0; | - binding `x` declared here LL | let f = &drop::<&'a i32>; + | ---------------- assignment requires that `x` is borrowed for `'a` LL | f(&x); - | --^^- - | | | - | | borrowed value does not live long enough - | argument requires that `x` is borrowed for `'a` + | ^^ borrowed value does not live long enough LL | LL | } | - `x` dropped here while still borrowed