Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3568,8 +3568,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
&& (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
Expand Down Expand Up @@ -3599,10 +3598,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
} 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,
Expand Down
36 changes: 36 additions & 0 deletions compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
}

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
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
| ^^^^^^^^^^^^^^^^^^
| |
Expand Down
Loading