Skip to content

Commit 20e6a6c

Browse files
committed
Account for more cases
1 parent 0211233 commit 20e6a6c

File tree

3 files changed

+82
-10
lines changed

3 files changed

+82
-10
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
496496
}
497497
};
498498

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

501505
match variance_info {
502506
ty::VarianceDiagInfo::None => {}
@@ -618,14 +622,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
618622
fn explain_impl_static_obligation(
619623
&self,
620624
diag: &mut DiagnosticBuilder<'_>,
621-
code: &ObligationCauseCode<'tcx>,
625+
ty: Ty<'tcx>,
626+
call_span: Span,
622627
outlived_fr: RegionVid,
623628
) {
624629
let tcx = self.infcx.tcx;
625-
debug!(?code);
626-
let ObligationCauseCode::MethodCallConstraint(ty, call_span) = code else {
627-
return;
628-
};
629630
let ty::FnDef(def_id, args) = ty.kind() else {
630631
return;
631632
};
@@ -719,7 +720,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
719720
if let ty::Ref(region, _, _) = self
720721
.infcx
721722
.instantiate_binder_with_fresh_vars(
722-
*call_span,
723+
call_span,
723724
BoundRegionConversionTime::FnCall,
724725
tcx.fn_sig(def_id).instantiate_identity().inputs().map_bound(|inputs| inputs[0]),
725726
)
@@ -801,10 +802,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
801802
let span: MultiSpan = predicates.into();
802803
diag.span_note(span, format!("the `impl` on `{ty}` has {a_static_lt}"));
803804
}
804-
if new_primary_span && diag.span.primary_span() != Some(*call_span) {
805-
diag.replace_span_with(*call_span, false);
805+
if new_primary_span && diag.span.primary_span() != Some(call_span) {
806+
diag.replace_span_with(call_span, false);
806807
diag.span_label(
807-
*call_span,
808+
call_span,
808809
"calling this method introduces a `'static` lifetime requirement",
809810
);
810811
}
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+
}
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)