Skip to content

Commit 4e51aeb

Browse files
committed
Account for more cases
1 parent 4550f3c commit 4e51aeb

File tree

3 files changed

+82
-10
lines changed

3 files changed

+82
-10
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
500500
}
501501
};
502502

503-
self.explain_impl_static_obligation(&mut diag, cause.code(), outlived_fr);
503+
if let ConstraintCategory::CallArgument(Some(ty)) = category {
504+
self.explain_impl_static_obligation(&mut diag, ty, cause.span, outlived_fr);
505+
} else if let ObligationCauseCode::MethodCallConstraint(ty, call_span) = cause.code() {
506+
self.explain_impl_static_obligation(&mut diag, *ty, *call_span, outlived_fr);
507+
}
504508

505509
match variance_info {
506510
ty::VarianceDiagInfo::None => {}
@@ -622,14 +626,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
622626
fn explain_impl_static_obligation(
623627
&self,
624628
diag: &mut Diag<'_>,
625-
code: &ObligationCauseCode<'tcx>,
629+
ty: Ty<'tcx>,
630+
call_span: Span,
626631
outlived_fr: RegionVid,
627632
) {
628633
let tcx = self.infcx.tcx;
629-
debug!(?code);
630-
let ObligationCauseCode::MethodCallConstraint(ty, call_span) = code else {
631-
return;
632-
};
633634
let ty::FnDef(def_id, args) = ty.kind() else {
634635
return;
635636
};
@@ -723,7 +724,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
723724
if let ty::Ref(region, _, _) = self
724725
.infcx
725726
.instantiate_binder_with_fresh_vars(
726-
*call_span,
727+
call_span,
727728
BoundRegionConversionTime::FnCall,
728729
tcx.fn_sig(def_id).instantiate_identity().inputs().map_bound(|inputs| inputs[0]),
729730
)
@@ -805,10 +806,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
805806
let span: MultiSpan = predicates.into();
806807
diag.span_note(span, format!("the `impl` on `{ty}` has {a_static_lt}"));
807808
}
808-
if new_primary_span && diag.span.primary_span() != Some(*call_span) {
809-
diag.replace_span_with(*call_span, false);
809+
if new_primary_span && diag.span.primary_span() != Some(call_span) {
810+
diag.replace_span_with(call_span, false);
810811
diag.span_label(
811-
*call_span,
812+
call_span,
812813
"calling this method introduces a `'static` lifetime requirement",
813814
);
814815
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::cell::*;
2+
3+
#[derive(Default)]
4+
struct Test {
5+
pub foo: u32,
6+
}
7+
8+
trait FooSetter {
9+
fn set_foo(&mut self, value: u32);
10+
}
11+
12+
impl FooSetter for Test {
13+
fn set_foo(&mut self, value: u32) {
14+
self.foo = value;
15+
}
16+
}
17+
18+
trait BaseSetter{
19+
fn set(&mut self, value: u32);
20+
}
21+
impl BaseSetter for dyn FooSetter {
22+
fn set(&mut self, value: u32){
23+
self.set_foo(value);
24+
}
25+
}
26+
27+
struct TestHolder<'a> {
28+
pub holder: Option<RefCell<&'a mut dyn FooSetter>>,
29+
}
30+
31+
impl <'a>TestHolder<'a>{
32+
pub fn test_foo(&self){
33+
self.holder.as_ref().unwrap().borrow_mut().set(20);
34+
//~^ ERROR borrowed data escapes outside of method
35+
}
36+
}
37+
38+
fn main() {
39+
let mut test = Test::default();
40+
test.foo = 10;
41+
{
42+
let holder = TestHolder { holder: Some(RefCell::from(&mut test))};
43+
44+
holder.test_foo();
45+
}
46+
test.foo = 30;
47+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0521]: borrowed data escapes outside of method
2+
--> $DIR/dyn-trait-static-obligation.rs:33:8
3+
|
4+
LL | impl <'a>TestHolder<'a>{
5+
| -- lifetime `'a` defined here
6+
LL | pub fn test_foo(&self){
7+
| ----- `self` is a reference that is only valid in the method body
8+
LL | self.holder.as_ref().unwrap().borrow_mut().set(20);
9+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10+
| |
11+
| `self` escapes the method body here
12+
| argument requires that `'a` must outlive `'static`
13+
|
14+
= note: requirement occurs because of a mutable reference to `dyn FooSetter`
15+
= note: mutable references are invariant over their type parameter
16+
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
17+
help: consider relaxing the implicit `'static` requirement on the impl
18+
|
19+
LL | impl BaseSetter for dyn FooSetter + '_ {
20+
| ++++
21+
22+
error: aborting due to 1 previous error
23+
24+
For more information about this error, try `rustc --explain E0521`.

0 commit comments

Comments
 (0)