Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account for missing lifetime in opaque and trait object return types #72543

Merged
merged 10 commits into from
May 31, 2020
170 changes: 124 additions & 46 deletions src/librustc_infer/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ use rustc_errors::{pluralize, struct_span_err};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::Node;
use rustc_hir::{Item, ItemKind, Node};
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::{
self,
@@ -1682,49 +1682,92 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
bound_kind: GenericKind<'tcx>,
sub: Region<'tcx>,
) -> DiagnosticBuilder<'a> {
let hir = &self.tcx.hir();
// Attempt to obtain the span of the parameter so we can
// suggest adding an explicit lifetime bound to it.
let type_param_span = match (self.in_progress_tables, bound_kind) {
(Some(ref table), GenericKind::Param(ref param)) => {
let table_owner = table.borrow().hir_owner;
table_owner.and_then(|table_owner| {
let generics = self.tcx.generics_of(table_owner.to_def_id());
// Account for the case where `param` corresponds to `Self`,
// which doesn't have the expected type argument.
if !(generics.has_self && param.index == 0) {
let type_param = generics.type_param(param, self.tcx);
let hir = &self.tcx.hir();
type_param.def_id.as_local().map(|def_id| {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
// instead we suggest `T: 'a + 'b` in that case.
let id = hir.as_local_hir_id(def_id);
let mut has_bounds = false;
if let Node::GenericParam(param) = hir.get(id) {
has_bounds = !param.bounds.is_empty();
}
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers
// `T:` when appropriate
let is_impl_trait = bound_kind.to_string().starts_with("impl ");
let sp = if has_bounds && !is_impl_trait {
sp.to(self
.tcx
.sess
.source_map()
.next_point(self.tcx.sess.source_map().next_point(sp)))
} else {
sp
};
(sp, has_bounds, is_impl_trait)
})
let generics =
self.in_progress_tables.and_then(|table| table.borrow().hir_owner).map(|table_owner| {
let hir_id = hir.as_local_hir_id(table_owner);
let parent_id = hir.get_parent_item(hir_id);
(
// Parent item could be a `mod`, so we check the HIR before calling:
if let Some(Node::Item(Item {
kind: ItemKind::Trait(..) | ItemKind::Impl { .. },
..
})) = hir.find(parent_id)
{
Some(self.tcx.generics_of(hir.local_def_id(parent_id).to_def_id()))
} else {
None
}
})
},
self.tcx.generics_of(table_owner.to_def_id()),
)
});
let type_param_span = match (generics, bound_kind) {
(Some((_, ref generics)), GenericKind::Param(ref param)) => {
// Account for the case where `param` corresponds to `Self`,
// which doesn't have the expected type argument.
if !(generics.has_self && param.index == 0) {
let type_param = generics.type_param(param, self.tcx);
type_param.def_id.as_local().map(|def_id| {
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: 'a'b`,
// instead we suggest `T: 'a + 'b` in that case.
let id = hir.as_local_hir_id(def_id);
let mut has_bounds = false;
if let Node::GenericParam(param) = hir.get(id) {
has_bounds = !param.bounds.is_empty();
}
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers
// `T:` when appropriate
let is_impl_trait = bound_kind.to_string().starts_with("impl ");
let sp = if has_bounds && !is_impl_trait {
sp.to(self
.tcx
.sess
.source_map()
.next_point(self.tcx.sess.source_map().next_point(sp)))
} else {
sp
};
(sp, has_bounds, is_impl_trait)
})
} else {
None
}
}
_ => None,
};
let new_lt = generics
.as_ref()
.and_then(|(parent_g, g)| {
let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect();
let mut lts_names = g
.params
.iter()
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
.map(|p| p.name.as_str())
.collect::<Vec<_>>();
if let Some(g) = parent_g {
lts_names.extend(
g.params
.iter()
.filter(|p| matches!(p.kind, ty::GenericParamDefKind::Lifetime))
.map(|p| p.name.as_str()),
);
}
let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::<Vec<_>>();
possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str()))
})
.unwrap_or("'lt".to_string());
let add_lt_sugg = generics
.as_ref()
.and_then(|(_, g)| g.params.first())
.and_then(|param| param.def_id.as_local())
.map(|def_id| {
(hir.span(hir.as_local_hir_id(def_id)).shrink_to_lo(), format!("{}, ", new_lt))
});

let labeled_user_string = match bound_kind {
GenericKind::Param(ref p) => format!("the parameter type `{}`", p),
@@ -1781,6 +1824,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}

let new_binding_suggestion =
|err: &mut DiagnosticBuilder<'tcx>,
type_param_span: Option<(Span, bool, bool)>,
bound_kind: GenericKind<'tcx>| {
let msg = "consider introducing an explicit lifetime bound";
if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
let suggestion = if is_impl_trait {
(sp.shrink_to_hi(), format!(" + {}", new_lt))
} else {
let tail = if has_lifetimes { " +" } else { "" };
(sp, format!("{}: {}{}", bound_kind, new_lt, tail))
};
let mut sugg =
vec![suggestion, (span.shrink_to_hi(), format!(" + {}", new_lt))];
if let Some(lt) = add_lt_sugg {
sugg.push(lt);
sugg.rotate_right(1);
}
// `MaybeIncorrect` due to issue #41966.
err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect);
}
};

let mut err = match *sub {
ty::ReEarlyBound(ty::EarlyBoundRegion { name, .. })
| ty::ReFree(ty::FreeRegion { bound_region: ty::BrNamed(_, name), .. }) => {
@@ -1822,17 +1888,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"{} may not live long enough",
labeled_user_string
);
err.help(&format!(
"consider adding an explicit lifetime bound for `{}`",
bound_kind
));
note_and_explain_region(
self.tcx,
&mut err,
&format!("{} must be valid for ", labeled_user_string),
sub,
"...",
);
if let Some(infer::RelateParamBound(_, t)) = origin {
let t = self.resolve_vars_if_possible(&t);
match t.kind {
// We've got:
// fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
// suggest:
// fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
ty::Closure(_, _substs) | ty::Opaque(_, _substs) => {
new_binding_suggestion(&mut err, type_param_span, bound_kind);
}
_ => {
binding_suggestion(&mut err, type_param_span, bound_kind, new_lt);
}
}
}
err
}
};
@@ -1861,14 +1938,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"...",
);

debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);

if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) =
(&sup_origin, &sub_origin)
{
debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
Original file line number Diff line number Diff line change
@@ -121,16 +121,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
(Some(ret_span), _) => (
ty_sub.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes..."
"this parameter and the return type are declared with different lifetimes..."
.to_owned(),
format!("...but data{} is returned here", span_label_var1),
),
(_, Some(ret_span)) => (
ty_sup.span,
ret_span,
"this parameter and the return type are declared \
with different lifetimes..."
"this parameter and the return type are declared with different lifetimes..."
.to_owned(),
format!("...but data{} is returned here", span_label_var1),
),
Original file line number Diff line number Diff line change
@@ -55,9 +55,9 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
diag.emit();
ErrorReported
})
.or_else(|| self.try_report_impl_not_conforming_to_trait())
.or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_static_impl_trait())
.or_else(|| self.try_report_impl_not_conforming_to_trait())
}

pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
Original file line number Diff line number Diff line change
@@ -21,8 +21,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// where the anonymous region appears (there must always be one; we
// only introduced anonymous regions in parameters) as well as a
// version new_ty of its type where the anonymous region is replaced
// with the named one.//scope_def_id
let (named, anon, anon_param_info, region_info) = if self.is_named_region(sub)
// with the named one.
let (named, anon, anon_param_info, region_info) = if sub.has_name()
&& self.tcx().is_suitable_region(sup).is_some()
&& self.find_param_with_region(sup, sub).is_some()
{
@@ -32,7 +32,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
self.find_param_with_region(sup, sub).unwrap(),
self.tcx().is_suitable_region(sup).unwrap(),
)
} else if self.is_named_region(sup)
} else if sup.has_name()
&& self.tcx().is_suitable_region(sub).is_some()
&& self.find_param_with_region(sub, sup).is_some()
{
@@ -74,15 +74,21 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}

if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
if self.is_return_type_anon(scope_def_id, br, fndecl).is_some()
|| self.is_self_anon(is_first, scope_def_id)
{
let is_self_anon = self.is_self_anon(is_first, scope_def_id);
if is_self_anon {
return None;
}

if let FnRetTy::Return(ty) = &fndecl.output {
if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) {
// This is an impl Trait return that evaluates de need of 'static.
// We handle this case better in `static_impl_trait`.
let mut v = ty::TraitObjectVisitor(vec![]);
rustc_hir::intravisit::walk_ty(&mut v, ty);

debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if sub == &ty::ReStatic && (matches!(ty.kind, TyKind::Def(_, _)) || v.0.len() == 1)
{
debug!("try_report_named_anon_conflict: impl Trait + 'static");
// This is an `impl Trait` or `dyn Trait` return that evaluates de need of
// `'static`. We handle this case better in `static_impl_trait`.
return None;
}
}
@@ -114,17 +120,4 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {

Some(diag)
}

// This method returns whether the given Region is Named
pub(super) fn is_named_region(&self, region: ty::Region<'tcx>) -> bool {
match *region {
ty::ReStatic => true,
ty::ReFree(ref free_region) => match free_region.bound_region {
ty::BrNamed(..) => true,
_ => false,
},
ty::ReEarlyBound(ebr) => ebr.has_name(),
_ => false,
}
}
}
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use crate::infer::error_reporting::msg_span_from_free_region;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
use rustc_errors::{Applicability, ErrorReported};
use rustc_middle::ty::{BoundRegion, FreeRegion, RegionKind};
use rustc_middle::ty::RegionKind;

impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// Print the error message for lifetime errors when the return type is a static impl Trait.
@@ -20,48 +20,59 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
) = error.clone()
{
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
let return_ty = self.tcx().return_type_impl_trait(anon_reg_sup.def_id);
if sub_r == &RegionKind::ReStatic && return_ty.is_some() {
let (fn_return_span, is_dyn) =
self.tcx().return_type_impl_or_dyn_trait(anon_reg_sup.def_id)?;
if sub_r == &RegionKind::ReStatic {
let sp = var_origin.span();
let return_sp = sub_origin.span();
let mut err =
self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
err.span_label(
return_sp,
"this return type evaluates to the `'static` lifetime...",
);
err.span_label(sup_origin.span(), "...but this borrow...");
let param_info = self.find_param_with_region(sup_r, sub_r)?;
err.span_label(param_info.param_ty_span, "data with this lifetime...");

let (lifetime, lt_sp_opt) = msg_span_from_free_region(self.tcx(), sup_r);
if let Some(lifetime_sp) = lt_sp_opt {
err.span_note(lifetime_sp, &format!("...can't outlive {}", lifetime));
}

let lifetime_name = match sup_r {
RegionKind::ReFree(FreeRegion {
bound_region: BoundRegion::BrNamed(_, ref name),
..
}) => name.to_string(),
_ => "'_".to_owned(),
};
let fn_return_span = return_ty.unwrap().1;
if let Ok(snippet) =
self.tcx().sess.source_map().span_to_snippet(fn_return_span)
// We try to make the output have fewer overlapping spans if possible.
if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()))
&& sup_origin.span() != return_sp
{
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return_span.desugaring_kind().is_none() {
err.span_suggestion(
fn_return_span,
&format!(
"you can add a bound to the return type to make it last \
less than `'static` and match {}",
lifetime,
),
format!("{} + {}", snippet, lifetime_name),
Applicability::Unspecified,
);
// FIXME: account for `async fn` like in `async-await/issues/issue-62097.rs`

// Customize the spans and labels depending on their relative order so
// that split sentences flow correctly.
if sup_origin.span().shrink_to_hi() <= return_sp.shrink_to_lo() {
err.span_label(sup_origin.span(), "...is captured here...");
err.span_label(return_sp, "...and required to be `'static` by this");
} else {
err.span_label(return_sp, "...is required to be `'static` by this...");
err.span_label(sup_origin.span(), "...and is captured here");
}
} else {
err.span_label(
return_sp,
"...is captured and required to be `'static` here",
);
}

let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r);

let lifetime_name =
if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return_span.desugaring_kind().is_none() {
let msg = format!(
"to permit non-static references in {} `{} Trait` value, you can add \
an explicit bound for {}",
if is_dyn { "a" } else { "an" },
if is_dyn { "dyn" } else { "impl" },
lifetime,
);
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
err.span_suggestion_verbose(
fn_return_span.shrink_to_hi(),
&msg,
format!(" + {}", lifetime_name),
Applicability::MaybeIncorrect,
);
}
err.emit();
return Some(ErrorReported);
59 changes: 32 additions & 27 deletions src/librustc_infer/infer/error_reporting/note.rs
Original file line number Diff line number Diff line change
@@ -10,10 +10,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
err: &mut DiagnosticBuilder<'_>,
origin: &SubregionOrigin<'tcx>,
) {
let mut label_or_note = |span, msg| {
let sub_count = err.children.iter().filter(|d| d.span.is_dummy()).count();
let expanded_sub_count = err.children.iter().filter(|d| !d.span.is_dummy()).count();
let span_is_primary = err.span.primary_spans().iter().all(|&sp| sp == span);
if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
err.span_label(span, msg);
} else if span_is_primary && expanded_sub_count == 0 {
err.note(msg);
} else {
err.span_note(span, msg);
}
};
match *origin {
infer::Subtype(ref trace) => {
if let Some((expected, found)) = self.values_str(&trace.values) {
err.span_note(
label_or_note(
trace.cause.span,
&format!("...so that the {}", trace.cause.as_requirement_str()),
);
@@ -24,27 +36,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// handling of region checking when type errors are present is
// *terrible*.

err.span_note(
label_or_note(
trace.cause.span,
&format!("...so that {}", trace.cause.as_requirement_str()),
);
}
}
infer::Reborrow(span) => {
err.span_note(span, "...so that reference does not outlive borrowed content");
label_or_note(span, "...so that reference does not outlive borrowed content");
}
infer::ReborrowUpvar(span, ref upvar_id) => {
let var_name = self.tcx.hir().name(upvar_id.var_path.hir_id);
err.span_note(span, &format!("...so that closure can access `{}`", var_name));
label_or_note(span, &format!("...so that closure can access `{}`", var_name));
}
infer::RelateObjectBound(span) => {
err.span_note(span, "...so that it can be closed over into an object");
label_or_note(span, "...so that it can be closed over into an object");
}
infer::CallReturn(span) => {
err.span_note(span, "...so that return value is valid for the call");
label_or_note(span, "...so that return value is valid for the call");
}
infer::DataBorrowed(ty, span) => {
err.span_note(
label_or_note(
span,
&format!(
"...so that the type `{}` is not borrowed for too long",
@@ -53,36 +65,33 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
);
}
infer::ReferenceOutlivesReferent(ty, span) => {
err.span_note(
label_or_note(
span,
&format!(
"...so that the reference type `{}` does not outlive the \
data it points at",
"...so that the reference type `{}` does not outlive the data it points at",
self.ty_to_string(ty)
),
);
}
infer::RelateParamBound(span, t) => {
err.span_note(
label_or_note(
span,
&format!(
"...so that the type `{}` will meet its required \
lifetime bounds",
"...so that the type `{}` will meet its required lifetime bounds",
self.ty_to_string(t)
),
);
}
infer::RelateRegionParamBound(span) => {
err.span_note(
label_or_note(
span,
"...so that the declared lifetime parameter bounds are satisfied",
);
}
infer::CompareImplMethodObligation { span, .. } => {
err.span_note(
label_or_note(
span,
"...so that the definition in impl matches the definition from the \
trait",
"...so that the definition in impl matches the definition from the trait",
);
}
}
@@ -113,8 +122,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
span,
E0312,
"lifetime of reference outlives lifetime of \
borrowed content..."
"lifetime of reference outlives lifetime of borrowed content..."
);
note_and_explain_region(
self.tcx,
@@ -138,8 +146,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
span,
E0313,
"lifetime of borrowed pointer outlives lifetime \
of captured variable `{}`...",
"lifetime of borrowed pointer outlives lifetime of captured variable `{}`...",
var_name
);
note_and_explain_region(
@@ -163,8 +170,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
span,
E0476,
"lifetime of the source pointer does not outlive \
lifetime bound of the object type"
"lifetime of the source pointer does not outlive lifetime bound of the \
object type"
);
note_and_explain_region(self.tcx, &mut err, "object type is valid for ", sub, "");
note_and_explain_region(
@@ -181,8 +188,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
span,
E0477,
"the type `{}` does not fulfill the required \
lifetime",
"the type `{}` does not fulfill the required lifetime",
self.ty_to_string(ty)
);
match *sub {
@@ -217,8 +223,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
self.tcx.sess,
span,
E0482,
"lifetime of return value does not outlive the \
function call"
"lifetime of return value does not outlive the function call"
);
note_and_explain_region(
self.tcx,
101 changes: 74 additions & 27 deletions src/librustc_middle/ty/context.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@
//! Type context book-keeping.
use crate::arena::Arena;
use crate::dep_graph::DepGraph;
use crate::dep_graph::{self, DepConstructor};
use crate::dep_graph::{self, DepConstructor, DepGraph};
use crate::hir::exports::Export;
use crate::ich::{NodeIdHashingMode, StableHashingContext};
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::LintDiagnosticBuilder;
use crate::lint::{struct_lint_level, LintSource};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintSource};
use crate::middle;
use crate::middle::cstore::CrateStoreDyn;
use crate::middle::cstore::EncodedMetadata;
use crate::middle::cstore::{CrateStoreDyn, EncodedMetadata};
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::interpret::{Allocation, ConstValue, Scalar};
use crate::mir::{interpret, Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::traits;
use crate::ty::query;
use crate::ty::steal::Steal;
use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
use crate::ty::subst::{GenericArgKind, UserSubsts};
use crate::ty::CanonicalPolyFnSig;
use crate::ty::GenericParamDefKind;
use crate::ty::RegionKind;
use crate::ty::ReprOptions;
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
use crate::ty::TyKind::*;
use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
use crate::ty::{AdtDef, AdtKind, Const, Region};
use crate::ty::{BindingMode, BoundVar};
use crate::ty::{ConstVid, FloatVar, FloatVid, IntVar, IntVid, TyVar, TyVid};
use crate::ty::{ExistentialPredicate, Predicate, PredicateKind};
use crate::ty::{InferConst, ParamConst};
use crate::ty::{InferTy, ParamTy, PolyFnSig, ProjectionTy};
use crate::ty::{List, TyKind, TyS};
use crate::ty::{
self, query, AdtDef, AdtKind, BindingMode, BoundVar, CanonicalPolyFnSig, Const, ConstVid,
DefIdTree, ExistentialPredicate, FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy,
IntVar, IntVid, List, ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, ProjectionTy,
Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut,
};
use rustc_ast::ast;
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_attr as attr;
@@ -48,10 +37,8 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::{DefPathHash, Definitions};
use rustc_hir::lang_items;
use rustc_hir::lang_items::PanicLocationLangItem;
use rustc_hir::{HirId, Node, TraitCandidate};
use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet};
use rustc_hir::lang_items::{self, PanicLocationLangItem};
use rustc_hir::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate};
use rustc_index::vec::{Idx, IndexVec};
use rustc_macros::HashStable;
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
@@ -1396,6 +1383,66 @@ impl<'tcx> TyCtxt<'tcx> {
})
}

pub fn return_type_impl_or_dyn_trait(&self, scope_def_id: DefId) -> Option<(Span, bool)> {
let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
let hir_output = match self.hir().get(hir_id) {
Node::Item(hir::Item {
kind:
ItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
..,
),
..
})
| Node::ImplItem(hir::ImplItem {
kind:
hir::ImplItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
_,
),
..
})
| Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig {
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
..
},
_,
),
..
}) => ty,
_ => return None,
};

let ret_ty = self.type_of(scope_def_id);
match ret_ty.kind {
ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(*self);
let output = self.erase_late_bound_regions(&sig.output());
if output.is_impl_trait() {
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
Some((fn_decl.output.span(), false))
} else {
let mut v = TraitObjectVisitor(vec![]);
rustc_hir::intravisit::walk_ty(&mut v, hir_output);
if v.0.len() == 1 {
return Some((v.0[0], true));
}
None
}
}
_ => None,
}
}

pub fn return_type_impl_trait(&self, scope_def_id: DefId) -> Option<(Ty<'tcx>, Span)> {
// HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
let hir_id = self.hir().as_local_hir_id(scope_def_id.expect_local());
19 changes: 19 additions & 0 deletions src/librustc_middle/ty/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -249,3 +249,22 @@ pub fn suggest_constraining_type_param(
true
}
}

pub struct TraitObjectVisitor(pub Vec<rustc_span::Span>);
impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor {
type Map = rustc_hir::intravisit::ErasedMap<'v>;

fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
hir::intravisit::NestedVisitorMap::None
}

fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
if let hir::TyKind::TraitObject(
_,
hir::Lifetime { name: hir::LifetimeName::ImplicitObjectLifetimeDefault, .. },
) = ty.kind
{
self.0.push(ty.span);
}
}
}
13 changes: 5 additions & 8 deletions src/test/ui/async-await/issues/issue-62097.stderr
Original file line number Diff line number Diff line change
@@ -2,15 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/issue-62097.rs:12:31
|
LL | pub async fn run_dummy_fn(&self) {
| ^^^^^ ...but this borrow...
| ^^^^^
| |
| data with this lifetime...
| ...is captured here...
LL | foo(|| self.bar()).await;
| --- this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 12:31
--> $DIR/issue-62097.rs:12:31
|
LL | pub async fn run_dummy_fn(&self) {
| ^
| --- ...and required to be `'static` by this

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -2,15 +2,9 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/builtin-superkinds-self-type.rs:10:16
|
LL | impl <T: Sync> Foo for T { }
| -- ^^^
| -- ^^^ ...so that the type `T` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `T: 'static +`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/builtin-superkinds-self-type.rs:10:16
|
LL | impl <T: Sync> Foo for T { }
| ^^^

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `U` may not live long enough
LL | struct Foo<U> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`
LL | bar: Bar<U>
| ^^^^^^^^^^^
|
note: ...so that the type `U` will meet its required lifetime bounds
--> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:5
|
LL | bar: Bar<U>
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds

error: aborting due to previous error

6 changes: 1 addition & 5 deletions src/test/ui/generic-associated-types/impl_bounds.stderr
Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | type A<'a> where Self: 'static = (&'a ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `T: 'static`...
note: ...so that the type `Fooy<T>` will meet its required lifetime bounds
--> $DIR/impl_bounds.rs:15:5
|
LL | type A<'a> where Self: 'static = (&'a ());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the type `Fooy<T>` will meet its required lifetime bounds

error[E0478]: lifetime bound not satisfied
--> $DIR/impl_bounds.rs:17:5
56 changes: 19 additions & 37 deletions src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
Original file line number Diff line number Diff line change
@@ -2,55 +2,43 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:3:35
|
LL | fn elided(x: &i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| ---- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
--> $DIR/must_outlive_least_region_or_bound.rs:3:1
|
LL | fn elided(x: &i32) -> impl Copy { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
| ^^^^^^^^^^^^^^
| ^^^^

error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| ------- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
--> $DIR/must_outlive_least_region_or_bound.rs:6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^^^^^^^^^^^
| ^^^^

error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:12:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| -------------------------------- ^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
--> $DIR/must_outlive_least_region_or_bound.rs:12:15
| ------- -------------------------------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^

error[E0623]: lifetime mismatch
--> $DIR/must_outlive_least_region_or_bound.rs:17:61
@@ -65,15 +53,9 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:22:51
|
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| -- ^^^^^^^^^^^^^^^^^^^^
| -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `T: 'static +`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/must_outlive_least_region_or_bound.rs:22:51
|
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 5 previous errors

32 changes: 12 additions & 20 deletions src/test/ui/impl-trait/static-return-lifetime-infered.stderr
Original file line number Diff line number Diff line change
@@ -2,43 +2,35 @@ error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:7:16
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
| ----------------------- this return type evaluates to the `'static` lifetime...
| ----- ----------------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...but this borrow...
| ...and is captured here
|
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
--> $DIR/static-return-lifetime-infered.rs:6:5
|
LL | / fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
LL | | self.x.iter().map(|a| a.0)
LL | | }
| |_____^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^

error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:11:16
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ----------------------- this return type evaluates to the `'static` lifetime...
| -------- ----------------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
--> $DIR/static-return-lifetime-infered.rs:10:20
| ...and is captured here
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ^^
help: you can add a bound to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^

error: aborting due to 2 previous errors

8 changes: 1 addition & 7 deletions src/test/ui/impl-trait/type_parameters_captured.stderr
Original file line number Diff line number Diff line change
@@ -2,15 +2,9 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/type_parameters_captured.rs:7:20
|
LL | fn foo<T>(x: T) -> impl Any + 'static {
| - ^^^^^^^^^^^^^^^^^^
| - ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `T: 'static`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/type_parameters_captured.rs:7:20
|
LL | fn foo<T>(x: T) -> impl Any + 'static {
| ^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

10 changes: 10 additions & 0 deletions src/test/ui/issues/issue-16922.nll.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: lifetime may not live long enough
--> $DIR/issue-16922.rs:4:5
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
| - let's call the lifetime of this reference `'1`
LL | Box::new(value) as Box<dyn Any>
| ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-16922.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use std::any::Any;

fn foo<T: Any>(value: &T) -> Box<dyn Any> {
Box::new(value) as Box<dyn Any>
//~^ ERROR explicit lifetime required in the type of `value` [E0621]
//~^ ERROR cannot infer an appropriate lifetime
}

fn main() {
17 changes: 12 additions & 5 deletions src/test/ui/issues/issue-16922.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
error[E0621]: explicit lifetime required in the type of `value`
--> $DIR/issue-16922.rs:4:5
error: cannot infer an appropriate lifetime
--> $DIR/issue-16922.rs:4:14
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
| -- help: add explicit lifetime `'static` to the type of `value`: `&'static T`
| -- data with this lifetime...
LL | Box::new(value) as Box<dyn Any>
| ^^^^^^^^^^^^^^^ lifetime `'static` required
| ---------^^^^^-
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
| ^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0621`.
46 changes: 7 additions & 39 deletions src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,15 @@ error[E0310]: the parameter type `T` may not live long enough
LL | struct Foo<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | foo: &'static T
| ^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'static T` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:19:5
|
LL | foo: &'static T
| ^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at

error[E0309]: the parameter type `K` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
|
LL | trait X<K>: Sized {
| - help: consider adding an explicit lifetime bound...: `K: 'a`
LL | fn foo<'a, L: X<&'a Nested<K>>>();
| ^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
|
LL | fn foo<'a, L: X<&'a Nested<K>>>();
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at

error[E0309]: the parameter type `Self` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
@@ -33,51 +21,31 @@ LL | fn bar<'a, L: X<&'a Nested<Self>>>();
| ^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `Self: 'a`...
note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
|
LL | fn bar<'a, L: X<&'a Nested<Self>>>();
| ^^^^^^^^^^^^^^^^^^^
= note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at

error[E0309]: the parameter type `L` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
|
LL | fn baz<'a, L, M: X<&'a Nested<L>>>() {
| - ^^^^^^^^^^^^^^^^
| - ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<L>` does not outlive the data it points at
| |
| help: consider adding an explicit lifetime bound...: `L: 'a`
|
note: ...so that the reference type `&'a Nested<L>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
|
LL | fn baz<'a, L, M: X<&'a Nested<L>>>() {
| ^^^^^^^^^^^^^^^^

error[E0309]: the parameter type `K` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
|
LL | impl<K> Nested<K> {
| - help: consider adding an explicit lifetime bound...: `K: 'a`
LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
| ^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
|
LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
| ^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at

error[E0309]: the parameter type `M` may not live long enough
--> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
|
LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
| ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound...: `M: 'a +`
|
note: ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
--> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
|
LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
| ^^^^^^^^^^^^^^^^
| |
| ...so that the reference type `&'a Nested<M>` does not outlive the data it points at

error: aborting due to 6 previous errors

Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
--> $DIR/projection-where-clause-env-wrong-bound.rs:15:5
|
LL | bar::<T::Output>()
| ^^^^^^^^^^^^^^^^
= note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | bar::<<T as MyTrait<'a>>::Output>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as MyTrait<'a>>::Output: 'a`...
note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds
--> $DIR/projection-where-clause-env-wrong-lifetime.rs:14:5
|
LL | bar::<<T as MyTrait<'a>>::Output>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the type `<T as MyTrait<'a>>::Output` will meet its required lifetime bounds

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0621]: explicit lifetime required in the type of `ss`
error: lifetime may not live long enough
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
| --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
| -- has type `&mut SomeStruct<'1>`
...
LL | ss.r
| ^^^^ lifetime `'static` required
| ^^^^ returning this value requires that `'1` must outlive `'static`

error[E0507]: cannot move out of `ss.r` which is behind a mutable reference
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
// `Box<SomeTrait>` defaults to a `'static` bound, so this return
// is illegal.

ss.r //~ ERROR explicit lifetime required in the type of `ss` [E0621]
ss.r //~ ERROR cannot infer an appropriate lifetime
}

fn store(ss: &mut SomeStruct, b: Box<dyn SomeTrait>) {
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
error[E0621]: explicit lifetime required in the type of `ss`
error: cannot infer an appropriate lifetime
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
| --------------- help: add explicit lifetime `'static` to the type of `ss`: `&mut SomeStruct<'static>`
| --------------- data with this lifetime...
...
LL | ss.r
| ^^^^ lifetime `'static` required
| ^^^^ ...is captured and required to be `'static` here
|
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
| ^^^^

error[E0621]: explicit lifetime required in the type of `ss`
--> $DIR/object-lifetime-default-from-box-error.rs:31:12
Original file line number Diff line number Diff line change
@@ -14,17 +14,17 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required

error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:21:5
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:20:5
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
| - let's call the lifetime of this reference `'1`
...
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`

error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:26:5
--> $DIR/region-object-lifetime-in-coercion.rs:24:5
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| -- -- lifetime `'b` defined here
9 changes: 3 additions & 6 deletions src/test/ui/regions/region-object-lifetime-in-coercion.rs
Original file line number Diff line number Diff line change
@@ -11,20 +11,17 @@ fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
}

fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
Box::new(v)
//~^ ERROR explicit lifetime required in the type of `v` [E0621]
Box::new(v) //~ ERROR explicit lifetime required in the type of `v` [E0621]
}

fn c(v: &[u8]) -> Box<dyn Foo> {
// same as previous case due to RFC 599

Box::new(v)
//~^ ERROR explicit lifetime required in the type of `v` [E0621]
Box::new(v) //~ ERROR cannot infer an appropriate lifetime
}

fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
Box::new(v)
//~^ ERROR cannot infer an appropriate lifetime due to conflicting
Box::new(v) //~ ERROR cannot infer an appropriate lifetime due to conflicting
}

fn e<'a:'b,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
30 changes: 19 additions & 11 deletions src/test/ui/regions/region-object-lifetime-in-coercion.stderr
Original file line number Diff line number Diff line change
@@ -14,40 +14,48 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required

error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/region-object-lifetime-in-coercion.rs:21:5
error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:20:14
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ----- help: add explicit lifetime `'static` to the type of `v`: `&'static [u8]`
| ----- data with this lifetime...
...
LL | Box::new(v)
| ^^^^^^^^^^^ lifetime `'static` required
| ---------^-
| | |
| | ...and is captured here
| ...is required to be `'static` by this...
|
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1
|
LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
| ^^^^

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/region-object-lifetime-in-coercion.rs:26:14
--> $DIR/region-object-lifetime-in-coercion.rs:24:14
|
LL | Box::new(v)
| ^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6...
--> $DIR/region-object-lifetime-in-coercion.rs:25:6
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 23:6...
--> $DIR/region-object-lifetime-in-coercion.rs:23:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the expression is assignable
--> $DIR/region-object-lifetime-in-coercion.rs:26:14
--> $DIR/region-object-lifetime-in-coercion.rs:24:14
|
LL | Box::new(v)
| ^
= note: expected `&[u8]`
found `&'a [u8]`
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
--> $DIR/region-object-lifetime-in-coercion.rs:25:9
note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 23:9...
--> $DIR/region-object-lifetime-in-coercion.rs:23:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the expression is assignable
--> $DIR/region-object-lifetime-in-coercion.rs:26:5
--> $DIR/region-object-lifetime-in-coercion.rs:24:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | Box::new(item)
| ^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
--> $DIR/regions-close-associated-type-into-object.rs:15:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds

error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:22:5
@@ -18,11 +14,7 @@ LL | Box::new(item)
| ^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`...
note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
--> $DIR/regions-close-associated-type-into-object.rs:22:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
= note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds

error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:28:5
@@ -31,11 +23,7 @@ LL | Box::new(item)
| ^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
--> $DIR/regions-close-associated-type-into-object.rs:28:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds

error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:35:5
@@ -44,11 +32,7 @@ LL | Box::new(item)
| ^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`...
note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds
--> $DIR/regions-close-associated-type-into-object.rs:35:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
= note: ...so that the type `std::boxed::Box<<T as Iter>::Item>` will meet its required lifetime bounds

error: aborting due to 4 previous errors

48 changes: 6 additions & 42 deletions src/test/ui/regions/regions-close-object-into-object-5.stderr
Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^^^^^^^^
|
note: ...so that the type `B<'_, T>` will meet its required lifetime bounds
--> $DIR/regions-close-object-into-object-5.rs:17:5
|
LL | box B(&*v) as Box<X>
| ^^^^^^^^^^
| ^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:9
@@ -20,13 +14,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-close-object-into-object-5.rs:17:9
|
LL | box B(&*v) as Box<X>
| ^
| ^ ...so that the type `T` will meet its required lifetime bounds

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:9
@@ -35,13 +23,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-close-object-into-object-5.rs:17:9
|
LL | box B(&*v) as Box<X>
| ^^^^^^
| ^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -50,13 +32,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
|
note: ...so that the reference type `&dyn A<T>` does not outlive the data it points at
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | box B(&*v) as Box<X>
| ^^^
| ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -65,13 +41,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
|
note: ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | box B(&*v) as Box<X>
| ^^^
| ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:11
@@ -80,13 +50,7 @@ LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // oh dear!
LL | box B(&*v) as Box<X>
| ^^^
|
note: ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
--> $DIR/regions-close-object-into-object-5.rs:17:11
|
LL | box B(&*v) as Box<X>
| ^^^
| ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long

error: aborting due to 6 previous errors

16 changes: 2 additions & 14 deletions src/test/ui/regions/regions-close-over-type-parameter-1.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,15 @@ error[E0310]: the parameter type `A` may not live long enough
LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
| -- help: consider adding an explicit lifetime bound...: `A: 'static +`
LL | box v as Box<dyn SomeTrait + 'static>
| ^^^^^
|
note: ...so that the type `A` will meet its required lifetime bounds
--> $DIR/regions-close-over-type-parameter-1.rs:12:5
|
LL | box v as Box<dyn SomeTrait + 'static>
| ^^^^^
| ^^^^^ ...so that the type `A` will meet its required lifetime bounds

error[E0309]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:21:5
|
LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
| -- help: consider adding an explicit lifetime bound...: `A: 'b +`
LL | box v as Box<dyn SomeTrait + 'b>
| ^^^^^
|
note: ...so that the type `A` will meet its required lifetime bounds
--> $DIR/regions-close-over-type-parameter-1.rs:21:5
|
LL | box v as Box<dyn SomeTrait + 'b>
| ^^^^^
| ^^^^^ ...so that the type `A` will meet its required lifetime bounds

error: aborting due to 2 previous errors

32 changes: 4 additions & 28 deletions src/test/ui/regions/regions-close-param-into-object.stderr
Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | fn p1<T>(v: T) -> Box<dyn X + 'static>
| - help: consider adding an explicit lifetime bound...: `T: 'static`
...
LL | Box::new(v)
| ^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-close-param-into-object.rs:6:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-param-into-object.rs:12:5
@@ -20,13 +14,7 @@ LL | fn p2<T>(v: Box<T>) -> Box<dyn X + 'static>
| - help: consider adding an explicit lifetime bound...: `T: 'static`
...
LL | Box::new(v)
| ^^^^^^^^^^^
|
note: ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
--> $DIR/regions-close-param-into-object.rs:12:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-close-param-into-object.rs:18:5
@@ -35,13 +23,7 @@ LL | fn p3<'a,T>(v: T) -> Box<dyn X + 'a>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | Box::new(v)
| ^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-close-param-into-object.rs:18:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-close-param-into-object.rs:24:5
@@ -50,13 +32,7 @@ LL | fn p4<'a,T>(v: Box<T>) -> Box<dyn X + 'a>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | Box::new(v)
| ^^^^^^^^^^^
|
note: ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds
--> $DIR/regions-close-param-into-object.rs:24:5
|
LL | Box::new(v)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `std::boxed::Box<T>` will meet its required lifetime bounds

error: aborting due to 4 previous errors

35 changes: 4 additions & 31 deletions src/test/ui/regions/regions-enum-not-wf.stderr
Original file line number Diff line number Diff line change
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
LL | enum Ref1<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:18:18
|
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:23:25
@@ -19,13 +13,7 @@ LL | enum Ref2<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref2Variant1,
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:23:25
|
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:35:1
@@ -37,30 +25,15 @@ LL | enum RefDouble<'a, 'b, T> {
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
LL | |
LL | | }
| |_^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:35:1
|
LL | / enum RefDouble<'a, 'b, T> {
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
LL | |
LL | | }
| |_^
| |_^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | enum RefDouble<'a, 'b, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'b`
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to 4 previous errors

Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo)
| -- help: consider adding an explicit lifetime bound...: `T: 'x +`
LL | {
LL | wf::<&'x T>();
| ^^^^^
|
note: ...so that the reference type `&'x T` does not outlive the data it points at
--> $DIR/regions-implied-bounds-projection-gap-1.rs:16:10
|
LL | wf::<&'x T>();
| ^^^^^
| ^^^^^ ...so that the reference type `&'x T` does not outlive the data it points at

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | check_bound(x, self)
| ^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `Self: 'a`...
note: ...so that the type `Self` will meet its required lifetime bounds
--> $DIR/regions-infer-bound-from-trait-self.rs:46:9
|
LL | check_bound(x, self)
| ^^^^^^^^^^^
= note: ...so that the type `Self` will meet its required lifetime bounds

error: aborting due to previous error

16 changes: 2 additions & 14 deletions src/test/ui/regions/regions-infer-bound-from-trait.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,15 @@ error[E0309]: the parameter type `A` may not live long enough
LL | fn bar1<'a,A>(x: Inv<'a>, a: A) {
| - help: consider adding an explicit lifetime bound...: `A: 'a`
LL | check_bound(x, a)
| ^^^^^^^^^^^
|
note: ...so that the type `A` will meet its required lifetime bounds
--> $DIR/regions-infer-bound-from-trait.rs:33:5
|
LL | check_bound(x, a)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds

error[E0309]: the parameter type `A` may not live long enough
--> $DIR/regions-infer-bound-from-trait.rs:37:5
|
LL | fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) {
| -- help: consider adding an explicit lifetime bound...: `A: 'a +`
LL | check_bound(x, a)
| ^^^^^^^^^^^
|
note: ...so that the type `A` will meet its required lifetime bounds
--> $DIR/regions-infer-bound-from-trait.rs:37:5
|
LL | check_bound(x, a)
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds

error: aborting due to 2 previous errors

8 changes: 1 addition & 7 deletions src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
Original file line number Diff line number Diff line change
@@ -4,13 +4,7 @@ error[E0310]: the parameter type `U` may not live long enough
LL | struct Foo<U> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`
LL | bar: Bar<U>
| ^^^^^^^^^^^
|
note: ...so that the type `U` will meet its required lifetime bounds
--> $DIR/dont-infer-static.rs:8:5
|
LL | bar: Bar<U>
| ^^^^^^^^^^^
| ^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds

error: aborting due to previous error

35 changes: 4 additions & 31 deletions src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr
Original file line number Diff line number Diff line change
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
LL | enum Ref1<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:18:18
|
LL | Ref1Variant1(RequireOutlives<'a, T>)
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:23:25
@@ -19,13 +13,7 @@ LL | enum Ref2<'a, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | Ref2Variant1,
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:23:25
|
LL | Ref2Variant2(isize, RequireOutlives<'a, T>),
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:35:1
@@ -37,30 +25,15 @@ LL | enum RefDouble<'a, 'b, T> {
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
LL | |
LL | | }
| |_^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:35:1
|
LL | / enum RefDouble<'a, 'b, T> {
LL | | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
LL | |
LL | | }
| |_^
| |_^ ...so that the type `T` will meet its required lifetime bounds

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | enum RefDouble<'a, 'b, T> {
| - help: consider adding an explicit lifetime bound...: `T: 'b`
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-enum-not-wf.rs:36:23
|
LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error: aborting due to 4 previous errors

16 changes: 2 additions & 14 deletions src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,15 @@ error[E0309]: the parameter type `T` may not live long enough
LL | impl<'a, T> Trait<'a, T> for usize {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a T;
| ^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a T` does not outlive the data it points at
--> $DIR/regions-struct-not-wf.rs:13:5
|
LL | type Out = &'a T;
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/regions-struct-not-wf.rs:21:5
|
LL | impl<'a, T> Trait<'a, T> for u32 {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = RefOk<'a, T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/regions-struct-not-wf.rs:21:5
|
LL | type Out = RefOk<'a, T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds

error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references
--> $DIR/regions-struct-not-wf.rs:25:5
Original file line number Diff line number Diff line change
@@ -2,15 +2,10 @@ error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^ ---------- this return type evaluates to the `'static` lifetime...
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 8:26
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^
| ^^^^ ---------- ---------- ...and required to be `'static` by this
| | |
| | data with this lifetime...
| ...is captured here...

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -2,19 +2,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ---------- ^^^^ ...but this borrow...
| |
| this return type evaluates to the `'static` lifetime...
| ---------- ---------- ^^^^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the return type to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^^^^^^^^^^^^
| ^^^^

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/missing-lifetimes-in-signature.rs:37:11
|
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| - ^^ undeclared lifetime
| |
| help: consider introducing lifetime `'a` here: `'a,`

error: lifetime may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:15:37
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
| - ^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
| |
| let's call the lifetime of this reference `'1`
|
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 25:1...
--> $DIR/missing-lifetimes-in-signature.rs:25:1
|
LL | / fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
LL | |
LL | | where
LL | | G: Get<T>
... |
LL | | }
LL | | }
| |_^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 47:1...
--> $DIR/missing-lifetimes-in-signature.rs:47:1
|
LL | / fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
LL | |
LL | | where
LL | | G: Get<T>
... |
LL | | }
LL | | }
| |_^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the method body at 59:5...
--> $DIR/missing-lifetimes-in-signature.rs:59:5
|
LL | / fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
LL | |
LL | | move || {
LL | | *dest = g.get();
LL | | }
LL | | }
| |_____^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:68:45
|
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ^^^^^^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 68:1...
--> $DIR/missing-lifetimes-in-signature.rs:68:1
|
LL | / fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
LL | |
LL | | where
LL | | G: Get<T>
... |
LL | | }
LL | | }
| |_^

error[E0621]: explicit lifetime required in the type of `dest`
--> $DIR/missing-lifetimes-in-signature.rs:73:5
|
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
...
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^ lifetime `'a` required

error[E0309]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:79:44
|
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
| ^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `G: 'a`...

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0261, E0309, E0621.
For more information about an error, try `rustc --explain E0261`.
110 changes: 110 additions & 0 deletions src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
pub trait Get<T> {
fn get(self) -> T;
}

struct Foo {
x: usize,
}

impl Get<usize> for Foo {
fn get(self) -> usize {
self.x
}
}

fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
where
G: Get<T>
{
move || { //~ ERROR cannot infer an appropriate lifetime
*dest = g.get();
}
}

// After applying suggestion for `foo`:
fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
//~^ ERROR the parameter type `G` may not live long enough
where
G: Get<T>
{
move || {
*dest = g.get();
}
}


// After applying suggestion for `bar`:
fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ //~ ERROR undeclared lifetime
where
G: Get<T>
{
move || {
*dest = g.get();
}
}

// After applying suggestion for `baz`:
fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
//~^ ERROR the parameter type `G` may not live long enough
where
G: Get<T>
{
move || {
*dest = g.get();
}
}

// Same as above, but show that we pay attention to lifetime names from parent item
impl<'a> Foo {
fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
//~^ ERROR the parameter type `G` may not live long enough
move || {
*dest = g.get();
}
}
}

// After applying suggestion for `qux`:
fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
//~^ ERROR explicit lifetime required in the type of `dest`
where
G: Get<T>
{
move || {
*dest = g.get();
}
}

// Potential incorrect attempt:
fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
//~^ ERROR the parameter type `G` may not live long enough
where
G: Get<T>
{
move || {
*dest = g.get();
}
}


// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure:
fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
where
G: Get<T>
{
move || {
*dest = g.get();
}
}

// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
where
G: Get<T>
{
move || {
*dest = g.get();
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
error[E0261]: use of undeclared lifetime name `'a`
--> $DIR/missing-lifetimes-in-signature.rs:37:11
|
LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| - ^^ undeclared lifetime
| |
| help: consider introducing lifetime `'a` here: `'a,`

error: cannot infer an appropriate lifetime
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
| ------ ------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
...
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^ ...and is captured here
|
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 25:1...
--> $DIR/missing-lifetimes-in-signature.rs:25:1
|
LL | / fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
LL | |
LL | | where
LL | | G: Get<T>
... |
LL | | }
LL | | }
| |_^
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:30:5: 32:6 g:G, dest:&mut T]` will meet its required lifetime bounds
--> $DIR/missing-lifetimes-in-signature.rs:25:37
|
LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime bound
|
LL | fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ^^^^^ ^^^^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the function body at 47:1...
--> $DIR/missing-lifetimes-in-signature.rs:47:1
|
LL | / fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
LL | |
LL | | where
LL | | G: Get<T>
... |
LL | | }
LL | | }
| |_^
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:52:5: 54:6 g:G, dest:&mut T]` will meet its required lifetime bounds
--> $DIR/missing-lifetimes-in-signature.rs:47:45
|
LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime bound
|
LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b
| ^^^ ^^^^^^^ ^^^^

error[E0311]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
| ^^^^^^^^^^^^^^^^^^
|
note: the parameter type `G` must be valid for the anonymous lifetime #1 defined on the method body at 59:5...
--> $DIR/missing-lifetimes-in-signature.rs:59:5
|
LL | / fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
LL | |
LL | | move || {
LL | | *dest = g.get();
LL | | }
LL | | }
| |_____^
note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:61:9: 63:10 g:G, dest:&mut T]` will meet its required lifetime bounds
--> $DIR/missing-lifetimes-in-signature.rs:59:58
|
LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
| ^^^^^^^^^^^^^^^^^^
help: consider introducing an explicit lifetime bound
|
LL | fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c {
| ^^^ ^^^^^^^ ^^^^

error[E0621]: explicit lifetime required in the type of `dest`
--> $DIR/missing-lifetimes-in-signature.rs:68:45
|
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ------ ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
| |
| help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`

