Skip to content

Commit eb415e9

Browse files
authored
Rollup merge of #148506 - estebank:issue-41966, r=davidtwco
Special case detecting `'static` lifetime requirement coming from `-> Box<dyn Trait>` ``` error[E0310]: the parameter type `R` may not live long enough --> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:10:5 | LL | fn bb<R>(r: R) -> Box<dyn Foo> { | ------- this `dyn Trait` has an implicit `'static` lifetime bound LL | Box::new(Bar(r)) | ^^^^^^^^^^^^^^^^ | | | the parameter type `R` must be valid for the static lifetime... | ...so that the type `R` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | LL | fn bb<R: 'static>(r: R) -> Box<dyn Foo> { | +++++++++ ``` Partly address #41966 and #54753. #103849, which shows a case where there's an intermediary binding, is not addressed at all, as aren't cases *other* than `Box<dyn Trait>` return type.
2 parents 01ae075 + a49d4d7 commit eb415e9

File tree

6 files changed

+132
-3
lines changed

6 files changed

+132
-3
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3592,8 +3592,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
35923592
&& (lt.kind == MissingLifetimeKind::Ampersand
35933593
|| lt.kind == MissingLifetimeKind::Underscore)
35943594
{
3595-
let pre = if lt.kind == MissingLifetimeKind::Ampersand
3596-
&& let Some((kind, _span)) = self.diag_metadata.current_function
3595+
let pre = if let Some((kind, _span)) = self.diag_metadata.current_function
35973596
&& let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
35983597
&& !sig.decl.inputs.is_empty()
35993598
&& let sugg = sig
@@ -3623,10 +3622,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
36233622
} else {
36243623
("one of the", "s")
36253624
};
3625+
let dotdotdot =
3626+
if lt.kind == MissingLifetimeKind::Ampersand { "..." } else { "" };
36263627
err.multipart_suggestion_verbose(
36273628
format!(
36283629
"instead, you are more likely to want to change {the} \
3629-
argument{s} to be borrowed...",
3630+
argument{s} to be borrowed{dotdotdot}",
36303631
),
36313632
sugg,
36323633
Applicability::MaybeIncorrect,

compiler/rustc_trait_selection/src/error_reporting/infer/region.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
864864
}
865865
}
866866

867+
if sub.kind() == ty::ReStatic
868+
&& let Some(node) = self.tcx.hir_get_if_local(generic_param_scope.into())
869+
&& let hir::Node::Item(hir::Item {
870+
kind: hir::ItemKind::Fn { sig, body, has_body: true, .. },
871+
..
872+
})
873+
| hir::Node::TraitItem(hir::TraitItem {
874+
kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)),
875+
..
876+
})
877+
| hir::Node::ImplItem(hir::ImplItem {
878+
kind: hir::ImplItemKind::Fn(sig, body), ..
879+
}) = node
880+
&& let hir::Node::Expr(expr) = self.tcx.hir_node(body.hir_id)
881+
&& let hir::ExprKind::Block(block, _) = expr.kind
882+
&& let Some(tail) = block.expr
883+
&& tail.span == span
884+
&& let hir::FnRetTy::Return(ty) = sig.decl.output
885+
&& let hir::TyKind::Path(path) = ty.kind
886+
&& let hir::QPath::Resolved(None, path) = path
887+
&& let hir::def::Res::Def(_, def_id) = path.res
888+
&& Some(def_id) == self.tcx.lang_items().owned_box()
889+
&& let [segment] = path.segments
890+
&& let Some(args) = segment.args
891+
&& let [hir::GenericArg::Type(ty)] = args.args
892+
&& let hir::TyKind::TraitObject(_, tagged_ref) = ty.kind
893+
&& let hir::LifetimeKind::ImplicitObjectLifetimeDefault = tagged_ref.pointer().kind
894+
{
895+
// Explicitly look for `-> Box<dyn Trait>` to point at it as the *likely* source of
896+
// the `'static` lifetime requirement.
897+
err.span_label(
898+
ty.span,
899+
format!("this `dyn Trait` has an implicit `'static` lifetime bound"),
900+
);
901+
}
902+
867903
err
868904
}
869905

