Skip to content

Commit b27b9fd

Browse files
committed
Account for more cases
1 parent 6d8c08a commit b27b9fd

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
@@ -499,7 +499,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
499499
}
500500
};
501501

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

504508
match variance_info {
505509
ty::VarianceDiagInfo::None => {}
@@ -621,14 +625,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
621625
fn explain_impl_static_obligation(
622626
&self,
623627
diag: &mut Diag<'_>,
624-
code: &ObligationCauseCode<'tcx>,
628+
ty: Ty<'tcx>,
629+
call_span: Span,
625630
outlived_fr: RegionVid,
626631
) {
627632
let tcx = self.infcx.tcx;
628-
debug!(?code);
629-
let ObligationCauseCode::MethodCallConstraint(ty, call_span) = code else {
630-
return;
631-
};
632633
let ty::FnDef(def_id, args) = ty.kind() else {
633634
return;
634635
};
@@ -722,7 +723,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
722723
if let ty::Ref(region, _, _) = self
723724
.infcx
724725
.instantiate_binder_with_fresh_vars(
725-
*call_span,
726+
call_span,
726727
BoundRegionConversionTime::FnCall,
727728
tcx.fn_sig(def_id).instantiate_identity().inputs().map_bound(|inputs| inputs[0]),
728729
)
@@ -804,10 +805,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
804805
let span: MultiSpan = predicates.into();
805806
diag.span_note(span, format!("the `impl` on `{ty}` has {a_static_lt}"));
806807
}
807-
if new_primary_span && diag.span.primary_span() != Some(*call_span) {
808-
diag.replace_span_with(*call_span, false);
808+
if new_primary_span && diag.span.primary_span() != Some(call_span) {
809+
diag.replace_span_with(call_span, false);
809810
diag.span_label(
810-
*call_span,
811+
call_span,
811812
"calling this method introduces a `'static` lifetime requirement",
812813
);
813814
}
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)