error[E0309]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:79:44
|
LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
| - ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:84:5: 86:6 g:G, dest:&mut T]` will meet its required lifetime bounds
| |
| help: consider adding an explicit lifetime bound...: `G: 'a`

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0261, E0309, E0621.
For more information about an error, try `rustc --explain E0261`.
8 changes: 1 addition & 7 deletions src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | fn foo(d: impl Debug) {
| ---------- help: consider adding an explicit lifetime bound...: `impl Debug + 'static`
LL |
LL | bar(d);
| ^^^
|
note: ...so that the type `impl Debug` will meet its required lifetime bounds
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
LL | bar(d);
| ^^^
| ^^^ ...so that the type `impl Debug` will meet its required lifetime bounds

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -22,16 +22,10 @@ error[E0310]: the parameter type `T` may not live long enough
--> $DIR/generic_type_does_not_live_long_enough.rs:9:1
|
LL | type WrongGeneric<T> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
...
LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
|
note: ...so that the type `T` will meet its required lifetime bounds
--> $DIR/generic_type_does_not_live_long_enough.rs:9:1
|
LL | type WrongGeneric<T> = impl 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

31 changes: 8 additions & 23 deletions src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
error: cannot infer an appropriate lifetime
--> $DIR/dyn-trait-underscore.rs:8:20
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| ---- data with this lifetime...
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ^^^^
| ---------------^^^^--- ...is captured and required to be `'static` here
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 6:1...
--> $DIR/dyn-trait-underscore.rs:6:1
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
|
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | | Box::new(items.iter())
LL | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> $DIR/dyn-trait-underscore.rs:8:14
|
LL | Box::new(items.iter())
| ^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
--> $DIR/dyn-trait-underscore.rs:8:5
|
LL | Box::new(items.iter())
| ^^^^^^^^^^^^^^^^^^^^^^
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = &T> + 'static)>`
found `std::boxed::Box<dyn std::iter::Iterator<Item = &T>>`
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
| ^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
8 changes: 1 addition & 7 deletions src/test/ui/wf/wf-impl-associated-type-region.stderr
Original file line number Diff line number Diff line change
@@ -4,13 +4,7 @@ error[E0309]: the parameter type `T` may not live long enough
LL | impl<'a, T> Foo<'a> for T {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Bar = &'a T;
| ^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a T` does not outlive the data it points at
--> $DIR/wf-impl-associated-type-region.rs:10:5
|
LL | type Bar = &'a T;
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at

error: aborting due to previous error

16 changes: 2 additions & 14 deletions src/test/ui/wf/wf-in-fn-type-static.stderr
Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | struct Foo<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: 'static
LL | x: fn() -> &'static T
| ^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'static T` does not outlive the data it points at
--> $DIR/wf-in-fn-type-static.rs:13:5
|
LL | x: fn() -> &'static T
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at

error[E0310]: the parameter type `T` may not live long enough
--> $DIR/wf-in-fn-type-static.rs:18:5
@@ -20,13 +14,7 @@ LL | struct Bar<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: Copy
LL | x: fn(&'static T)
| ^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'static T` does not outlive the data it points at
--> $DIR/wf-in-fn-type-static.rs:18:5
|
LL | x: fn(&'static T)
| ^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at

error: aborting due to 2 previous errors

8 changes: 1 addition & 7 deletions src/test/ui/wf/wf-in-obj-type-static.stderr
Original file line number Diff line number Diff line change
@@ -5,13 +5,7 @@ LL | struct Foo<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
LL | // needs T: 'static
LL | x: dyn Object<&'static T>
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'static T` does not outlive the data it points at
--> $DIR/wf-in-obj-type-static.rs:14:5
|
LL | x: dyn Object<&'static T>
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at

error: aborting due to previous error

16 changes: 2 additions & 14 deletions src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr
Original file line number Diff line number Diff line change
@@ -4,27 +4,15 @@ error[E0309]: the parameter type `T` may not live long enough
LL | impl<'a, T> Trait<'a, T> for usize {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a fn(T);
| ^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a fn(T)` does not outlive the data it points at
--> $DIR/wf-outlives-ty-in-fn-or-trait.rs:9:5
|
LL | type Out = &'a fn(T);
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a fn(T)` does not outlive the data it points at

error[E0309]: the parameter type `T` may not live long enough
--> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
|
LL | impl<'a, T> Trait<'a, T> for u32 {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | type Out = &'a dyn Baz<T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at
--> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:5
|
LL | type Out = &'a dyn Baz<T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at

error: aborting due to 2 previous errors

6 changes: 1 addition & 5 deletions src/test/ui/wf/wf-trait-associated-type-region.stderr
Original file line number Diff line number Diff line change
@@ -5,11 +5,7 @@ LL | type Type2 = &'a Self::Type1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding an explicit lifetime bound `<Self as SomeTrait<'a>>::Type1: 'a`...
note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at
--> $DIR/wf-trait-associated-type-region.rs:9:5
|
LL | type Type2 = &'a Self::Type1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...so that the reference type `&'a <Self as SomeTrait<'a>>::Type1` does not outlive the data it points at

error: aborting due to previous error