parent
9e92106d45
commit
6513148c14
13 changed files with 431 additions and 302 deletions
|
@ -2,227 +2,302 @@
|
|||
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
use rustc_errors::{struct_span_err, Applicability, ErrorReported};
|
||||
use rustc_hir::{GenericBound, ItemKind, Lifetime, LifetimeName, TyKind};
|
||||
use rustc_middle::ty::RegionKind;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::{
|
||||
GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, Path, PolyTraitRef, TraitRef,
|
||||
TyKind,
|
||||
};
|
||||
use rustc_middle::ty::{self, RegionKind, Ty, TypeFoldable, TypeVisitor};
|
||||
|
||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
/// Print the error message for lifetime errors when the return type is a static impl Trait.
|
||||
pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
|
||||
debug!("try_report_static_impl_trait(error={:?})", self.error);
|
||||
if let Some(RegionResolutionError::SubSupConflict(
|
||||
_,
|
||||
var_origin,
|
||||
ref sub_origin,
|
||||
sub_r,
|
||||
ref sup_origin,
|
||||
sup_r,
|
||||
)) = self.error
|
||||
{
|
||||
debug!(
|
||||
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
|
||||
var_origin, sub_origin, sub_r, sup_origin, sup_r
|
||||
);
|
||||
let anon_reg_sup = self.tcx().is_suitable_region(sup_r)?;
|
||||
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
|
||||
let fn_returns = self.tcx().return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
||||
if fn_returns.is_empty() {
|
||||
return None;
|
||||
let tcx = self.tcx();
|
||||
let (var_origin, sub_origin, sub_r, sup_origin, sup_r) = match self.error.as_ref()? {
|
||||
RegionResolutionError::SubSupConflict(
|
||||
_,
|
||||
var_origin,
|
||||
sub_origin,
|
||||
sub_r,
|
||||
sup_origin,
|
||||
sup_r,
|
||||
) if **sub_r == RegionKind::ReStatic => {
|
||||
(var_origin, sub_origin, sub_r, sup_origin, sup_r)
|
||||
}
|
||||
debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns);
|
||||
if *sub_r == RegionKind::ReStatic {
|
||||
let sp = var_origin.span();
|
||||
let return_sp = sub_origin.span();
|
||||
let param_info = self.find_param_with_region(sup_r, sub_r)?;
|
||||
let (lifetime_name, lifetime) = if sup_r.has_name() {
|
||||
(sup_r.to_string(), format!("lifetime `{}`", sup_r))
|
||||
} else {
|
||||
("'_".to_owned(), "an anonymous lifetime `'_`".to_string())
|
||||
};
|
||||
let mut err = struct_span_err!(
|
||||
self.tcx().sess,
|
||||
sp,
|
||||
E0759,
|
||||
"cannot infer an appropriate lifetime"
|
||||
);
|
||||
_ => return None,
|
||||
};
|
||||
debug!(
|
||||
"try_report_static_impl_trait(var={:?}, sub={:?} {:?} sup={:?} {:?})",
|
||||
var_origin, sub_origin, sub_r, sup_origin, sup_r
|
||||
);
|
||||
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
|
||||
debug!("try_report_static_impl_trait: anon_reg_sup={:?}", anon_reg_sup);
|
||||
let sp = var_origin.span();
|
||||
let return_sp = sub_origin.span();
|
||||
let param = self.find_param_with_region(sup_r, sub_r)?;
|
||||
let (lifetime_name, lifetime) = if sup_r.has_name() {
|
||||
(sup_r.to_string(), format!("lifetime `{}`", sup_r))
|
||||
} else {
|
||||
("'_".to_owned(), "an anonymous lifetime `'_`".to_string())
|
||||
};
|
||||
let mut err = struct_span_err!(tcx.sess, sp, E0759, "cannot infer an appropriate lifetime");
|
||||
err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime));
|
||||
debug!("try_report_static_impl_trait: param_info={:?}", param);
|
||||
|
||||
// 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
|
||||
{
|
||||
// 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().overlaps(return_sp) && sp == sup_origin.span() {
|
||||
// Avoid the following:
|
||||
//
|
||||
// error: cannot infer an appropriate lifetime
|
||||
// --> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
||||
// |
|
||||
// LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
|
||||
// | ---- ---------^-
|
||||
//
|
||||
// and instead show:
|
||||
//
|
||||
// error: cannot infer an appropriate lifetime
|
||||
// --> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
||||
// |
|
||||
// LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
|
||||
// | ---- ^
|
||||
err.span_label(
|
||||
param_info.param_ty_span,
|
||||
&format!("this data with {}...", lifetime),
|
||||
sup_origin.span(),
|
||||
"...is captured here, requiring it to live as long as `'static`",
|
||||
);
|
||||
debug!("try_report_static_impl_trait: param_info={:?}", param_info);
|
||||
|
||||
// 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
|
||||
{
|
||||
// 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().overlaps(return_sp) && sp == sup_origin.span() {
|
||||
// Avoid the following:
|
||||
//
|
||||
// error: cannot infer an appropriate lifetime
|
||||
// --> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
||||
// |
|
||||
// LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
|
||||
// | ---- ---------^-
|
||||
//
|
||||
// and instead show:
|
||||
//
|
||||
// error: cannot infer an appropriate lifetime
|
||||
// --> $DIR/must_outlive_least_region_or_bound.rs:18:50
|
||||
// |
|
||||
// LL | fn foo(x: &i32) -> Box<dyn Debug> { Box::new(x) }
|
||||
// | ---- ^
|
||||
err.span_label(
|
||||
sup_origin.span(),
|
||||
"...is captured here, requiring it to live as long as `'static`",
|
||||
);
|
||||
} else {
|
||||
err.span_label(sup_origin.span(), "...is captured here...");
|
||||
if return_sp < sup_origin.span() {
|
||||
err.span_note(
|
||||
return_sp,
|
||||
"...and is required to live as long as `'static` here",
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
return_sp,
|
||||
"...and is required to live as long as `'static` here",
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err.span_label(sup_origin.span(), "...is captured here...");
|
||||
if return_sp < sup_origin.span() {
|
||||
err.span_note(
|
||||
return_sp,
|
||||
"...and is required to live as long as `'static` here",
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
return_sp,
|
||||
"...is captured and required to live as long as `'static` here",
|
||||
"...and is required to live as long as `'static` here",
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err.span_label(
|
||||
return_sp,
|
||||
"...is captured and required to live as long as `'static` here",
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
|
||||
let consider = "consider changing the";
|
||||
let declare = "to declare that the";
|
||||
let arg = match param_info.param.pat.simple_ident() {
|
||||
Some(simple_ident) => format!("argument `{}`", simple_ident),
|
||||
None => "the argument".to_string(),
|
||||
};
|
||||
let explicit =
|
||||
format!("you can add an explicit `{}` lifetime bound", lifetime_name);
|
||||
let explicit_static =
|
||||
format!("explicit `'static` bound to the lifetime of {}", arg);
|
||||
let captures = format!("captures data from {}", arg);
|
||||
let add_static_bound =
|
||||
"alternatively, add an explicit `'static` bound to this reference";
|
||||
let plus_lt = format!(" + {}", lifetime_name);
|
||||
for fn_return in fn_returns {
|
||||
if fn_return.span.desugaring_kind().is_some() {
|
||||
// Skip `async` desugaring `impl Future`.
|
||||
continue;
|
||||
self.find_impl_on_dyn_trait(&mut err, param.param_ty);
|
||||
|
||||
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
|
||||
debug!("try_report_static_impl_trait: fn_return={:?}", fn_returns);
|
||||
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
|
||||
let consider = "consider changing the";
|
||||
let declare = "to declare that the";
|
||||
let arg = match param.param.pat.simple_ident() {
|
||||
Some(simple_ident) => format!("argument `{}`", simple_ident),
|
||||
None => "the argument".to_string(),
|
||||
};
|
||||
let explicit = format!("you can add an explicit `{}` lifetime bound", lifetime_name);
|
||||
let explicit_static = format!("explicit `'static` bound to the lifetime of {}", arg);
|
||||
let captures = format!("captures data from {}", arg);
|
||||
let add_static_bound = "alternatively, add an explicit `'static` bound to this reference";
|
||||
let plus_lt = format!(" + {}", lifetime_name);
|
||||
for fn_return in fn_returns {
|
||||
if fn_return.span.desugaring_kind().is_some() {
|
||||
// Skip `async` desugaring `impl Future`.
|
||||
continue;
|
||||
}
|
||||
match fn_return.kind {
|
||||
TyKind::OpaqueDef(item_id, _) => {
|
||||
let item = tcx.hir().item(item_id.id);
|
||||
let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
|
||||
opaque
|
||||
} else {
|
||||
err.emit();
|
||||
return Some(ErrorReported);
|
||||
};
|
||||
|
||||
if let Some(span) = opaque
|
||||
.bounds
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime {
|
||||
name: LifetimeName::Static,
|
||||
span,
|
||||
..
|
||||
}) => Some(*span),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!("{} `impl Trait`'s {}", consider, explicit_static),
|
||||
lifetime_name.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
param.param_ty_span,
|
||||
add_static_bound,
|
||||
param.param_ty.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if let Some(_) = opaque
|
||||
.bounds
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime { name, span, .. })
|
||||
if name.ident().to_string() == lifetime_name =>
|
||||
{
|
||||
Some(*span)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
{
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
&format!(
|
||||
"{declare} `impl Trait` {captures}, {explicit}",
|
||||
declare = declare,
|
||||
captures = captures,
|
||||
explicit = explicit,
|
||||
),
|
||||
plus_lt.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
match fn_return.kind {
|
||||
TyKind::OpaqueDef(item_id, _) => {
|
||||
let item = self.tcx().hir().item(item_id.id);
|
||||
let opaque = if let ItemKind::OpaqueTy(opaque) = &item.kind {
|
||||
opaque
|
||||
} else {
|
||||
err.emit();
|
||||
return Some(ErrorReported);
|
||||
};
|
||||
}
|
||||
TyKind::TraitObject(_, lt) => match lt.name {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
&format!(
|
||||
"{declare} trait object {captures}, {explicit}",
|
||||
declare = declare,
|
||||
captures = captures,
|
||||
explicit = explicit,
|
||||
),
|
||||
plus_lt.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
name if name.ident().to_string() != lifetime_name => {
|
||||
// With this check we avoid suggesting redundant bounds. This
|
||||
// would happen if there are nested impl/dyn traits and only
|
||||
// one of them has the bound we'd suggest already there, like
|
||||
// in `impl Foo<X = dyn Bar> + '_`.
|
||||
err.span_suggestion_verbose(
|
||||
lt.span,
|
||||
&format!("{} trait object's {}", consider, explicit_static),
|
||||
lifetime_name.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
param.param_ty_span,
|
||||
add_static_bound,
|
||||
param.param_ty.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
Some(ErrorReported)
|
||||
}
|
||||
|
||||
if let Some(span) = opaque
|
||||
.bounds
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime {
|
||||
name: LifetimeName::Static,
|
||||
span,
|
||||
..
|
||||
}) => Some(*span),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
{
|
||||
/// When we call a method coming from an `impl Foo for dyn Bar`, `dyn Bar` introduces a default
|
||||
/// `'static` obligation. Find `impl` blocks that are implemented
|
||||
fn find_impl_on_dyn_trait(&self, err: &mut DiagnosticBuilder<'_>, ty: Ty<'_>) -> bool {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Find the trait object types in the argument.
|
||||
let mut v = TraitObjectVisitor(vec![]);
|
||||
v.visit_ty(ty);
|
||||
debug!("TraitObjectVisitor {:?}", v.0);
|
||||
|
||||
// Find all the `impl`s in the local scope that can be called on the type parameter.
|
||||
// FIXME: this doesn't find `impl dyn Trait { /**/ }`.
|
||||
let impl_self_tys = tcx
|
||||
.all_traits(LOCAL_CRATE)
|
||||
.iter()
|
||||
.flat_map(|trait_did| tcx.hir().trait_impls(*trait_did))
|
||||
.filter_map(|impl_node| {
|
||||
let impl_did = tcx.hir().local_def_id(*impl_node);
|
||||
if let Some(Node::Item(Item { kind: ItemKind::Impl { self_ty, .. }, .. })) =
|
||||
tcx.hir().get_if_local(impl_did.to_def_id())
|
||||
{
|
||||
Some(self_ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let mut suggested = false;
|
||||
for self_ty in impl_self_tys {
|
||||
if let TyKind::TraitObject(
|
||||
poly_trait_refs,
|
||||
Lifetime { name: LifetimeName::ImplicitObjectLifetimeDefault, .. },
|
||||
) = self_ty.kind
|
||||
{
|
||||
for p in poly_trait_refs {
|
||||
if let PolyTraitRef {
|
||||
trait_ref:
|
||||
TraitRef { path: Path { res: Res::Def(DefKind::Trait, did), .. }, .. },
|
||||
..
|
||||
} = p
|
||||
{
|
||||
for found_did in &v.0 {
|
||||
if did == found_did {
|
||||
// We've found an `impl Foo for dyn Bar {}`.
|
||||
// FIXME: we should change this so it also works for
|
||||
// `impl Foo for Box<dyn Bar> {}`.
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
&format!("{} `impl Trait`'s {}", consider, explicit_static),
|
||||
lifetime_name.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
param_info.param_ty_span,
|
||||
add_static_bound,
|
||||
param_info.param_ty.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if let Some(_) = opaque
|
||||
.bounds
|
||||
.iter()
|
||||
.filter_map(|arg| match arg {
|
||||
GenericBound::Outlives(Lifetime { name, span, .. })
|
||||
if name.ident().to_string() == lifetime_name =>
|
||||
{
|
||||
Some(*span)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
{
|
||||
} else {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
&format!(
|
||||
"{declare} `impl Trait` {captures}, {explicit}",
|
||||
declare = declare,
|
||||
captures = captures,
|
||||
explicit = explicit,
|
||||
),
|
||||
plus_lt.clone(),
|
||||
self_ty.span.shrink_to_hi(),
|
||||
"this `impl` introduces an implicit `'static` requirement, \
|
||||
consider changing it",
|
||||
" + '_".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
suggested = true;
|
||||
}
|
||||
}
|
||||
TyKind::TraitObject(_, lt) => match lt.name {
|
||||
LifetimeName::ImplicitObjectLifetimeDefault => {
|
||||
err.span_suggestion_verbose(
|
||||
fn_return.span.shrink_to_hi(),
|
||||
&format!(
|
||||
"{declare} trait object {captures}, {explicit}",
|
||||
declare = declare,
|
||||
captures = captures,
|
||||
explicit = explicit,
|
||||
),
|
||||
plus_lt.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
name if name.ident().to_string() != lifetime_name => {
|
||||
// With this check we avoid suggesting redundant bounds. This
|
||||
// would happen if there are nested impl/dyn traits and only
|
||||
// one of them has the bound we'd suggest already there, like
|
||||
// in `impl Foo<X = dyn Bar> + '_`.
|
||||
err.span_suggestion_verbose(
|
||||
lt.span,
|
||||
&format!("{} trait object's {}", consider, explicit_static),
|
||||
lifetime_name.clone(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
param_info.param_ty_span,
|
||||
add_static_bound,
|
||||
param_info.param_ty.to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
return Some(ErrorReported);
|
||||
}
|
||||
}
|
||||
None
|
||||
suggested
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
|
||||
struct TraitObjectVisitor(Vec<DefId>);
|
||||
|
||||
impl TypeVisitor<'_> for TraitObjectVisitor {
|
||||
fn visit_ty(&mut self, t: Ty<'_>) -> bool {
|
||||
match t.kind {
|
||||
ty::Dynamic(preds, RegionKind::ReStatic) => {
|
||||
if let Some(def_id) = preds.principal_def_id() {
|
||||
self.0.push(def_id);
|
||||
}
|
||||
false
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
|
|||
|
||||
#[cfg(transmute)] // one instantiations: BAD
|
||||
fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
|
||||
bar(foo, x) //[transmute]~ ERROR E0495
|
||||
bar(foo, x) //[transmute]~ ERROR E0759
|
||||
}
|
||||
|
||||
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
|
||||
|
|
|
@ -1,26 +1,11 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/project-fn-ret-contravariant.rs:38:8
|
||||
|
|
||||
LL | bar(foo, x)
|
||||
| ^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8...
|
||||
--> $DIR/project-fn-ret-contravariant.rs:37:8
|
||||
|
|
||||
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
|
||||
| ^^
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/project-fn-ret-contravariant.rs:38:13
|
||||
|
|
||||
| ------- this data with lifetime `'a`...
|
||||
LL | bar(foo, x)
|
||||
| ^
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/project-fn-ret-contravariant.rs:38:4
|
||||
|
|
||||
LL | bar(foo, x)
|
||||
| ^^^^^^^^^^^
|
||||
| ----^^^---- ...is captured and required to live as long as `'static` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0495`.
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
|
|
|
@ -46,7 +46,7 @@ fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
|
|||
// Cannot instantiate `foo` with any lifetime other than `'a`,
|
||||
// since it is provided as input.
|
||||
|
||||
bar(foo, x) //[transmute]~ ERROR E0495
|
||||
bar(foo, x) //[transmute]~ ERROR E0759
|
||||
}
|
||||
|
||||
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
|
||||
|
|
|
@ -1,30 +1,12 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/project-fn-ret-invariant.rs:49:9
|
||||
|
|
||||
LL | bar(foo, x)
|
||||
| ^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 45:8...
|
||||
--> $DIR/project-fn-ret-invariant.rs:45:8
|
||||
|
|
||||
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
|
||||
| ^^
|
||||
note: ...so that the expression is assignable
|
||||
--> $DIR/project-fn-ret-invariant.rs:49:14
|
||||
|
|
||||
| -------- this data with lifetime `'a`...
|
||||
...
|
||||
LL | bar(foo, x)
|
||||
| ^
|
||||
= note: expected `Type<'_>`
|
||||
found `Type<'a>`
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that the expression is assignable
|
||||
--> $DIR/project-fn-ret-invariant.rs:49:5
|
||||
|
|
||||
LL | bar(foo, x)
|
||||
| ^^^^^^^^^^^
|
||||
= note: expected `Type<'static>`
|
||||
found `Type<'_>`
|
||||
| ----^^^---- ...is captured and required to live as long as `'static` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0495`.
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
|
|
|
@ -1,30 +1,17 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/dyn-trait.rs:20:16
|
||||
|
|
||||
LL | static_val(x);
|
||||
| ^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26...
|
||||
--> $DIR/dyn-trait.rs:19:26
|
||||
|
|
||||
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
|
||||
| ^^
|
||||
note: ...so that the expression is assignable
|
||||
--> $DIR/dyn-trait.rs:20:16
|
||||
|
|
||||
| ------------------- this data with lifetime `'a`...
|
||||
LL | static_val(x);
|
||||
| ^
|
||||
= note: expected `std::boxed::Box<dyn std::fmt::Debug>`
|
||||
found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>`
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that the types are compatible
|
||||
| ^ ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/dyn-trait.rs:20:5
|
||||
|
|
||||
LL | static_val(x);
|
||||
| ^^^^^^^^^^
|
||||
= note: expected `StaticTrait`
|
||||
found `StaticTrait`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0495`.
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
|
|
|
@ -1,28 +1,11 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
||||
|
|
||||
LL | <Foo<'a>>::C
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8...
|
||||
--> $DIR/constant-in-expr-inherent-1.rs:7:8
|
||||
|
|
||||
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
|
||||
| ^^
|
||||
note: ...so that the types are compatible
|
||||
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
||||
|
|
||||
| ------- this data with lifetime `'a`...
|
||||
LL | <Foo<'a>>::C
|
||||
| ^^^^^^^^^^^^
|
||||
= note: expected `Foo<'_>`
|
||||
found `Foo<'a>`
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
||||
|
|
||||
LL | <Foo<'a>>::C
|
||||
| ^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0495`.
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
|
|
|
@ -1,29 +1,11 @@
|
|||
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/regions-addr-of-self.rs:7:37
|
||||
|
|
||||
LL | pub fn chase_cat(&mut self) {
|
||||
| --------- this data with an anonymous lifetime `'_`...
|
||||
LL | let p: &'static mut usize = &mut self.cats_chased;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
|
||||
--> $DIR/regions-addr-of-self.rs:6:5
|
||||
|
|
||||
LL | / pub fn chase_cat(&mut self) {
|
||||
LL | | let p: &'static mut usize = &mut self.cats_chased;
|
||||
LL | | *p += 1;
|
||||
LL | | }
|
||||
| |_____^
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/regions-addr-of-self.rs:7:37
|
||||
|
|
||||
LL | let p: &'static mut usize = &mut self.cats_chased;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: but, the lifetime must be valid for the static lifetime...
|
||||
note: ...so that reference does not outlive borrowed content
|
||||
--> $DIR/regions-addr-of-self.rs:7:37
|
||||
|
|
||||
LL | let p: &'static mut usize = &mut self.cats_chased;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0495`.
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
trait OtherTrait<'a> {}
|
||||
impl<'a> OtherTrait<'a> for &'a () {}
|
||||
|
||||
trait ObjectTrait {}
|
||||
|
||||
impl dyn ObjectTrait {
|
||||
fn use_self(&self) -> &() { panic!() }
|
||||
}
|
||||
|
||||
fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
|
||||
val.use_self() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-without-suggestion.rs:11:9
|
||||
|
|
||||
LL | val.use_self()
|
||||
| ^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected reference `&(dyn ObjectTrait + 'static)`
|
||||
found reference `&(dyn ObjectTrait + 'a)`
|
||||
note: the lifetime `'a` as defined on the function body at 10:11...
|
||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-without-suggestion.rs:10:11
|
||||
|
|
||||
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
|
||||
| ^^
|
||||
= note: ...does not necessarily outlive the static lifetime
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,37 @@
|
|||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod foo {
|
||||
trait OtherTrait<'a> {}
|
||||
impl<'a> OtherTrait<'a> for &'a () {}
|
||||
|
||||
trait ObjectTrait {}
|
||||
trait MyTrait {
|
||||
fn use_self(&self) -> &();
|
||||
}
|
||||
|
||||
impl MyTrait for dyn ObjectTrait + '_ {
|
||||
fn use_self(&self) -> &() { panic!() }
|
||||
}
|
||||
|
||||
fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
|
||||
val.use_self() //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
trait ObjectTrait {}
|
||||
trait MyTrait {
|
||||
fn use_self(&self) -> &();
|
||||
}
|
||||
|
||||
impl MyTrait for dyn ObjectTrait + '_ {
|
||||
fn use_self(&self) -> &() { panic!() }
|
||||
}
|
||||
|
||||
fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
|
||||
val.use_self() //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,37 @@
|
|||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod foo {
|
||||
trait OtherTrait<'a> {}
|
||||
impl<'a> OtherTrait<'a> for &'a () {}
|
||||
|
||||
trait ObjectTrait {}
|
||||
trait MyTrait {
|
||||
fn use_self(&self) -> &();
|
||||
}
|
||||
|
||||
impl MyTrait for dyn ObjectTrait {
|
||||
fn use_self(&self) -> &() { panic!() }
|
||||
}
|
||||
|
||||
fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
|
||||
val.use_self() //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
trait ObjectTrait {}
|
||||
trait MyTrait {
|
||||
fn use_self(&self) -> &();
|
||||
}
|
||||
|
||||
impl MyTrait for dyn ObjectTrait {
|
||||
fn use_self(&self) -> &() { panic!() }
|
||||
}
|
||||
|
||||
fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
|
||||
val.use_self() //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,29 @@
|
|||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:18:13
|
||||
|
|
||||
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
|
||||
| ------------------- this data with lifetime `'a`...
|
||||
LL | val.use_self()
|
||||
| ^^^^^^^^ ...is captured and required to live as long as `'static` here
|
||||
|
|
||||
help: this `impl` introduces an implicit `'static` requirement, consider changing it
|
||||
|
|
||||
LL | impl MyTrait for dyn ObjectTrait + '_ {
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:33:13
|
||||
|
|
||||
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
|
||||
| ------------------- this data with lifetime `'a`...
|
||||
LL | val.use_self()
|
||||
| ^^^^^^^^ ...is captured and required to live as long as `'static` here
|
||||
|
|
||||
help: this `impl` introduces an implicit `'static` requirement, consider changing it
|
||||
|
|
||||
LL | impl MyTrait for dyn ObjectTrait + '_ {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0759`.
|
Loading…
Add table
Reference in a new issue