mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
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> {
| +++++++++
```
This commit is contained in:
@@ -3568,8 +3568,7 @@ fn add_missing_lifetime_specifiers_label(
|
||||
&& (lt.kind == MissingLifetimeKind::Ampersand
|
||||
|| lt.kind == MissingLifetimeKind::Underscore)
|
||||
{
|
||||
let pre = if lt.kind == MissingLifetimeKind::Ampersand
|
||||
&& let Some((kind, _span)) = self.diag_metadata.current_function
|
||||
let pre = if let Some((kind, _span)) = self.diag_metadata.current_function
|
||||
&& let FnKind::Fn(_, _, ast::Fn { sig, .. }) = kind
|
||||
&& !sig.decl.inputs.is_empty()
|
||||
&& let sugg = sig
|
||||
@@ -3599,10 +3598,12 @@ fn add_missing_lifetime_specifiers_label(
|
||||
} else {
|
||||
("one of the", "s")
|
||||
};
|
||||
let dotdotdot =
|
||||
if lt.kind == MissingLifetimeKind::Ampersand { "..." } else { "" };
|
||||
err.multipart_suggestion_verbose(
|
||||
format!(
|
||||
"instead, you are more likely to want to change {the} \
|
||||
argument{s} to be borrowed...",
|
||||
argument{s} to be borrowed{dotdotdot}",
|
||||
),
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
||||
@@ -864,6 +864,42 @@ pub fn construct_generic_bound_failure(
|
||||
}
|
||||
}
|
||||
|
||||
if sub.kind() == ty::ReStatic
|
||||
&& let Some(node) = self.tcx.hir_get_if_local(generic_param_scope.into())
|
||||
&& let hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn { sig, body, has_body: true, .. },
|
||||
..
|
||||
})
|
||||
| hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body)),
|
||||
..
|
||||
})
|
||||
| hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(sig, body), ..
|
||||
}) = node
|
||||
&& let hir::Node::Expr(expr) = self.tcx.hir_node(body.hir_id)
|
||||
&& let hir::ExprKind::Block(block, _) = expr.kind
|
||||
&& let Some(tail) = block.expr
|
||||
&& tail.span == span
|
||||
&& let hir::FnRetTy::Return(ty) = sig.decl.output
|
||||
&& let hir::TyKind::Path(path) = ty.kind
|
||||
&& let hir::QPath::Resolved(None, path) = path
|
||||
&& let hir::def::Res::Def(_, def_id) = path.res
|
||||
&& Some(def_id) == self.tcx.lang_items().owned_box()
|
||||
&& let [segment] = path.segments
|
||||
&& let Some(args) = segment.args
|
||||
&& let [hir::GenericArg::Type(ty)] = args.args
|
||||
&& let hir::TyKind::TraitObject(_, tagged_ref) = ty.kind
|
||||
&& let hir::LifetimeKind::ImplicitObjectLifetimeDefault = tagged_ref.pointer().kind
|
||||
{
|
||||
// Explicitly look for `-> Box<dyn Trait>` to point at it as the *likely* source of
|
||||
// the `'static` lifetime requirement.
|
||||
err.span_label(
|
||||
ty.span,
|
||||
format!("this `dyn Trait` has an implicit `'static` lifetime bound"),
|
||||
);
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
error[E0310]: the associated type `impl Fn()` may not live long enough
|
||||
--> $DIR/missing-static-bound-from-impl.rs:11:9
|
||||
|
|
||||
LL | fn f(&self) -> Box<dyn Fn()> {
|
||||
| -------- this `dyn Trait` has an implicit `'static` lifetime bound
|
||||
LL | Box::new(<T as Original>::f())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// #41966
|
||||
trait Foo {}
|
||||
|
||||
struct Bar<R>(R);
|
||||
|
||||
impl<R> Foo for Bar<R> {
|
||||
}
|
||||
|
||||
fn bb<R>(r: R) -> Box<dyn Foo> {
|
||||
Box::new(Bar(r)) //~ ERROR the parameter type `R` may not live long enough
|
||||
}
|
||||
|
||||
fn cc<R>(r: R) -> Box<dyn Foo + '_> { //~ ERROR missing lifetime specifier
|
||||
Box::new(Bar(r))
|
||||
}
|
||||
|
||||
// #54753
|
||||
pub struct Qux<T>(T);
|
||||
|
||||
pub struct Bazzzz<T>(T);
|
||||
|
||||
pub trait Baz {}
|
||||
impl<T> Baz for Bazzzz<T> {}
|
||||
|
||||
impl<T> Qux<T> {
|
||||
fn baz(self) -> Box<dyn Baz> {
|
||||
Box::new(Bazzzz(self.0)) //~ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = 10;
|
||||
let _b = bb(&a);
|
||||
let _c = cc(&a);
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:13:33
|
||||
|
|
||||
LL | fn cc<R>(r: R) -> Box<dyn Foo + '_> {
|
||||
| ^^ expected named lifetime parameter
|
||||
|
|
||||
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
|
||||
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
|
||||
|
|
||||
LL - fn cc<R>(r: R) -> Box<dyn Foo + '_> {
|
||||
LL + fn cc<R>(r: R) -> Box<dyn Foo + 'static> {
|
||||
|
|
||||
help: instead, you are more likely to want to change the argument to be borrowed
|
||||
|
|
||||
LL | fn cc<R>(r: &R) -> Box<dyn Foo + '_> {
|
||||
| +
|
||||
|
||||
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> {
|
||||
| +++++++++
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/implicit-static-lifetime-in-dyn-trait-return-type.rs:27:9
|
||||
|
|
||||
LL | fn baz(self) -> Box<dyn Baz> {
|
||||
| ------- this `dyn Trait` has an implicit `'static` lifetime bound
|
||||
LL | Box::new(Bazzzz(self.0))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| the parameter type `T` must be valid for the static lifetime...
|
||||
| ...so that the type `T` will meet its required lifetime bounds
|
||||
|
|
||||
help: consider adding an explicit lifetime bound
|
||||
|
|
||||
LL | impl<T: 'static> Qux<T> {
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0106, E0310.
|
||||
For more information about an error, try `rustc --explain E0106`.
|
||||
@@ -38,6 +38,8 @@ LL | fn without_sized<T: Fn() -> &'static (dyn std::fmt::Debug) + ?Sized>() {}
|
||||
error[E0310]: the parameter type `impl FnOnce(T) -> dyn Future<Output = ()>` may not live long enough
|
||||
--> $DIR/wrap-dyn-in-suggestion-issue-120223.rs:6:5
|
||||
|
|
||||
LL | ) -> Box<dyn FnOnce(T) -> dyn Future<Output = ()>> {
|
||||
| ---------------------------------------- this `dyn Trait` has an implicit `'static` lifetime bound
|
||||
LL | Box::new(executor)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
|
||||
Reference in New Issue
Block a user