Skip to content

Commit 5074501

Browse files
committed
Report a specialized error when a 'static obligation comes from an impl dyn Trait
```text error: lifetime may not live long enough --> $DIR/static-impl-obligation.rs:8:27 | LL | fn bar<'a>(x: &'a &'a u32) { | -- lifetime `'a` defined here LL | let y: &dyn Foo = x; | ^ cast requires that `'a` must outlive `'static` LL | y.hello(); | --------- calling this method introduces a `'static` lifetime requirement | help: relax the implicit `'static` bound on the impl | LL | impl dyn Foo + '_ { | ++++ ``` ```text error: lifetime may not live long enough --> $DIR/static-impl-obligation.rs:173:27 | LL | fn bar<'a>(x: &'a &'a u32) { | -- lifetime `'a` defined here LL | let y: &dyn Foo = x; | ^ cast requires that `'a` must outlive `'static` LL | y.hello(); | --------- calling this method introduces a `'static` lifetime requirement | note: the `impl` on `(dyn p::Foo + 'static)` has `'static` lifetime requirements --> $DIR/static-impl-obligation.rs:169:20 | LL | impl dyn Foo + 'static where Self: 'static { | ^^^^^^^ ^^^^^^^ LL | fn hello(&self) where Self: 'static {} | ^^^^^^^ ```
1 parent 8a49772 commit 5074501

File tree

11 files changed

+834
-55
lines changed

11 files changed

+834
-55
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3553,6 +3553,7 @@ dependencies = [
35533553
"either",
35543554
"itertools",
35553555
"polonius-engine",
3556+
"rustc_ast",
35563557
"rustc_data_structures",
35573558
"rustc_errors",
35583559
"rustc_fluent_macro",

compiler/rustc_borrowck/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
either = "1.5.0"
99
itertools = "0.11"
1010
polonius-engine = "0.13.0"
11+
rustc_ast = { path = "../rustc_ast" }
1112
rustc_data_structures = { path = "../rustc_data_structures" }
1213
rustc_errors = { path = "../rustc_errors" }
1314
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+262-44
Large diffs are not rendered by default.

compiler/rustc_borrowck/src/region_infer/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20512051
CRATE_DEF_ID.to_def_id(),
20522052
predicate_span,
20532053
))
2054+
} else if let ConstraintCategory::CallArgument(Some(fn_def)) = constraint.category {
2055+
Some(ObligationCauseCode::MethodCallConstraint(fn_def, constraint.span))
20542056
} else {
20552057
None
20562058
}

compiler/rustc_middle/src/traits/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,9 @@ pub enum ObligationCauseCode<'tcx> {
451451

452452
/// Obligations emitted during the normalization of a weak type alias.
453453
TypeAlias(InternedObligationCauseCode<'tcx>, Span, DefId),
454+
455+
/// During borrowck we've found a method call that could have introduced a lifetime requirement.
456+
MethodCallConstraint(Ty<'tcx>, Span),
454457
}
455458

456459
/// Whether a value can be extracted into a const.

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2683,6 +2683,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26832683
| ObligationCauseCode::MethodReceiver
26842684
| ObligationCauseCode::ReturnNoExpression
26852685
| ObligationCauseCode::UnifyReceiver(..)
2686+
| ObligationCauseCode::MethodCallConstraint(..)
26862687
| ObligationCauseCode::MiscObligation
26872688
| ObligationCauseCode::WellFormed(..)
26882689
| ObligationCauseCode::MatchImpl(..)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
mod a {
2+
trait Foo {}
3+
impl<'a> Foo for &'a u32 {}
4+
impl dyn Foo { //~ HELP consider relaxing the implicit `'static` requirement
5+
fn hello(&self) {}
6+
}
7+
fn bar<'a>(x: &'a &'a u32) {
8+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
9+
y.hello();
10+
}
11+
}
12+
mod b {
13+
trait Foo {}
14+
impl<'a> Foo for &'a u32 {}
15+
impl dyn Foo {
16+
fn hello(&'static self) {}
17+
}
18+
fn bar<'a>(x: &'a &'a u32) {
19+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
20+
y.hello();
21+
}
22+
}
23+
mod c {
24+
trait Foo {}
25+
impl<'a> Foo for &'a u32 {}
26+
impl dyn Foo {
27+
fn hello(&'static self) where Self: 'static {}
28+
}
29+
fn bar<'a>(x: &'a &'a u32) {
30+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
31+
y.hello();
32+
}
33+
}
34+
mod d {
35+
trait Foo {}
36+
impl<'a> Foo for &'a u32 {}
37+
impl dyn Foo {
38+
fn hello(&self) where Self: 'static {}
39+
}
40+
fn bar<'a>(x: &'a &'a u32) {
41+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
42+
y.hello();
43+
}
44+
}
45+
mod e {
46+
trait Foo {}
47+
impl<'a> Foo for &'a u32 {}
48+
impl dyn Foo + 'static { //~ HELP consider replacing this `'static` requirement
49+
fn hello(&self) {}
50+
}
51+
fn bar<'a>(x: &'a &'a u32) {
52+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
53+
y.hello();
54+
}
55+
}
56+
mod f {
57+
trait Foo {}
58+
impl<'a> Foo for &'a u32 {}
59+
impl dyn Foo + 'static {
60+
fn hello(&'static self) {}
61+
}
62+
fn bar<'a>(x: &'a &'a u32) {
63+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
64+
y.hello();
65+
}
66+
}
67+
mod g {
68+
trait Foo {}
69+
impl<'a> Foo for &'a u32 {}
70+
impl dyn Foo + 'static {
71+
fn hello(&'static self) where Self: 'static {}
72+
}
73+
fn bar<'a>(x: &'a &'a u32) {
74+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
75+
y.hello();
76+
}
77+
}
78+
mod h {
79+
trait Foo {}
80+
impl<'a> Foo for &'a u32 {}
81+
impl dyn Foo + 'static {
82+
fn hello(&self) where Self: 'static {}
83+
}
84+
fn bar<'a>(x: &'a &'a u32) {
85+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
86+
y.hello();
87+
}
88+
}
89+
mod i {
90+
trait Foo {}
91+
impl<'a> Foo for &'a u32 {}
92+
impl dyn Foo where Self: 'static {
93+
fn hello(&self) {}
94+
}
95+
fn bar<'a>(x: &'a &'a u32) {
96+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
97+
y.hello();
98+
}
99+
}
100+
mod j {
101+
trait Foo {}
102+
impl<'a> Foo for &'a u32 {}
103+
impl dyn Foo where Self: 'static {
104+
fn hello(&'static self) {}
105+
}
106+
fn bar<'a>(x: &'a &'a u32) {
107+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
108+
y.hello();
109+
}
110+
}
111+
mod k {
112+
trait Foo {}
113+
impl<'a> Foo for &'a u32 {}
114+
impl dyn Foo where Self: 'static {
115+
fn hello(&'static self) where Self: 'static {}
116+
}
117+
fn bar<'a>(x: &'a &'a u32) {
118+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
119+
y.hello();
120+
}
121+
}
122+
mod l {
123+
trait Foo {}
124+
impl<'a> Foo for &'a u32 {}
125+
impl dyn Foo where Self: 'static {
126+
fn hello(&self) where Self: 'static {}
127+
}
128+
fn bar<'a>(x: &'a &'a u32) {
129+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
130+
y.hello();
131+
}
132+
}
133+
mod m {
134+
trait Foo {}
135+
impl<'a> Foo for &'a u32 {}
136+
impl dyn Foo + 'static where Self: 'static {
137+
fn hello(&self) {}
138+
}
139+
fn bar<'a>(x: &'a &'a u32) {
140+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
141+
y.hello();
142+
}
143+
}
144+
mod n {
145+
trait Foo {}
146+
impl<'a> Foo for &'a u32 {}
147+
impl dyn Foo + 'static where Self: 'static {
148+
fn hello(&'static self) {}
149+
}
150+
fn bar<'a>(x: &'a &'a u32) {
151+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
152+
y.hello();
153+
}
154+
}
155+
mod o {
156+
trait Foo {}
157+
impl<'a> Foo for &'a u32 {}
158+
impl dyn Foo + 'static where Self: 'static {
159+
fn hello(&'static self) where Self: 'static {}
160+
}
161+
fn bar<'a>(x: &'a &'a u32) {
162+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
163+
y.hello();
164+
}
165+
}
166+
mod p {
167+
trait Foo {}
168+
impl<'a> Foo for &'a u32 {}
169+
impl dyn Foo + 'static where Self: 'static {
170+
fn hello(&self) where Self: 'static {}
171+
}
172+
fn bar<'a>(x: &'a &'a u32) {
173+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
174+
y.hello();
175+
}
176+
}
177+
mod q {
178+
struct Foo {}
179+
impl Foo {
180+
fn hello(&'static self) {}
181+
}
182+
fn bar<'a>(x: &'a &'a Foo) {
183+
x.hello(); //~ ERROR borrowed data escapes outside of function
184+
}
185+
}
186+
mod r {
187+
struct Foo {}
188+
impl Foo {
189+
fn hello(&'static self) where Self: 'static {}
190+
}
191+
fn bar<'a>(x: &'a &'a Foo) {
192+
x.hello(); //~ ERROR borrowed data escapes outside of function
193+
}
194+
}
195+
mod s {
196+
trait Foo {}
197+
impl<'a> Foo for &'a u32 {}
198+
199+
trait Trait { fn hello(&self) {} }
200+
201+
impl Trait for dyn Foo { //~ HELP consider relaxing the implicit `'static` requirement on the impl
202+
fn hello(&self) {}
203+
204+
}
205+
fn convert<'a>(x: &'a &'a u32) {
206+
let y: &dyn Foo = x; //~ ERROR lifetime may not live long enough
207+
y.hello();
208+
}
209+
}
210+
fn main() {}

0 commit comments

Comments
 (0)