tests/ui/impl-trait/in-trait/missing-static-bound-from-impl.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error[E0310]: the associated type `impl Fn()` may not live long enough
22
--> $DIR/missing-static-bound-from-impl.rs:11:9
33
|
4+
LL | fn f(&self) -> Box<dyn Fn()> {
5+
| -------- this `dyn Trait` has an implicit `'static` lifetime bound
46
LL | Box::new(<T as Original>::f())
57
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68
| |
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// #41966
2+
trait Foo {}
3+
4+
struct Bar<R>(R);
5+
6+
impl<R> Foo for Bar<R> {
7+
}
8+
9+
fn bb<R>(r: R) -> Box<dyn Foo> {
10+
Box::new(Bar(r)) //~ ERROR the parameter type `R` may not live long enough
11+
}
12+
13+
fn cc<R>(r: R) -> Box<dyn Foo + '_> { //~ ERROR missing lifetime specifier
14+
Box::new(Bar(r))
15+
}
16+
17+
// #54753
18+
pub struct Qux<T>(T);
19+
20+
pub struct Bazzzz<T>(T);
21+
22+
pub trait Baz {}
23+
impl<T> Baz for Bazzzz<T> {}
24+
25+
impl<T> Qux<T> {
26+
fn baz(self) -> Box<dyn Baz> {
27+
Box::new(Bazzzz(self.0)) //~ ERROR the parameter type `T` may not live long enough
28+
}
29+
}
30+
31+
fn main() {
32+
let a = 10;
33+
let _b = bb(&a);
34+
let _c = cc(&a);
35+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:13:33
3+
|
4+
LL | fn cc<R>(r: R) -> Box<dyn Foo + '_> {
5+
| ^^ expected named lifetime parameter
6+
|
7+
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
8+
help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values
9+
|
10+
LL - fn cc<R>(r: R) -> Box<dyn Foo + '_> {
11+
LL + fn cc<R>(r: R) -> Box<dyn Foo + 'static> {
12+
|
13+
help: instead, you are more likely to want to change the argument to be borrowed
14+
|
15+
LL | fn cc<R>(r: &R) -> Box<dyn Foo + '_> {
16+
| +
17+
18+
error[E0310]: the parameter type `R` may not live long enough
19+
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:10:5
20+
|
21+
LL | fn bb<R>(r: R) -> Box<dyn Foo> {
22+
| ------- this `dyn Trait` has an implicit `'static` lifetime bound
23+
LL | Box::new(Bar(r))
24+
| ^^^^^^^^^^^^^^^^
25+
| |
26+
| the parameter type `R` must be valid for the static lifetime...
27+
| ...so that the type `R` will meet its required lifetime bounds
28+
|
29+
help: consider adding an explicit lifetime bound
30+
|
31+
LL | fn bb<R: 'static>(r: R) -> Box<dyn Foo> {
32+
| +++++++++
33+
34+
error[E0310]: the parameter type `T` may not live long enough
35+
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:27:9
36+
|
37+
LL | fn baz(self) -> Box<dyn Baz> {
38+
| ------- this `dyn Trait` has an implicit `'static` lifetime bound
39+
LL | Box::new(Bazzzz(self.0))
40+
| ^^^^^^^^^^^^^^^^^^^^^^^^
41+
| |
42+
| the parameter type `T` must be valid for the static lifetime...
43+
| ...so that the type `T` will meet its required lifetime bounds
44+
|
45+
help: consider adding an explicit lifetime bound
46+
|
47+
LL | impl<T: 'static> Qux<T> {
48+
| +++++++++
49+
50+
error: aborting due to 3 previous errors
51+
52+
Some errors have detailed explanations: E0106, E0310.
53+
For more information about an error, try `rustc --explain E0106`.

tests/ui/suggestions/wrap-dyn-in-suggestion-issue-120223.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ LL | fn without_sized<T: Fn() -> &'static (dyn std::fmt::Debug) + ?Sized>() {}
3838
error[E0310]: the parameter type `impl FnOnce(T) -> dyn Future<Output = ()>` may not live long enough
3939
--> $DIR/wrap-dyn-in-suggestion-issue-120223.rs:6:5
4040
|
41+
LL | ) -> Box<dyn FnOnce(T) -> dyn Future<Output = ()>> {
42+
| ---------------------------------------- this `dyn Trait` has an implicit `'static` lifetime bound
4143
LL | Box::new(executor)
4244
| ^^^^^^^^^^^^^^^^^^
4345
| |

0 commit comments

Comments
 (0)