best_blame_constraint
: prioritize blaming interesting-seeming constraints
This commit is contained in:
parent
45b2ae935d
commit
6421d4cf80
22 changed files with 206 additions and 173 deletions
|
@ -4118,7 +4118,6 @@ name = "rustc_middle"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"derive-where",
|
|
||||||
"either",
|
"either",
|
||||||
"field-offset",
|
"field-offset",
|
||||||
"gsgdt",
|
"gsgdt",
|
||||||
|
|
|
@ -2026,87 +2026,102 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let interesting_to_blame = |constraint: &OutlivesConstraint<'tcx>| {
|
// To pick a constraint to blame, we organize constraints by how interesting we expect them
|
||||||
!matches!(
|
// to be in diagnostics, then pick the most interesting one closest to either the source or
|
||||||
constraint.category,
|
// the target on our constraint path.
|
||||||
ConstraintCategory::OpaqueType
|
let constraint_interest = |constraint: &OutlivesConstraint<'tcx>| {
|
||||||
| ConstraintCategory::Boring
|
// Try to avoid blaming constraints from desugarings, since they may not clearly match
|
||||||
| ConstraintCategory::BoringNoLocation
|
// match what users have written. As an exception, allow blaming returns generated by
|
||||||
| ConstraintCategory::Internal
|
// `?` desugaring, since the correspondence is fairly clear.
|
||||||
| ConstraintCategory::Predicate(_)
|
let category = if let Some(kind) = constraint.span.desugaring_kind()
|
||||||
| ConstraintCategory::Assignment { has_interesting_ty: false }
|
&& (kind != DesugaringKind::QuestionMark
|
||||||
) && constraint.span.desugaring_kind().is_none_or(|kind| {
|
|| !matches!(constraint.category, ConstraintCategory::Return(_)))
|
||||||
// Try to avoid blaming constraints from desugarings, since they may not clearly
|
{
|
||||||
// clearly match what users have written. As an exception, allow blaming returns
|
ConstraintCategory::Boring
|
||||||
// generated by `?` desugaring, since the correspondence is fairly clear.
|
} else {
|
||||||
kind == DesugaringKind::QuestionMark
|
constraint.category
|
||||||
&& matches!(constraint.category, ConstraintCategory::Return(_))
|
};
|
||||||
})
|
|
||||||
|
match category {
|
||||||
|
// Returns usually provide a type to blame and have specially written diagnostics,
|
||||||
|
// so prioritize them.
|
||||||
|
ConstraintCategory::Return(_) => 0,
|
||||||
|
// Unsizing coercions are interesting, since we have a note for that:
|
||||||
|
// `BorrowExplanation::add_object_lifetime_default_note`.
|
||||||
|
// FIXME(dianne): That note shouldn't depend on a coercion being blamed; see issue
|
||||||
|
// #131008 for an example of where we currently don't emit it but should.
|
||||||
|
// Once the note is handled properly, this case should be removed. Until then, it
|
||||||
|
// should be as limited as possible; the note is prone to false positives and this
|
||||||
|
// constraint usually isn't best to blame.
|
||||||
|
ConstraintCategory::Cast {
|
||||||
|
unsize_to: Some(unsize_ty),
|
||||||
|
is_implicit_coercion: true,
|
||||||
|
} if target_region == self.universal_regions().fr_static
|
||||||
|
// Mirror the note's condition, to minimize how often this diverts blame.
|
||||||
|
&& let ty::Adt(_, args) = unsize_ty.kind()
|
||||||
|
&& args.iter().any(|arg| arg.as_type().is_some_and(|ty| ty.is_trait()))
|
||||||
|
// Mimic old logic for this, to minimize false positives in tests.
|
||||||
|
&& !path
|
||||||
|
.iter()
|
||||||
|
.any(|c| matches!(c.category, ConstraintCategory::TypeAnnotation)) =>
|
||||||
|
{
|
||||||
|
1
|
||||||
|
}
|
||||||
|
// Between other interesting constraints, order by their position on the `path`.
|
||||||
|
ConstraintCategory::Yield
|
||||||
|
| ConstraintCategory::UseAsConst
|
||||||
|
| ConstraintCategory::UseAsStatic
|
||||||
|
| ConstraintCategory::TypeAnnotation
|
||||||
|
| ConstraintCategory::Cast { .. }
|
||||||
|
| ConstraintCategory::CallArgument(_)
|
||||||
|
| ConstraintCategory::CopyBound
|
||||||
|
| ConstraintCategory::SizedBound
|
||||||
|
| ConstraintCategory::Assignment { has_interesting_ty: true }
|
||||||
|
| ConstraintCategory::Usage
|
||||||
|
| ConstraintCategory::ClosureUpvar(_) => 2,
|
||||||
|
// Give assignments a lower priority when flagged as less likely to be interesting.
|
||||||
|
// In particular, de-prioritize MIR assignments lowered from argument patterns.
|
||||||
|
ConstraintCategory::Assignment { has_interesting_ty: false } => 3,
|
||||||
|
// We handle predicates and opaque types specially; don't prioritize them here.
|
||||||
|
ConstraintCategory::Predicate(_) | ConstraintCategory::OpaqueType => 4,
|
||||||
|
// `Boring` constraints can correspond to user-written code and have useful spans,
|
||||||
|
// but don't provide any other useful information for diagnostics.
|
||||||
|
ConstraintCategory::Boring => 5,
|
||||||
|
// `BoringNoLocation` constraints can point to user-written code, but are less
|
||||||
|
// specific, and are not used for relations that would make sense to blame.
|
||||||
|
ConstraintCategory::BoringNoLocation => 6,
|
||||||
|
// Do not blame internal constraints.
|
||||||
|
ConstraintCategory::Internal => 7,
|
||||||
|
ConstraintCategory::IllegalUniverse => 8,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let best_choice = if blame_source {
|
let best_choice = if blame_source {
|
||||||
path.iter().rposition(interesting_to_blame)
|
path.iter().enumerate().rev().min_by_key(|(_, c)| constraint_interest(c)).unwrap().0
|
||||||
} else {
|
} else {
|
||||||
path.iter().position(interesting_to_blame)
|
path.iter().enumerate().min_by_key(|(_, c)| constraint_interest(c)).unwrap().0
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!(?best_choice, ?blame_source);
|
debug!(?best_choice, ?blame_source);
|
||||||
|
|
||||||
let best_constraint = match best_choice {
|
let best_constraint = if let Some(next) = path.get(best_choice + 1)
|
||||||
Some(i)
|
&& matches!(path[best_choice].category, ConstraintCategory::Return(_))
|
||||||
if let Some(next) = path.get(i + 1)
|
&& next.category == ConstraintCategory::OpaqueType
|
||||||
&& matches!(path[i].category, ConstraintCategory::Return(_))
|
|
||||||
&& next.category == ConstraintCategory::OpaqueType =>
|
|
||||||
{
|
{
|
||||||
// The return expression is being influenced by the return type being
|
// The return expression is being influenced by the return type being
|
||||||
// impl Trait, point at the return type and not the return expr.
|
// impl Trait, point at the return type and not the return expr.
|
||||||
*next
|
*next
|
||||||
}
|
} else if path[best_choice].category == ConstraintCategory::Return(ReturnConstraint::Normal)
|
||||||
|
|
||||||
Some(i)
|
|
||||||
if path[i].category == ConstraintCategory::Return(ReturnConstraint::Normal)
|
|
||||||
&& let Some(field) = path.iter().find_map(|p| {
|
&& let Some(field) = path.iter().find_map(|p| {
|
||||||
if let ConstraintCategory::ClosureUpvar(f) = p.category {
|
if let ConstraintCategory::ClosureUpvar(f) = p.category { Some(f) } else { None }
|
||||||
Some(f)
|
})
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}) =>
|
|
||||||
{
|
{
|
||||||
OutlivesConstraint {
|
OutlivesConstraint {
|
||||||
category: ConstraintCategory::Return(ReturnConstraint::ClosureUpvar(field)),
|
category: ConstraintCategory::Return(ReturnConstraint::ClosureUpvar(field)),
|
||||||
..path[i]
|
..path[best_choice]
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(_)
|
|
||||||
if target_region == self.universal_regions().fr_static
|
|
||||||
&& let Some(old_best) = path.iter().min_by_key(|p| p.category)
|
|
||||||
&& matches!(old_best.category, ConstraintCategory::Cast {
|
|
||||||
is_implicit_coercion: true,
|
|
||||||
unsize_to: Some(_)
|
|
||||||
}) =>
|
|
||||||
{
|
|
||||||
// FIXME(dianne): This is a hack in order to emit the subdiagnostic
|
|
||||||
// `BorrowExplanation::add_object_lifetime_default_note` more often, e.g. on
|
|
||||||
// `tests/ui/traits/trait-object-lifetime-default-note.rs`. The subdiagnostic
|
|
||||||
// depends on a coercion being blamed, so we fall back to an earlier version of this
|
|
||||||
// function's blaming logic to keep the test result the same. A proper fix will
|
|
||||||
// require rewriting the subdiagnostic not to rely on a coercion being blamed.
|
|
||||||
// For examples of where notes are missing, see #131008 and
|
|
||||||
// `tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs`.
|
|
||||||
// As part of fixing those, this case should be removed.
|
|
||||||
*old_best
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(i) => path[i],
|
|
||||||
|
|
||||||
None => {
|
|
||||||
// If that search fails, the only constraints on the path are those that we try not
|
|
||||||
// to blame. In that case, find what appears to be the most interesting point to
|
|
||||||
// report to the user via an even more ad-hoc guess.
|
|
||||||
*path.iter().min_by_key(|p| p.category).unwrap()
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
path[best_choice]
|
||||||
};
|
};
|
||||||
|
|
||||||
let blame_constraint = BlameConstraint {
|
let blame_constraint = BlameConstraint {
|
||||||
|
|
|
@ -6,7 +6,6 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
bitflags = "2.4.1"
|
bitflags = "2.4.1"
|
||||||
derive-where = "1.2.7"
|
|
||||||
either = "1.5.0"
|
either = "1.5.0"
|
||||||
field-offset = "0.3.5"
|
field-offset = "0.3.5"
|
||||||
gsgdt = "0.1.2"
|
gsgdt = "0.1.2"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
|
|
||||||
use derive_where::derive_where;
|
|
||||||
use rustc_abi::{FieldIdx, VariantIdx};
|
use rustc_abi::{FieldIdx, VariantIdx};
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
|
@ -225,7 +224,6 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
|
||||||
/// See also `rustc_const_eval::borrow_check::constraints`.
|
/// See also `rustc_const_eval::borrow_check::constraints`.
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
||||||
#[derive_where(PartialOrd, Ord)]
|
|
||||||
pub enum ConstraintCategory<'tcx> {
|
pub enum ConstraintCategory<'tcx> {
|
||||||
Return(ReturnConstraint),
|
Return(ReturnConstraint),
|
||||||
Yield,
|
Yield,
|
||||||
|
@ -237,12 +235,11 @@ pub enum ConstraintCategory<'tcx> {
|
||||||
is_implicit_coercion: bool,
|
is_implicit_coercion: bool,
|
||||||
/// Whether this is an unsizing coercion and if yes, this contains the target type.
|
/// Whether this is an unsizing coercion and if yes, this contains the target type.
|
||||||
/// Region variables are erased to ReErased.
|
/// Region variables are erased to ReErased.
|
||||||
#[derive_where(skip)]
|
|
||||||
unsize_to: Option<Ty<'tcx>>,
|
unsize_to: Option<Ty<'tcx>>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Contains the function type if available.
|
/// Contains the function type if available.
|
||||||
CallArgument(#[derive_where(skip)] Option<Ty<'tcx>>),
|
CallArgument(Option<Ty<'tcx>>),
|
||||||
CopyBound,
|
CopyBound,
|
||||||
SizedBound,
|
SizedBound,
|
||||||
Assignment {
|
Assignment {
|
||||||
|
@ -276,7 +273,7 @@ pub enum ConstraintCategory<'tcx> {
|
||||||
IllegalUniverse,
|
IllegalUniverse,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
||||||
pub enum ReturnConstraint {
|
pub enum ReturnConstraint {
|
||||||
Normal,
|
Normal,
|
||||||
|
|
|
@ -4,7 +4,7 @@ error: lifetime may not live long enough
|
||||||
LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> {
|
LL | fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | x as _
|
LL | x as _
|
||||||
| ^^^^^^ cast requires that `'a` must outlive `'static`
|
| ^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,12 @@ LL | fn change_lt<'a, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x as _
|
LL | x as _
|
||||||
| ^^^^^^ cast requires that `'b` must outlive `'a`
|
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable pointer to `dyn Trait<'_>`
|
||||||
|
= note: mutable pointers are invariant over their type parameter
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5
|
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:6:5
|
||||||
|
@ -35,9 +38,12 @@ LL | fn change_lt_ab<'a: 'b, 'b>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x as _
|
LL | x as _
|
||||||
| ^^^^^^ cast requires that `'b` must outlive `'a`
|
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable pointer to `dyn Trait<'_>`
|
||||||
|
= note: mutable pointers are invariant over their type parameter
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:15:5
|
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:15:5
|
||||||
|
@ -85,9 +91,12 @@ LL | fn change_assoc_0<'a, 'b>(
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | x as _
|
LL | x as _
|
||||||
| ^^^^^^ cast requires that `'b` must outlive `'a`
|
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Send>`
|
||||||
|
= note: mutable pointers are invariant over their type parameter
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
|
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5
|
||||||
|
@ -118,9 +127,12 @@ LL | fn change_assoc_1<'a, 'b>(
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | x as _
|
LL | x as _
|
||||||
| ^^^^^^ cast requires that `'b` must outlive `'a`
|
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
= note: requirement occurs because of a mutable pointer to `dyn Assocked<Assoc = dyn Trait<'_>>`
|
||||||
|
= note: mutable pointers are invariant over their type parameter
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
|
--> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5
|
||||||
|
|
|
@ -46,8 +46,8 @@ fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
|
|
||||||
fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
let x = match true {
|
let x = match true {
|
||||||
true => foo::<&'c ()>,
|
true => foo::<&'c ()>, //~ ERROR lifetime may not live long enough
|
||||||
false => foo::<&'a ()>, //~ ERROR lifetime may not live long enough
|
false => foo::<&'a ()>,
|
||||||
};
|
};
|
||||||
|
|
||||||
x(a);
|
x(a);
|
||||||
|
|
|
@ -6,9 +6,9 @@ LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'a ()>;
|
LL | let mut x = foo::<&'a ()>;
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -22,9 +22,9 @@ LL | fn f<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'a ()>;
|
LL | let mut x = foo::<&'a ()>;
|
||||||
LL | x = foo::<&'b ()>;
|
LL | x = foo::<&'b ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -53,9 +53,9 @@ LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let mut x = foo::<&'c ()>;
|
LL | let mut x = foo::<&'c ()>;
|
||||||
LL | x = foo::<&'b ()>;
|
LL | x = foo::<&'b ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -69,9 +69,9 @@ LL | fn i<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | x = foo::<&'a ()>;
|
LL | x = foo::<&'a ()>;
|
||||||
| ^^^^^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -89,9 +89,9 @@ LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | let x = match true {
|
LL | let x = match true {
|
||||||
LL | true => foo::<&'b ()>,
|
LL | true => foo::<&'b ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -105,9 +105,9 @@ LL | fn j<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
...
|
||||||
LL | false => foo::<&'a ()>,
|
LL | false => foo::<&'a ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'b`
|
| ^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a function pointer to `foo`
|
= note: requirement occurs because of a function pointer to `foo`
|
||||||
= note: the function `foo` is invariant over the parameter `T`
|
= note: the function `foo` is invariant over the parameter `T`
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -117,14 +117,14 @@ help: `'a` and `'b` must be the same: replace one with the other
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/fn_def_coercion.rs:50:18
|
--> $DIR/fn_def_coercion.rs:49:17
|
||||||
|
|
|
|
||||||
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
LL | fn k<'a, 'b, 'c: 'a + 'b>(a: &'a (), b: &'b (), c: &'c ()) {
|
||||||
| -- -- lifetime `'c` defined here
|
| -- -- lifetime `'c` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
...
|
LL | let x = match true {
|
||||||
LL | false => foo::<&'a ()>,
|
LL | true => foo::<&'c ()>,
|
||||||
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c`
|
| ^^^^^^^^^^^^^ assignment requires that `'a` must outlive `'c`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'c`
|
= help: consider adding the following bound: `'a: 'c`
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0621]: explicit lifetime required in the type of `lexer`
|
error[E0621]: explicit lifetime required in the type of `lexer`
|
||||||
--> $DIR/issue-15034.rs:17:25
|
--> $DIR/issue-15034.rs:17:9
|
||||||
|
|
|
|
||||||
LL | pub fn new(lexer: &'a mut Lexer) -> Parser<'a> {
|
LL | pub fn new(lexer: &'a mut Lexer) -> Parser<'a> {
|
||||||
| ------------- help: add explicit lifetime `'a` to the type of `lexer`: `&'a mut Lexer<'a>`
|
| ------------- help: add explicit lifetime `'a` to the type of `lexer`: `&'a mut Lexer<'a>`
|
||||||
LL | Parser { lexer: lexer }
|
LL | Parser { lexer: lexer }
|
||||||
| ^^^^^ lifetime `'a` required
|
| ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,11 @@ error: lifetime may not live long enough
|
||||||
LL | fn foo<'a>() -> [Foo<'a>; 100] {
|
LL | fn foo<'a>() -> [Foo<'a>; 100] {
|
||||||
| -- lifetime `'a` defined here
|
| -- lifetime `'a` defined here
|
||||||
LL | [mk_foo::<'a>(); 100]
|
LL | [mk_foo::<'a>(); 100]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ copying this value requires that `'a` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
||||||
|
|
|
||||||
|
= note: requirement occurs because of the type `Foo<'_>`, which makes the generic argument `'_` invariant
|
||||||
|
= note: the struct `Foo<'a>` is invariant over the parameter `'a`
|
||||||
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl DebugWith<dyn DebugContext> for Foo {
|
||||||
fmt: &mut std::fmt::Formatter<'_>,
|
fmt: &mut std::fmt::Formatter<'_>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
let Foo { bar } = self;
|
let Foo { bar } = self;
|
||||||
bar.debug_with(cx); //~ lifetime may not live long enough
|
bar.debug_with(cx); //~ borrowed data escapes outside of method
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
error: lifetime may not live long enough
|
error[E0521]: borrowed data escapes outside of method
|
||||||
--> $DIR/issue-54779-anon-static-lifetime.rs:32:24
|
--> $DIR/issue-54779-anon-static-lifetime.rs:32:9
|
||||||
|
|
|
|
||||||
LL | cx: &dyn DebugContext,
|
LL | cx: &dyn DebugContext,
|
||||||
| - let's call the lifetime of this reference `'1`
|
| -- - let's call the lifetime of this reference `'1`
|
||||||
|
| |
|
||||||
|
| `cx` is a reference that is only valid in the method body
|
||||||
...
|
...
|
||||||
LL | bar.debug_with(cx);
|
LL | bar.debug_with(cx);
|
||||||
| ^^ coercion requires that `'1` must outlive `'static`
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| `cx` escapes the method body here
|
||||||
|
| argument requires that `'1` must outlive `'static`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0521`.
|
||||||
|
|
|
@ -11,14 +11,14 @@ LL | || { None::<&'a &'b ()>; };
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
|
||||||
error: lifetime may not live long enough
|
error: lifetime may not live long enough
|
||||||
--> $DIR/issue-98589-closures-relate-named-regions.rs:15:10
|
--> $DIR/issue-98589-closures-relate-named-regions.rs:15:5
|
||||||
|
|
|
|
||||||
LL | fn test_early_late<'a: 'a, 'b>() {
|
LL | fn test_early_late<'a: 'a, 'b>() {
|
||||||
| -- -- lifetime `'b` defined here
|
| -- -- lifetime `'b` defined here
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | || { None::<&'a &'b ()>; };
|
LL | || { None::<&'a &'b ()>; };
|
||||||
| ^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
|
error[E0597]: `a` does not live long enough
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:13
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:18
|
||||||
|
|
|
|
||||||
|
LL | let a = ();
|
||||||
|
| - binding `a` declared here
|
||||||
LL | let b = |_| &a;
|
LL | let b = |_| &a;
|
||||||
| ^^^ - `a` is borrowed here
|
| --- -^
|
||||||
| |
|
| | ||
|
||||||
| may outlive borrowed value `a`
|
| | |borrowed value does not live long enough
|
||||||
|
| | returning this value requires that `a` is borrowed for `'static`
|
||||||
|
| value captured here
|
||||||
|
...
|
||||||
|
LL | }
|
||||||
|
| - `a` dropped here while still borrowed
|
||||||
|
|
|
|
||||||
note: function requires argument type to outlive `'static`
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:20:22
|
||||||
|
|
|
|
||||||
LL | bad(&b);
|
LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
|
||||||
| ^^^^^^^
|
| ^^^
|
||||||
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
|
||||||
|
|
|
||||||
LL | let b = move |_| &a;
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: implementation of `Fn` is not general enough
|
error: implementation of `Fn` is not general enough
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
||||||
|
@ -36,4 +39,4 @@ LL | bad(&b);
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0373`.
|
For more information about this error, try `rustc --explain E0597`.
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
|
error[E0597]: `a` does not live long enough
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:13
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:10:18
|
||||||
|
|
|
|
||||||
|
LL | let a = ();
|
||||||
|
| - binding `a` declared here
|
||||||
LL | let b = |_| &a;
|
LL | let b = |_| &a;
|
||||||
| ^^^ - `a` is borrowed here
|
| --- -^
|
||||||
| |
|
| | ||
|
||||||
| may outlive borrowed value `a`
|
| | |borrowed value does not live long enough
|
||||||
|
| | returning this value requires that `a` is borrowed for `'static`
|
||||||
|
| value captured here
|
||||||
|
...
|
||||||
|
LL | }
|
||||||
|
| - `a` dropped here while still borrowed
|
||||||
|
|
|
|
||||||
note: function requires argument type to outlive `'static`
|
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:20:22
|
||||||
|
|
|
|
||||||
LL | bad(&b);
|
LL | fn bad<F: Fn(&()) -> &()>(_: F) {}
|
||||||
| ^^^^^^^
|
| ^^^
|
||||||
help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
|
|
||||||
|
|
|
||||||
LL | let b = move |_| &a;
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: implementation of `Fn` is not general enough
|
error: implementation of `Fn` is not general enough
|
||||||
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
--> $DIR/location-insensitive-scopes-issue-117146.rs:13:5
|
||||||
|
@ -36,4 +39,4 @@ LL | bad(&b);
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0373`.
|
For more information about this error, try `rustc --explain E0597`.
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = ();
|
let a = ();
|
||||||
let b = |_| &a;
|
let b = |_| &a;
|
||||||
//[nll]~^ ERROR closure may outlive the current function, but it borrows `a`
|
//[nll]~^ ERROR `a` does not live long enough
|
||||||
//[polonius]~^^ ERROR closure may outlive the current function, but it borrows `a`
|
//[polonius]~^^ ERROR `a` does not live long enough
|
||||||
bad(&b);
|
bad(&b);
|
||||||
//[nll]~^ ERROR implementation of `Fn`
|
//[nll]~^ ERROR implementation of `Fn`
|
||||||
//[nll]~| ERROR implementation of `FnOnce`
|
//[nll]~| ERROR implementation of `FnOnce`
|
||||||
|
|
|
@ -6,9 +6,9 @@ LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'a` must outlive `'b`
|
| ^ requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
= note: mutable references are invariant over their type parameter
|
= note: mutable references are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -21,9 +21,9 @@ LL | fn compare_const<'a, 'b>(x: *const &mut &'a i32, y: *const &mut &'b i32) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
= note: mutable references are invariant over their type parameter
|
= note: mutable references are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -38,9 +38,9 @@ LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'a` must outlive `'b`
|
| ^ requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a mutable pointer to `&i32`
|
= note: requirement occurs because of a mutable pointer to `&i32`
|
||||||
= note: mutable pointers are invariant over their type parameter
|
= note: mutable pointers are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -53,9 +53,9 @@ LL | fn compare_mut<'a, 'b>(x: *mut &'a i32, y: *mut &'b i32) {
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | x == y;
|
LL | x == y;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a mutable pointer to `&i32`
|
= note: requirement occurs because of a mutable pointer to `&i32`
|
||||||
= note: mutable pointers are invariant over their type parameter
|
= note: mutable pointers are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -72,9 +72,9 @@ LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | f == g;
|
LL | f == g;
|
||||||
| ^ requires that `'a` must outlive `'b`
|
| ^ requires that `'b` must outlive `'a`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'a: 'b`
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
= note: mutable references are invariant over their type parameter
|
= note: mutable references are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
@ -87,9 +87,9 @@ LL | fn compare_fn_ptr<'a, 'b, 'c>(f: fn(&'c mut &'a i32), g: fn(&'c mut &'b i32
|
||||||
| |
|
| |
|
||||||
| lifetime `'a` defined here
|
| lifetime `'a` defined here
|
||||||
LL | f == g;
|
LL | f == g;
|
||||||
| ^ requires that `'b` must outlive `'a`
|
| ^ requires that `'a` must outlive `'b`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'b: 'a`
|
= help: consider adding the following bound: `'a: 'b`
|
||||||
= note: requirement occurs because of a mutable reference to `&i32`
|
= note: requirement occurs because of a mutable reference to `&i32`
|
||||||
= note: mutable references are invariant over their type parameter
|
= note: mutable references are invariant over their type parameter
|
||||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||||
|
|
|
@ -64,7 +64,7 @@ mod bay {
|
||||||
|
|
||||||
fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
|
fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
|
||||||
val.use_self()
|
val.use_self()
|
||||||
//~^ ERROR: `val` does not live long enough
|
//~^ ERROR: cannot return value referencing function parameter `val`
|
||||||
//~| ERROR: borrowed data escapes outside of function
|
//~| ERROR: borrowed data escapes outside of function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,20 +25,6 @@ LL | val.use_self()
|
||||||
| returns a value referencing data owned by the current function
|
| returns a value referencing data owned by the current function
|
||||||
| `val` is borrowed here
|
| `val` is borrowed here
|
||||||
|
|
||||||
error[E0597]: `val` does not live long enough
|
|
||||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
|
|
||||||
|
|
|
||||||
LL | fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
|
|
||||||
| --- binding `val` declared here
|
|
||||||
LL | val.use_self()
|
|
||||||
| ^^^-----------
|
|
||||||
| |
|
|
||||||
| borrowed value does not live long enough
|
|
||||||
| argument requires that `val` is borrowed for `'static`
|
|
||||||
...
|
|
||||||
LL | }
|
|
||||||
| - `val` dropped here while still borrowed
|
|
||||||
|
|
||||||
error[E0521]: borrowed data escapes outside of function
|
error[E0521]: borrowed data escapes outside of function
|
||||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
|
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
|
||||||
|
|
|
|
||||||
|
@ -64,6 +50,15 @@ help: consider relaxing the implicit `'static` requirement
|
||||||
LL | impl MyTrait for Box<dyn ObjectTrait<Assoc = i32> + '_> {
|
LL | impl MyTrait for Box<dyn ObjectTrait<Assoc = i32> + '_> {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
|
error[E0515]: cannot return value referencing function parameter `val`
|
||||||
|
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
|
||||||
|
|
|
||||||
|
LL | val.use_self()
|
||||||
|
| ---^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| returns a value referencing data owned by the current function
|
||||||
|
| `val` is borrowed here
|
||||||
|
|
||||||
error[E0515]: cannot return value referencing function parameter `val`
|
error[E0515]: cannot return value referencing function parameter `val`
|
||||||
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:90:9
|
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:90:9
|
||||||
|
|
|
|
||||||
|
@ -75,5 +70,5 @@ LL | val.use_self()
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0515, E0521, E0597.
|
Some errors have detailed explanations: E0515, E0521.
|
||||||
For more information about an error, try `rustc --explain E0515`.
|
For more information about an error, try `rustc --explain E0515`.
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
|
||||||
| lifetime `'min` defined here
|
| lifetime `'min` defined here
|
||||||
...
|
...
|
||||||
LL | v
|
LL | v
|
||||||
| ^ coercion requires that `'min` must outlive `'max`
|
| ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'min: 'max`
|
= help: consider adding the following bound: `'min: 'max`
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
|
||||||
| lifetime `'min` defined here
|
| lifetime `'min` defined here
|
||||||
...
|
...
|
||||||
LL | v
|
LL | v
|
||||||
| ^ coercion requires that `'min` must outlive `'max`
|
| ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'min: 'max`
|
= help: consider adding the following bound: `'min: 'max`
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
|
||||||
| lifetime `'min` defined here
|
| lifetime `'min` defined here
|
||||||
...
|
...
|
||||||
LL | v
|
LL | v
|
||||||
| ^ coercion requires that `'min` must outlive `'max`
|
| ^ function was supposed to return data with lifetime `'max` but it is returning data with lifetime `'min`
|
||||||
|
|
|
|
||||||
= help: consider adding the following bound: `'min: 'max`
|
= help: consider adding the following bound: `'min: 'max`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue